linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH] 2.4: variable HZ
@ 2002-10-18 11:51 Neil Conway
  2002-10-18 18:44 ` Robert Love
  0 siblings, 1 reply; 10+ messages in thread
From: Neil Conway @ 2002-10-18 11:51 UTC (permalink / raw)
  To: rml, linux-kernel

Hiya...  Nice patch, must try it when I find a few minutes - I think I
have a few apps that are limited by select/poll behaviour.

I was looking at your jiffies_to_clock_t() macro, and I notice that it
will screw up badly if the user chooses a HZ value that isn't a multiple
of the normal value (e.g. 1000 is OK, 512 isn't).

How about tweaking the macro a little?  Instead of:
x / (HZ/USER_HZ)
you could use:
(x/HZ*USER_HZ + x%HZ*USER_HZ/HZ)

which minimises roundoff error and also won't overflow (at least, it
won't overflow as long as HZ*USER_HZ doesn't overflow!).

You could even use both versions of the macro, choosing between them at
compile time depending on whether or not (HZ % USER_HZ == 0).

What do you think?

cheers
Neil
PS: I'm off-list.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] 2.4: variable HZ
  2002-10-18 11:51 [PATCH] 2.4: variable HZ Neil Conway
@ 2002-10-18 18:44 ` Robert Love
  2002-10-18 19:38   ` Richard B. Johnson
  2002-10-21  8:15   ` Neil Conway
  0 siblings, 2 replies; 10+ messages in thread
From: Robert Love @ 2002-10-18 18:44 UTC (permalink / raw)
  To: Neil Conway; +Cc: linux-kernel

On Fri, 2002-10-18 at 07:51, Neil Conway wrote:

> I was looking at your jiffies_to_clock_t() macro, and I notice that it
> will screw up badly if the user chooses a HZ value that isn't a multiple
> of the normal value (e.g. 1000 is OK, 512 isn't).

OK, sure, but why specify a power-of-two HZ?  There is absolutely no
reason to, at least on x86.

Want 512?  500 will do just as well and has the benefit of (a) being a
multiple of the previous HZ and (b) evenly dividing into our concept of
time.

	Robert Love


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] 2.4: variable HZ
  2002-10-18 18:44 ` Robert Love
@ 2002-10-18 19:38   ` Richard B. Johnson
  2002-10-19  7:04     ` jdow
  2002-10-19  9:36     ` Willy Tarreau
  2002-10-21  8:15   ` Neil Conway
  1 sibling, 2 replies; 10+ messages in thread
From: Richard B. Johnson @ 2002-10-18 19:38 UTC (permalink / raw)
  To: Robert Love; +Cc: Neil Conway, linux-kernel

On 18 Oct 2002, Robert Love wrote:

> On Fri, 2002-10-18 at 07:51, Neil Conway wrote:
> 
> > I was looking at your jiffies_to_clock_t() macro, and I notice that it
> > will screw up badly if the user chooses a HZ value that isn't a multiple
> > of the normal value (e.g. 1000 is OK, 512 isn't).
> 
> OK, sure, but why specify a power-of-two HZ?  There is absolutely no
> reason to, at least on x86.
> 
> Want 512?  500 will do just as well and has the benefit of (a) being a
> multiple of the previous HZ and (b) evenly dividing into our concept of
> time.
> 
> 	Robert Love
> 

At least on ix86, HZ needs to be something that CLOCK_TICK_RATE/LATCH
comes out fairly close. Remember, LATCH is the divisor for the PIT
and that PIT gets CLOCK_TICK_RATE for its input. If this number isn't
fairly 'exact' there will be much jumping of time in the sawtooth
corrector.

If you are not using ELAN, CLOCK_TICK_RATE is 1193180. If your HZ is
100, you have 1193180/100 = 1193.18, not too exact. if you use
500, you get 1193180/500 = 2386.36 which has twice as much round-off.
If you use 1193180/512 = 2330.43, even a higher fractional part.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).
The US military has given us many words, FUBAR, SNAFU, now ENRON.
Yes, top management were graduates of West Point and Annapolis.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] 2.4: variable HZ
  2002-10-18 19:38   ` Richard B. Johnson
