Subject: HZ, key repeat, i386
To: None <tech-kern@netbsd.org>
From: None <dlagno@mail.nnov.ru>
List: tech-kern
Date: 03/11/2004 17:51:40
Hi,
I was just curious and attempted to rebuild current kernel for i386 with
lower HZ.
First kern/clock.c has switch that prescribes somehow fixed choice of HZ
values in case you use NTP. I use ntpd so I did not messed with that
file.
Secondly arch/i386/isa/clock.c somewhat restricts value of HZ. It will
panic early in boot process if HZ < 38 and TIME_FREQ == 1193182 -- as is
in my case.
So I tested new kernel with HZ=64. And after raising
ISA_TIMER_MSB_TABLE_SIZE in arch/i386/isa/clock.c I tested kernels with
HZ=32 and HZ=16.
HZ=64 works fine, but I discovered that speed of keys autorepeat in
console raised from ~30 symbols per second with HZ=100 to ~60 symbols per
second with HZ=64. At the same time I noticed no difference in XFree86
behaviour.
HZ=32 also works fine, I had no problem to rebuild kernel on that machine
but autorepeat feature is completely unusable -- if I hold key long
enough time to trigger autorepeat then 1024 symbols are emited
immediately.
HZ=16 boots fine, but I stopped in configuration of cgd device -- because
each keypress generates several symbols so I cannot enter password
correctly.
So it appears that keyboard driver somehow incorrectly uses HZ. Maybe it
should be fixed somehow??
Also I can provide patch that I used to enable HZ < 38 on i386:
--- arch/i386/isa/clock.c 2003-08-07 20:28:01.000000000 +0400
+++ arch/i386/isa/clock.c.new 2004-03-11 13:32:21.000000000 +0300
@@ -328,7 +328,13 @@
*
* time.tv_usec += isa_timer_msb_table[cnt_msb] - isa_timer_lsb_table
[cnt_lsb];
*/
+#if HZ > 36
#define ISA_TIMER_MSB_TABLE_SIZE 128
+#elif HZ > 18
+#define ISA_TIMER_MSB_TABLE_SIZE 256
+#elif HZ > 9
+#define ISA_TIMER_MSB_TABLE_SIZE 512
+#endif
u_long isa_timer_tick; /* the number of microseconds in a
tick */
u_short isa_timer_count; /* the countdown count for the timer */
@@ -380,34 +386,34 @@
/* LSB table is easy, just divide and round */
t = ((u_long) s * 1000000 * 2) / TIMER_FREQ;
isa_timer_lsb_table[s] = (u_short) ((t / 2) + (t &
0x1));
+ }
+ for (s = 0; s < ISA_TIMER_MSB_TABLE_SIZE; s++) {
/* MSB table is zero unless the MSB is <=
isa_timer_count */
- if (s < ISA_TIMER_MSB_TABLE_SIZE) {
- msb = ((u_long) s) * 256;
- if (msb > tval) {
- isa_timer_msb_table[s] = 0;
- } else {
- /*
- * Harder computation here, since
multiplying
- * the value by 1000000 can overflow
a long.
- * To avoid 64-bit computations we
divide
- * the high order byte and the low
order
- * byte of the numerator separately,
adding
- * the remainder of the first
computation
- * into the second. The constraint
on
- * TIMER_FREQ above should prevent
overflow
- * here.
- */
- msb = tval - msb;
- lsb = msb % 256;
- msb = (msb / 256) * 1000000;
- quotient = msb / TIMER_FREQ;
- remainder = msb % TIMER_FREQ;
- t = ((remainder * 256 * 2)
- + (lsb * 1000000 * 2)) /
TIMER_FREQ;
- isa_timer_msb_table[s] = (u_short)
((t / 2)
- + (t & 0x1) + (quotient * 256));
- }
+ msb = ((u_long) s) * 256;
+ if (msb > tval) {
+ isa_timer_msb_table[s] = 0;
+ } else {
+ /*
+ * Harder computation here, since multiplying
+ * the value by 1000000 can overflow a long.
+ * To avoid 64-bit computations we divide
+ * the high order byte and the low order
+ * byte of the numerator separately, adding
+ * the remainder of the first computation
+ * into the second. The constraint on
+ * TIMER_FREQ above should prevent overflow
+ * here.
+ */
+ msb = tval - msb;
+ lsb = msb % 256;
+ msb = (msb / 256) * 1000000;
+ quotient = msb / TIMER_FREQ;
+ remainder = msb % TIMER_FREQ;
+ t = ((remainder * 256 * 2)
+ + (lsb * 1000000 * 2)) / TIMER_FREQ;
+ isa_timer_msb_table[s] = (u_short)((t / 2)
+ + (t & 0x1) + (quotient * 256));
}
}