Increasing HZ (patch for HZ > 1000)

Jean-Marc Valin
2003-12-11T06:08:45Z

[-- Attachment #1.1: Type: text/plain, Size: 837 bytes --]

Hi,

I think this may be of interest to some people. I've attached a patch
that makes it possible to increase HZ up to 10000. The patch adds some
HZ-related defines (e.g. SHIFT_HZ) for higher HZ values. It also removes
some shift by negative number and divide by zero (e.g. in bogomips
computation) and prevents some overflows. I'm not sure I fixed
everything, but right now it seems to work with HZ=10000. The only thing
I'm seeing are messages such as: "orinoco_lock() called with
hw_unavailable (dev=f75c8000)" and "eth1: IRQ handler is looping too
much! Resetting.".

I know it's (much) too late for 2.6 but I'm sending the patch anyway so
it (hopefully) doesn't get lost.

Jean-Marc

--
Jean-Marc Valin, M.Sc.A., ing. jr.
LABORIUS (http://www.gel.usherb.ca/laborius)
Université de Sherbrooke, Québec, Canada

[-- Attachment #1.2: hz.patch --]
[-- Type: text/x-patch, Size: 7974 bytes --]

--- linux-2.6.0-test11/include/linux/timex.h 2003-11-26 15:42:54.000000000 -0500
+++ linux-2.6.0-test11-hz/include/linux/timex.h 2003-12-09 14:33:51.000000000 -0500
@@ -77,6 +77,12 @@
# define SHIFT_HZ 9
#elif HZ >= 768 && HZ < 1536
# define SHIFT_HZ 10
+#elif HZ >= 1536 && HZ < 3072
+# define SHIFT_HZ 11
+#elif HZ >= 3072 && HZ < 6144
+# define SHIFT_HZ 12
+#elif HZ >= 6144 && HZ < 12288
+# define SHIFT_HZ 13
#else
# error You lose.
#endif
--- linux-2.6.0-test11/init/main.c 2003-11-26 15:43:09.000000000 -0500
+++ linux-2.6.0-test11-hz/init/main.c 2003-12-09 14:52:24.000000000 -0500
@@ -212,8 +212,8 @@

/* Round the value and print it */
printk("%lu.%02lu BogoMIPS\n",
- loops_per_jiffy/(500000/HZ),
- (loops_per_jiffy/(5000/HZ)) % 100);
+ HZ*(loops_per_jiffy>>3)/62500,
+ (HZ*(loops_per_jiffy>>3)/625)%100);
}

static int __init debug_kernel(char *str)
--- linux-2.6.0-test11/arch/i386/kernel/cpu/proc.c 2003-11-26 15:45:30.000000000 -0500
+++ linux-2.6.0-test11-hz/arch/i386/kernel/cpu/proc.c 2003-12-09 14:54:20.000000000 -0500
@@ -121,8 +121,8 @@
seq_printf(m, " %s", x86_cap_flags[i]);

seq_printf(m, "\nbogomips\t: %lu.%02lu\n\n",
- c->loops_per_jiffy/(500000/HZ),
- (c->loops_per_jiffy/(5000/HZ)) % 100);
+ HZ*(c->loops_per_jiffy>>3)/62500,
+ (HZ*(c->loops_per_jiffy>>3)/625)%100);
return 0;
}

--- linux-2.6.0-test11/kernel/timer.c 2003-11-26 15:45:25.000000000 -0500
+++ linux-2.6.0-test11-hz/kernel/timer.c 2003-12-09 14:57:51.000000000 -0500
@@ -561,7 +561,11 @@
if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
time_offset += ltemp;
- time_adj = -ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
+#if SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE > 0
+ time_adj = -ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
+#else
+ time_adj = -ltemp >> (SHIFT_HZ + SHIFT_UPDATE - SHIFT_SCALE);
+#endif
} else {
ltemp = time_offset;
if (!(time_status & STA_FLL))
@@ -569,7 +573,11 @@
if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
time_offset -= ltemp;
- time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
+#if SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE > 0
+ time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
+#else
+ time_adj = ltemp >> (SHIFT_HZ + SHIFT_UPDATE - SHIFT_SCALE);
+#endif
}

/*
--- linux-2.6.0-test11/include/net/tcp.h 2003-11-26 15:43:05.000000000 -0500
+++ linux-2.6.0-test11-hz/include/net/tcp.h 2003-12-09 15:03:50.000000000 -0500
@@ -486,8 +486,8 @@
so that we select tick to get range about 4 seconds.
*/

-#if HZ <= 16 || HZ > 4096
-# error Unsupported: HZ <= 16 or HZ > 4096
+#if HZ <= 16 || HZ > 16384
+# error Unsupported: HZ <= 16 or HZ > 16384
#elif HZ <= 32
# define TCP_TW_RECYCLE_TICK (5+2-TCP_TW_RECYCLE_SLOTS_LOG)
#elif HZ <= 64
@@ -502,8 +502,12 @@
# define TCP_TW_RECYCLE_TICK (10+2-TCP_TW_RECYCLE_SLOTS_LOG)
#elif HZ <= 2048
# define TCP_TW_RECYCLE_TICK (11+2-TCP_TW_RECYCLE_SLOTS_LOG)
-#else
+#elif HZ <= 4096
# define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG)
+#elif HZ <= 8192
+# define TCP_TW_RECYCLE_TICK (13+2-TCP_TW_RECYCLE_SLOTS_LOG)
+#else
+# define TCP_TW_RECYCLE_TICK (14+2-TCP_TW_RECYCLE_SLOTS_LOG)
#endif