@ 2002-10-19  7:04     ` jdow
  2002-10-21 13:13       ` Richard B. Johnson
  2002-10-19  9:36     ` Willy Tarreau
  1 sibling, 1 reply; 10+ messages in thread
From: jdow @ 2002-10-19  7:04 UTC (permalink / raw)
  To: root, Robert Love; +Cc: Neil Conway, linux-kernel

Richard, would you believe that this is essentially what is done with the
GPS satellites in the dither process and in the clock correction process
to make the drifty Rb standards as stable as ground standards?

(You'd better. I designed the beastie involved.)
{^_-}    Joanne, jdow@earthlink.net
----- Original Message ----- 
From: "Richard B. Johnson" <root@chaos.analogic.com>
To: "Robert Love" <rml@tech9.net>
Cc: "Neil Conway" <nconway.list@ukaea.org.uk>; <linux-kernel@vger.kernel.org>
Sent: Friday, October 18, 2002 12:38
Subject: Re: [PATCH] 2.4: variable HZ


> On 18 Oct 2002, Robert Love wrote:
> 
> > On Fri, 2002-10-18 at 07:51, Neil Conway wrote:
> > 
> > > I was looking at your jiffies_to_clock_t() macro, and I notice that it
> > > will screw up badly if the user chooses a HZ value that isn't a multiple
> > > of the normal value (e.g. 1000 is OK, 512 isn't).
> > 
> > OK, sure, but why specify a power-of-two HZ?  There is absolutely no
> > reason to, at least on x86.
> > 
> > Want 512?  500 will do just as well and has the benefit of (a) being a
> > multiple of the previous HZ and (b) evenly dividing into our concept of
> > time.
> > 
> > Robert Love
> > 
> 
> At least on ix86, HZ needs to be something that CLOCK_TICK_RATE/LATCH
> comes out fairly close. Remember, LATCH is the divisor for the PIT
> and that PIT gets CLOCK_TICK_RATE for its input. If this number isn't
> fairly 'exact' there will be much jumping of time in the sawtooth
> corrector.
> 
> If you are not using ELAN, CLOCK_TICK_RATE is 1193180. If your HZ is
> 100, you have 1193180/100 = 1193.18, not too exact. if you use
> 500, you get 1193180/500 = 2386.36 which has twice as much round-off.
> If you use 1193180/512 = 2330.43, even a higher fractional part.
> 
> Cheers,
> Dick Johnson
> Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).
> The US military has given us many words, FUBAR, SNAFU, now ENRON.
> Yes, top management were graduates of West Point and Annapolis.
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] 2.4: variable HZ
  2002-10-18 19:38   ` Richard B. Johnson
  2002-10-19  7:04     ` jdow
@ 2002-10-19  9:36     ` Willy Tarreau
  1 sibling, 0 replies; 10+ messages in thread
From: Willy Tarreau @ 2002-10-19  9:36 UTC (permalink / raw)
  To: Richard B. Johnson; +Cc: Robert Love, Neil Conway, linux-kernel

On Fri, Oct 18, 2002 at 03:38:43PM -0400, Richard B. Johnson wrote:
> If you are not using ELAN, CLOCK_TICK_RATE is 1193180.

well, in fact it's 1193181.666... (14318180/12).

> If your HZ is 100, you have 1193180/100 = 1193.18, not too exact.

you meant 1000, I suppose ?

> if you use 500, you get 1193180/500 = 2386.36 which has twice as much
> round-off. If you use 1193180/512 = 2330.43, even a higher fractional
> part.

those interested can try 511 Hz (/2334.994) or 1900 Hz (/627.990) which
has the double advantage of being multiple of 100 Hz and have a little
drift due to frac part (/628 gives 1899.97 Hz, and /627 gives 1903.001 Hz).
If you don't need a multiple of 100 Hz, I noticed that dividing by 5709
gives 209.0001 Hz.

I'm also wondering why we never use the RTC as an interrupt source. Are
there any incompatible PCs ?

Cheers,
Willy


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] 2.4: variable HZ
  2002-10-18 18:44 ` Robert Love
  2002-10-18 19:38   ` Richard B. Johnson
@ 2002-10-21  8:15   ` Neil Conway
  1 sibling, 0 replies; 10+ messages in thread
From: Neil Conway @ 2002-10-21  8:15 UTC (permalink / raw)
  To: Robert Love; +Cc: linux-kernel

Robert Love wrote:
> OK, sure, but why specify a power-of-two HZ?  There is absolutely no
> reason to, at least on x86.

Totally agree.  However, I wasn't restricting it to powers of two.  You
just happened to have mentioned 512 (wrt. RedHat).

> Want 512?  500 will do just as well and has the benefit of (a) being a
> multiple of the previous HZ and (b) evenly dividing into our concept of
> time.

512 ~= 500.  150 !~= 100.  Would someone want to use 150?  Maybe...

Anyway, it's no big deal if you prefer to leave your patch as-is. 
However, if you do, then you need to at least add a comment to the code
and modify the Configure.help to make it clear that only integer
multiples work properly.  In fact, you could just make the HZ Config
value be a "speed-up ratio" which would make various bits of the patch
cleaner.

Neil

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] 2.4: variable HZ
  2002-10-19  7:04     ` jdow
@ 2002-10-21 13:13       ` Richard B. Johnson
  0 siblings, 0 replies; 10+ messages in thread
From: Richard B. Johnson @ 2002-10-21 13:13 UTC (permalink / raw)
  To: jdow; +Cc: Robert Love, Neil Conway, linux-kernel

On Sat, 19 Oct 2002, jdow wrote:

> Richard, would you believe that this is essentially what is done with the
> GPS satellites in the dither process and in the clock correction process
> to make the drifty Rb standards as stable as ground standards?
> 
> (You'd better. I designed the beastie involved.)
> {^_-}    Joanne, jdow@earthlink.net

Sure. I helped develop a Kalman Filter that would run in real-time.
It was first implemented in Matlab (which is awful to interpret).
I rewrote it in ix86 assembly, using synthetic division (where you
save the remainder and use it in a subsequent division for the same
element in the polynomial). The result being that the filter generates
no error even though it performs multiple divisions of non-integral
numbers.

These techniques are great for continuous functions. Early filtering
techniques, using classical methods (average, r.m.s, r.s.s, etc.)
develop a bias because of round-off. The synthetic division bounds
the bias to one less than the last divisor.

If you filter enough stuff, over a long enough time, you can make
gold out of shit. The onboard GPS software has a very long time
to tune. Its a good candidate. In principle, the ground standard
doesn't have to be very good as long as it averages correctly
with low residual bias.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).
The US military has given us many words, FUBAR, SNAFU, now ENRON.
Yes, top management were graduates of West Point and Annapolis.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] 2.4: variable HZ
  2002-10-15  6:03 Robert Love
  2002-10-15  6:50 ` Robert Love