/*
--- linux-2.6.0-test11/drivers/char/dtlk.c 2003-11-26 15:43:40.000000000 -0500
+++ linux-2.6.0-test11-hz/drivers/char/dtlk.c 2003-12-09 15:25:12.000000000 -0500
@@ -207,7 +207,7 @@
up to 250 usec for the RDY bit to
go nonzero. */
for (retries = 0;
- retries < loops_per_jiffy / (4000/HZ);
+ retries < HZ*(loops_per_jiffy>>5)/125;
retries++)
if (inb_p(dtlk_port_tts) &
TTS_WRITABLE)
--- linux-2.6.0-test11/include/linux/isicom.h 2003-11-26 15:43:36.000000000 -0500
+++ linux-2.6.0-test11-hz/include/linux/isicom.h 2003-12-09 15:30:39.000000000 -0500
@@ -147,7 +147,7 @@
int close_delay;
unsigned short channel;
unsigned short status;
- unsigned short closing_wait;
+ unsigned int closing_wait;
struct isi_board * card;
struct tty_struct * tty;
wait_queue_head_t close_wait;
--- linux-2.6.0-test11/include/linux/hayesesp.h 2003-11-26 15:45:08.000000000 -0500
+++ linux-2.6.0-test11-hz/include/linux/hayesesp.h 2003-12-09 15:30:50.000000000 -0500
@@ -87,8 +87,8 @@
int stat_flags;
int custom_divisor;
int close_delay;
- unsigned short closing_wait;
- unsigned short closing_wait2;
+ unsigned int closing_wait;
+ unsigned int closing_wait2;
int IER; /* Interrupt Enable Register */
int MCR; /* Modem control register */
unsigned long event;
--- linux-2.6.0-test11/include/linux/generic_serial.h 2003-11-26 15:45:26.000000000 -0500
+++ linux-2.6.0-test11-hz/include/linux/generic_serial.h 2003-12-09 15:31:06.000000000 -0500
@@ -42,7 +42,7 @@
int blocked_open;
struct tty_struct *tty;
unsigned long event;
- unsigned short closing_wait;
+ unsigned int closing_wait;
int close_delay;
struct real_driver *rd;
int wakeup_chars;
--- linux-2.6.0-test11/include/linux/cyclades.h 2003-11-26 15:46:06.000000000 -0500
+++ linux-2.6.0-test11-hz/include/linux/cyclades.h 2003-12-09 15:31:19.000000000 -0500
@@ -581,7 +581,7 @@
int custom_divisor;
int x_char; /* to be pushed out ASAP */
int close_delay;
- unsigned short closing_wait;
+ unsigned int closing_wait;
unsigned long event;
unsigned long last_active;
int count; /* # of fd on device */
--- linux-2.6.0-test11/include/linux/serialP.h 2003-11-26 15:42:57.000000000 -0500
+++ linux-2.6.0-test11-hz/include/linux/serialP.h 2003-12-09 15:29:12.000000000 -0500
@@ -47,8 +47,8 @@
int count;
u8 *iomem_base;
u16 iomem_reg_shift;
- unsigned short close_delay;
- unsigned short closing_wait; /* time to wait before closing */
+ unsigned int close_delay;
+ unsigned int closing_wait; /* time to wait before closing */
struct async_icount icount;
int io_type;
struct async_struct *info;
@@ -69,8 +69,8 @@
int quot;
int x_char; /* xon/xoff character */
int close_delay;
- unsigned short closing_wait;
- unsigned short closing_wait2; /* obsolete */
+ unsigned int closing_wait;
+ unsigned int closing_wait2; /* obsolete */
int IER; /* Interrupt Enable Register */
int MCR; /* Modem control register */
int LCR; /* Line control register */
--- linux-2.6.0-test11/include/net/irda/ircomm_tty.h 2003-11-26 15:43:37.000000000 -0500
+++ linux-2.6.0-test11-hz/include/net/irda/ircomm_tty.h 2003-12-09 15:28:17.000000000 -0500
@@ -97,8 +97,8 @@
struct timer_list watchdog_timer;
struct work_struct tqueue;

- unsigned short close_delay;
- unsigned short closing_wait; /* time to wait before closing */
+ unsigned int close_delay;
+ unsigned int closing_wait; /* time to wait before closing */

int open_count;
int blocked_open; /* # of blocked opens */
--- linux-2.6.0-test11/include/linux/serial.h 2003-11-26 15:43:24.000000000 -0500
+++ linux-2.6.0-test11-hz/include/linux/serial.h 2003-12-09 15:27:09.000000000 -0500
@@ -39,12 +39,12 @@
int xmit_fifo_size;
int custom_divisor;
int baud_base;
- unsigned short close_delay;
+ unsigned int close_delay;
char io_type;
char reserved_char[1];
int hub6;
- unsigned short closing_wait; /* time to wait before closing */
- unsigned short closing_wait2; /* no longer used... */
+ unsigned int closing_wait; /* time to wait before closing */
+ unsigned int closing_wait2; /* no longer used... */
unsigned char *iomem_base;
unsigned short iomem_reg_shift;
unsigned int port_high;

[-- Attachment #2: Ceci est une partie de message numériquement signée. --]
[-- Type: application/pgp-signature, Size: 189 bytes --]