@ 2002-10-18 18:27 ` Tim Schmielau
  1 sibling, 0 replies; 10+ messages in thread
From: Tim Schmielau @ 2002-10-18 18:27 UTC (permalink / raw)
  To: Robert Love; +Cc: lkml

On 15 Oct 2002, Robert Love wrote:
> I backported the jiffies_to_clock_t() code from 2.5 to 2.4, mostly just
> for fun.
...
> Oh, and I did not backport 64-bit jiffies yet.

If you would, how would you call the analogous function for 64 bit values?
And the type it returns?

The patches to make the kernel interfaces use the 64 bit jiffies value sit 
in Davej's tree since around 2.5.20-dj3, just waiting for the answer to 
these questions.

jiffies_64_to_clock_t_64() seems a bit lengthy. My current personal 
favourite would be jiffies_64_to_user_HZ(), just returning an u64, so that 
we don't keep on inventing silly types that get used just a very few 
times.

Just my 0.02 euro, though.

Tim


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] 2.4: variable HZ
  2002-10-15  6:03 Robert Love
@ 2002-10-15  6:50 ` Robert Love
  2002-10-18 18:27 ` Tim Schmielau
  1 sibling, 0 replies; 10+ messages in thread
From: Robert Love @ 2002-10-15  6:50 UTC (permalink / raw)
  To: linux-kernel; +Cc: high-res-timers-discourse

On Tue, 2002-10-15 at 02:03, Robert Love wrote:

> It works fine, and I have successfully used HZ=1000 on my machines.

Except processor usage output was screwy.

Attached is an updated patch which fixes the problem.

	Robert Love

diff -urN linux-2.4.20-pre10-ac2/arch/i386/config.in linux/arch/i386/config.in
--- linux-2.4.20-pre10-ac2/arch/i386/config.in	2002-10-14 01:43:05.000000000 -0400
+++ linux/arch/i386/config.in	2002-10-15 02:41:39.000000000 -0400
@@ -244,6 +244,7 @@
 mainmenu_option next_comment
 comment 'General setup'
 
+int 'Timer frequency (HZ) (100)' CONFIG_HZ 100
 bool 'Networking support' CONFIG_NET
 
 # Visual Workstation support is utterly broken.
diff -urN linux-2.4.20-pre10-ac2/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.4.20-pre10-ac2/Documentation/Configure.help	2002-10-14 01:43:06.000000000 -0400
+++ linux/Documentation/Configure.help	2002-10-15 02:41:40.000000000 -0400
@@ -2411,6 +2411,18 @@
   behaviour is platform-dependent, but normally the flash frequency is
   a hyperbolic function of the 5-minute load average.
 
+Timer frequency
+CONFIG_HZ
+  The frequency the system timer interrupt pops.  Higher tick values provide
+  improved granularity of timers, improved select() and poll() performance,
+  and lower scheduling latency.  Higher values, however, increase interrupt
+  overhead and will allow jiffie wraparound sooner.  For compatibility, the
+  tick count is always exported as if HZ=100.
+
+  The default value, which was the value for all of eternity, is 100.  If
+  you are looking to provide better timer granularity or increased desktop
+  performance, try 500 or 1000.  In unsure, go with the default of 100.
+
 Networking support
 CONFIG_NET
   Unless you really know what you are doing, you should say Y here.
diff -urN linux-2.4.20-pre10-ac2/fs/proc/array.c linux/fs/proc/array.c
--- linux-2.4.20-pre10-ac2/fs/proc/array.c	2002-10-14 01:43:10.000000000 -0400
+++ linux/fs/proc/array.c	2002-10-14 18:24:48.000000000 -0400
@@ -360,15 +360,15 @@
 		task->cmin_flt,
 		task->maj_flt,
 		task->cmaj_flt,
-		task->times.tms_utime,
-		task->times.tms_stime,
-		task->times.tms_cutime,
-		task->times.tms_cstime,
+		jiffies_to_clock_t(task->times.tms_utime),
+		jiffies_to_clock_t(task->times.tms_stime),
+		jiffies_to_clock_t(task->times.tms_cutime),
+		jiffies_to_clock_t(task->times.tms_cstime),
 		priority,
 		nice,
 		0UL /* removed */,
-		task->it_real_value,
-		task->start_time,
+		jiffies_to_clock_t(task->it_real_value),
+		jiffies_to_clock_t(task->start_time),
 		vsize,
 		mm ? mm->rss : 0, /* you might want to shift this left 3 */
 		task->rlim[RLIMIT_RSS].rlim_cur,
@@ -686,14 +686,14 @@
 
 	len = sprintf(buffer,
 		"cpu  %lu %lu\n",
-		task->times.tms_utime,
-		task->times.tms_stime);
+		jiffies_to_clock_t(task->times.tms_utime),
+		jiffies_to_clock_t(task->times.tms_stime));
 		
 	for (i = 0 ; i < smp_num_cpus; i++)
 		len += sprintf(buffer + len, "cpu%d %lu %lu\n",
 			i,
-			task->per_cpu_utime[cpu_logical_map(i)],
-			task->per_cpu_stime[cpu_logical_map(i)]);
+			jiffies_to_clock_t(task->per_cpu_utime[cpu_logical_map(i)]),
+			jiffies_to_clock_t(task->per_cpu_stime[cpu_logical_map(i)]));
 
 	return len;
 }
diff -urN linux-2.4.20-pre10-ac2/fs/proc/proc_misc.c linux/fs/proc/proc_misc.c
--- linux-2.4.20-pre10-ac2/fs/proc/proc_misc.c	2002-10-14 01:43:10.000000000 -0400
+++ linux/fs/proc/proc_misc.c	2002-10-15 02:29:21.000000000 -0400
@@ -317,16 +317,16 @@
 {
 	int i, len = 0;
 	extern unsigned long total_forks;
-	unsigned long jif = jiffies;
+	unsigned long jif = jiffies_to_clock_t(jiffies);
 	unsigned int sum = 0, user = 0, nice = 0, system = 0;
 	int major, disk;
 
 	for (i = 0 ; i < smp_num_cpus; i++) {
 		int cpu = cpu_logical_map(i), j;
 
-		user += kstat.per_cpu_user[cpu];
-		nice += kstat.per_cpu_nice[cpu];
-		system += kstat.per_cpu_system[cpu];
+		user += jiffies_to_clock_t(kstat.per_cpu_user[cpu]);
+		nice += jiffies_to_clock_t(kstat.per_cpu_nice[cpu]);
+		system += jiffies_to_clock_t(kstat.per_cpu_system[cpu]);
 #if !defined(CONFIG_ARCH_S390)
 		for (j = 0 ; j < NR_IRQS ; j++)
 			sum += kstat.irqs[cpu][j];
@@ -340,10 +340,10 @@
 		proc_sprintf(page, &off, &len,
 			"cpu%d %u %u %u %lu\n",
 			i,
-			kstat.per_cpu_user[cpu_logical_map(i)],
-			kstat.per_cpu_nice[cpu_logical_map(i)],
-			kstat.per_cpu_system[cpu_logical_map(i)],
-			jif - (  kstat.per_cpu_user[cpu_logical_map(i)] \
+			jiffies_to_clock_t(kstat.per_cpu_user[cpu_logical_map(i)]),
+			jiffies_to_clock_t(kstat.per_cpu_nice[cpu_logical_map(i)]),
+			jiffies_to_clock_t(kstat.per_cpu_system[cpu_logical_map(i)]),
+			jif - jiffies_to_clock_t(kstat.per_cpu_user[cpu_logical_map(i)] \
 				   + kstat.per_cpu_nice[cpu_logical_map(i)] \
 				   + kstat.per_cpu_system[cpu_logical_map(i)]));
 	proc_sprintf(page, &off, &len,
diff -urN linux-2.4.20-pre10-ac2/include/asm-i386/param.h linux/include/asm-i386/param.h
--- linux-2.4.20-pre10-ac2/include/asm-i386/param.h	2002-10-14 01:33:16.000000000 -0400
+++ linux/include/asm-i386/param.h	2002-10-14 18:46:32.000000000 -0400
@@ -1,8 +1,17 @@
 #ifndef _ASMi386_PARAM_H
 #define _ASMi386_PARAM_H
 
+#include <linux/config.h>
+
+#ifdef __KERNEL__
+# define HZ		CONFIG_HZ	/* internal kernel timer frequency */
+# define USER_HZ	100		/* some user interfaces are in ticks */
+# define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
+# define jiffies_to_clock_t(x)	((x) / ((HZ) / (USER_HZ)))
+#endif
+
 #ifndef HZ
-#define HZ 100
+#define HZ 100				/* if userspace cheats, give them 100 */
 #endif
 
 #define EXEC_PAGESIZE	4096
@@ -17,8 +26,4 @@
 
 #define MAXHOSTNAMELEN	64	/* max length of hostname */
 
-#ifdef __KERNEL__
-# define CLOCKS_PER_SEC	100	/* frequency at which times() counts */
-#endif
-
 #endif
diff -urN linux-2.4.20-pre10-ac2/kernel/signal.c linux/kernel/signal.c
--- linux-2.4.20-pre10-ac2/kernel/signal.c	2002-10-14 01:43:11.000000000 -0400
+++ linux/kernel/signal.c	2002-10-14 18:24:49.000000000 -0400
@@ -13,7 +13,7 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/sched.h>
-
+#include <asm/param.h>
 #include <asm/uaccess.h>
 
 /*
@@ -775,8 +775,8 @@
 	info.si_uid = tsk->uid;
 
 	/* FIXME: find out whether or not this is supposed to be c*time. */
-	info.si_utime = tsk->times.tms_utime;
-	info.si_stime = tsk->times.tms_stime;
+	info.si_utime = jiffies_to_clock_t(tsk->times.tms_utime);
+	info.si_stime = jiffies_to_clock_t(tsk->times.tms_stime);
 
 	status = tsk->exit_code & 0x7f;
 	why = SI_KERNEL;	/* shouldn't happen */
diff -urN linux-2.4.20-pre10-ac2/kernel/sys.c linux/kernel/sys.c
--- linux-2.4.20-pre10-ac2/kernel/sys.c	2002-10-14 01:43:11.000000000 -0400
+++ linux/kernel/sys.c	2002-10-14 18:24:49.000000000 -0400
@@ -15,7 +15,7 @@
 #include <linux/prctl.h>
 #include <linux/init.h>
 #include <linux/highuid.h>
-
+#include <asm/param.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -792,16 +792,23 @@
 
 asmlinkage long sys_times(struct tms * tbuf)
 {
+	struct tms temp;
+
 	/*
 	 *	In the SMP world we might just be unlucky and have one of
 	 *	the times increment as we use it. Since the value is an
 	 *	atomically safe type this is just fine. Conceptually its
 	 *	as if the syscall took an instant longer to occur.
 	 */
-	if (tbuf)
-		if (copy_to_user(tbuf, &current->times, sizeof(struct tms)))
+	if (tbuf) {
+		temp.tms_utime = jiffies_to_clock_t(current->times.tms_utime);
+		temp.tms_stime = jiffies_to_clock_t(current->times.tms_stime);
+		temp.tms_cutime = jiffies_to_clock_t(current->times.tms_cutime);
+		temp.tms_cstime = jiffies_to_clock_t(current->times.tms_cstime);
+		if (copy_to_user(tbuf, &temp, sizeof(struct tms)))
 			return -EFAULT;
-	return jiffies;
+	}
+	return jiffies_to_clock_t(jiffies);
 }
 
 /*


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] 2.4: variable HZ
@ 2002-10-15  6:03 Robert Love
  2002-10-15  6:50 ` Robert Love
  2002-10-18 18:27 ` Tim Schmielau
  0 siblings, 2 replies; 10+ messages in thread
From: Robert Love @ 2002-10-15  6:03 UTC (permalink / raw)
  To: linux-kernel; +Cc: high-res-timers-discourse

I backported the jiffies_to_clock_t() code from 2.5 to 2.4, mostly just
for fun.

It works fine, and I have successfully used HZ=1000 on my machines.  It
is the same API as 2.5, used in the same places - we export a static
HZ=100 to user-space and convert from the real HZ as needed.  The only
difference is I added a CONFIG_HZ to allow the user to set the value.

There are probably some HZ values you cannot use due to NTP issues.  I
suggest HZ=1000, since I know that works, and 2.5 is using it.  RedHat
is supposedly shipping their kernel with HZ=512 but I do not know if
they did anything else special.

Oh, and I did not backport 64-bit jiffies yet.  So HZ=1000 will wrap
around in just under 50 days.  If you just cannot have that, stick with
a lower value.

Patch is against 2.4.20-pre10-ac2 but applies OK to all 2.4.20-pre and
2.4.19 kernels.

Enjoy,

	Robert Love

diff -urN linux-2.4.20-pre10-ac2/arch/i386/config.in linux/arch/i386/config.in
--- linux-2.4.20-pre10-ac2/arch/i386/config.in	2002-10-14 01:43:05.000000000 -0400
+++ linux/arch/i386/config.in	2002-10-14 18:24:48.000000000 -0400
@@ -244,6 +244,7 @@
 mainmenu_option next_comment
 comment 'General setup'
 
+int 'Timer frequency (HZ) (100)' CONFIG_HZ 100
 bool 'Networking support' CONFIG_NET
 
 # Visual Workstation support is utterly broken.
diff -urN linux-2.4.20-pre10-ac2/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.4.20-pre10-ac2/Documentation/Configure.help	2002-10-14 01:43:06.000000000 -0400
+++ linux/Documentation/Configure.help	2002-10-14 18:32:38.000000000 -0400
@@ -2411,6 +2411,18 @@
   behaviour is platform-dependent, but normally the flash frequency is
   a hyperbolic function of the 5-minute load average.
 
+Timer frequency
+CONFIG_HZ
+  The frequency the system timer interrupt pops.  Higher tick values provide
+  improved granularity of timers, improved select() and poll() performance,
+  and lower scheduling latency.  Higher values, however, increase interrupt
+  overhead and will allow jiffie wraparound sooner.  For compatibility, the
+  tick count is always exported as if HZ=100.
+
+  The default value, which was the value for all of eternity, is 100.  If
+  you are looking to provide better timer granularity or increased desktop
+  performance, try 500 or 1000.  In unsure, go with the default of 100.
+
 Networking support
 CONFIG_NET
   Unless you really know what you are doing, you should say Y here.
diff -urN linux-2.4.20-pre10-ac2/fs/proc/array.c linux/fs/proc/array.c
--- linux-2.4.20-pre10-ac2/fs/proc/array.c	2002-10-14 01:43:10.000000000 -0400
+++ linux/fs/proc/array.c	2002-10-14 18:24:48.000000000 -0400
@@ -360,15 +360,15 @@
 		task->cmin_flt,
 		task->maj_flt,
 		task->cmaj_flt,
-		task->times.tms_utime,
-		task->times.tms_stime,
-		task->times.tms_cutime,
-		task->times.tms_cstime,
+		jiffies_to_clock_t(task->times.tms_utime),
+		jiffies_to_clock_t(task->times.tms_stime),
+		jiffies_to_clock_t(task->times.tms_cutime),
+		jiffies_to_clock_t(task->times.tms_cstime),
 		priority,
 		nice,
 		0UL /* removed */,
-		task->it_real_value,
-		task->start_time,
+		jiffies_to_clock_t(task->it_real_value),
+		jiffies_to_clock_t(task->start_time),
 		vsize,
 		mm ? mm->rss : 0, /* you might want to shift this left 3 */
 		task->rlim[RLIMIT_RSS].rlim_cur,
@@ -686,14 +686,14 @@
 
 	len = sprintf(buffer,
 		"cpu  %lu %lu\n",
-		task->times.tms_utime,
-		task->times.tms_stime);
+		jiffies_to_clock_t(task->times.tms_utime),
+		jiffies_to_clock_t(task->times.tms_stime));
 		
 	for (i = 0 ; i < smp_num_cpus; i++)
 		len += sprintf(buffer + len, "cpu%d %lu %lu\n",
 			i,
-			task->per_cpu_utime[cpu_logical_map(i)],
-			task->per_cpu_stime[cpu_logical_map(i)]);
+			jiffies_to_clock_t(task->per_cpu_utime[cpu_logical_map(i)]),
+			jiffies_to_clock_t(task->per_cpu_stime[cpu_logical_map(i)]));
 
 	return len;
 }
diff -urN linux-2.4.20-pre10-ac2/fs/proc/proc_misc.c linux/fs/proc/proc_misc.c
--- linux-2.4.20-pre10-ac2/fs/proc/proc_misc.c	2002-10-14 01:43:10.000000000 -0400
+++ linux/fs/proc/proc_misc.c	2002-10-14 18:40:08.000000000 -0400
@@ -317,7 +317,7 @@
 {
 	int i, len = 0;
 	extern unsigned long total_forks;
-	unsigned long jif = jiffies;
+	unsigned long jif = jiffies_to_clock_t(jiffies);
 	unsigned int sum = 0, user = 0, nice = 0, system = 0;
 	int major, disk;
 
@@ -334,16 +334,19 @@
 	}
 
 	proc_sprintf(page, &off, &len,
-		      "cpu  %u %u %u %lu\n", user, nice, system,
+		      "cpu  %u %u %u %lu\n",
+		      jiffies_to_clock_t(user),
+		      jiffies_to_clock_t(nice),
+		      jiffies_to_clock_t(system),
 		      jif * smp_num_cpus - (user + nice + system));
 	for (i = 0 ; i < smp_num_cpus; i++)
 		proc_sprintf(page, &off, &len,
 			"cpu%d %u %u %u %lu\n",
 			i,
-			kstat.per_cpu_user[cpu_logical_map(i)],
-			kstat.per_cpu_nice[cpu_logical_map(i)],
-			kstat.per_cpu_system[cpu_logical_map(i)],
-			jif - (  kstat.per_cpu_user[cpu_logical_map(i)] \
+			jiffies_to_clock_t(kstat.per_cpu_user[cpu_logical_map(i)]),
+			jiffies_to_clock_t(kstat.per_cpu_nice[cpu_logical_map(i)]),
+			jiffies_to_clock_t(kstat.per_cpu_system[cpu_logical_map(i)]),
+			jif - jiffies_to_clock_t(kstat.per_cpu_user[cpu_logical_map(i)] \
 				   + kstat.per_cpu_nice[cpu_logical_map(i)] \
 				   + kstat.per_cpu_system[cpu_logical_map(i)]));
 	proc_sprintf(page, &off, &len,
diff -urN linux-2.4.20-pre10-ac2/include/asm-i386/param.h linux/include/asm-i386/param.h
--- linux-2.4.20-pre10-ac2/include/asm-i386/param.h	2002-10-14 01:33:16.000000000 -0400
+++ linux/include/asm-i386/param.h	2002-10-14 18:33:35.000000000 -0400
@@ -1,8 +1,17 @@
 #ifndef _ASMi386_PARAM_H
 #define _ASMi386_PARAM_H
 
+#include <linux/config.h>
+
+#ifdef __KERNEL__
+# define HZ		CONFIG_HZ	/* internal kernel timer frequency */
+# define USER_HZ	100		/* some user interfaces are in ticks */
+# define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
+# define jiffies_to_clock_t(x)	((x) / ((HZ) / (USER_HZ)))
+#endif
+
 #ifndef HZ
-#define HZ 100
+#define HZ 100				/* if userspace cheats, give them 100 */
 #endif
 
 #define EXEC_PAGESIZE	4096
@@ -17,8 +26,4 @@
 
 #define MAXHOSTNAMELEN	64	/* max length of hostname */
 
-#ifdef __KERNEL__
-# define CLOCKS_PER_SEC	100	/* frequency at which times() counts */
-#endif
-
 #endif
diff -urN linux-2.4.20-pre10-ac2/kernel/signal.c linux/kernel/signal.c
--- linux-2.4.20-pre10-ac2/kernel/signal.c	2002-10-14 01:43:11.000000000 -0400
+++ linux/kernel/signal.c	2002-10-14 18:24:49.000000000 -0400
@@ -13,7 +13,7 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/sched.h>
-
+#include <asm/param.h>
 #include <asm/uaccess.h>
 
 /*
@@ -775,8 +775,8 @@
 	info.si_uid = tsk->uid;
 
 	/* FIXME: find out whether or not this is supposed to be c*time. */
-	info.si_utime = tsk->times.tms_utime;
-	info.si_stime = tsk->times.tms_stime;
+	info.si_utime = jiffies_to_clock_t(tsk->times.tms_utime);
+	info.si_stime = jiffies_to_clock_t(tsk->times.tms_stime);
 
 	status = tsk->exit_code & 0x7f;
 	why = SI_KERNEL;	/* shouldn't happen */
diff -urN linux-2.4.20-pre10-ac2/kernel/sys.c linux/kernel/sys.c
--- linux-2.4.20-pre10-ac2/kernel/sys.c	2002-10-14 01:43:11.000000000 -0400
+++ linux/kernel/sys.c	2002-10-14 18:24:49.000000000 -0400
@@ -15,7 +15,7 @@
 #include <linux/prctl.h>
 #include <linux/init.h>
 #include <linux/highuid.h>
-
+#include <asm/param.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -792,16 +792,23 @@
 
 asmlinkage long sys_times(struct tms * tbuf)
 {
+	struct tms temp;
+
 	/*
 	 *	In the SMP world we might just be unlucky and have one of
 	 *	the times increment as we use it. Since the value is an
 	 *	atomically safe type this is just fine. Conceptually its
 	 *	as if the syscall took an instant longer to occur.
 	 */
-	if (tbuf)
-		if (copy_to_user(tbuf, &current->times, sizeof(struct tms)))
+	if (tbuf) {
+		temp.tms_utime = jiffies_to_clock_t(current->times.tms_utime);
+		temp.tms_stime = jiffies_to_clock_t(current->times.tms_stime);
+		temp.tms_cutime = jiffies_to_clock_t(current->times.tms_cutime);
+		temp.tms_cstime = jiffies_to_clock_t(current->times.tms_cstime);
+		if (copy_to_user(tbuf, &temp, sizeof(struct tms)))
 			return -EFAULT;
-	return jiffies;
+	}
+	return jiffies_to_clock_t(jiffies);
 }
 
 /*




^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2002-10-21 13:06 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-10-18 11:51 [PATCH] 2.4: variable HZ Neil Conway
2002-10-18 18:44 ` Robert Love
2002-10-18 19:38   ` Richard B. Johnson
2002-10-19  7:04     ` jdow
2002-10-21 13:13       ` Richard B. Johnson
2002-10-19  9:36     ` Willy Tarreau
2002-10-21  8:15   ` Neil Conway
  -- strict thread matches above, loose matches on Subject: below --
2002-10-15  6:03 Robert Love
2002-10-15  6:50 ` Robert Love
2002-10-18 18:27 ` Tim Schmielau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).