linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* setitimer 1 usec fails
@ 2003-05-26 21:09 Richard C Bilson
  0 siblings, 0 replies; 6+ messages in thread
From: Richard C Bilson @ 2003-05-26 21:09 UTC (permalink / raw)
  To: linux-kernel

In trying the latest development kernel, I've noticed that calling
setitimer with a 1 usec delay (the shortest possible delay) results in
the timer never going off.  2 usec is ok but 1 is not, so I suspect
that somehow things are being rounded off incorrectly.  The attached
program demonstrates the problem on 2.5.69, but runs correctly on a
2.4.20 kernel.

I have only had the opportunity to try this on a single architecture
(ia64), so if anyone can convince me that it's a platform-specific
problem I'll be happy to take my gripe to the ia64 list.  I've tried to
figure out how the usecs are converted to jiffies, but the code is
sufficiently convoluted that I thought I'd throw it out in the hope of
finding someone who understands the situation a little better.

- Richard

// When run, this program should print "handled alarm" from within the
// signal handler, and "out of sigsuspend" right after.  It works on
// 2.4.20 or if MY_TIMER_USEC is >= 2, but not on 2.5.69 with
// MY_TIMER_USEC = 1.

#define MY_TIMER_USEC 1

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>

void
alarm_handler( int x )
{
  printf( "handled alarm\n" );
  return;
}

int
main()
{
  struct itimerval it = { { 0, 0 }, { 0, MY_TIMER_USEC } };
  sigset_t mask;
  struct sigaction act;

  act.sa_handler = alarm_handler;
  act.sa_flags = 0;
  sigemptyset( &act.sa_mask );
  if( sigaction(SIGALRM, &act, 0) ) {
    perror( "sigaction" );
    exit( 1 );
  }
  
  if( setitimer(ITIMER_REAL, &it, 0) ) {
    perror( "setitimer" );
    exit( 1 );
  }
  
  sigemptyset( &mask );
  sigsuspend( &mask );
  
  printf( "out of sigsuspend\n" );
  return 0;
}

-- 
Richard C. Bilson, Research Assistant   | School of Computer Science
rcbilson@plg.uwaterloo.ca               | University of Waterloo
http://plg.uwaterloo.ca/~rcbilson       | 200 University Avenue West
Office: DC 3548F Ph: (519)888-4567x4822 | Waterloo, Ontario, CANADA N2L 3G1

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

* Re: setitimer 1 usec fails
  2003-05-27 18:27   ` David Mosberger
@ 2003-05-27 20:01     ` george anzinger
  0 siblings, 0 replies; 6+ messages in thread
From: george anzinger @ 2003-05-27 20:01 UTC (permalink / raw)
  To: davidm
  Cc: Andrew Morton, Richard C Bilson, linux-kernel, Eric Piel, Ulrich Windl

David Mosberger wrote:
>>>>>>On Mon, 26 May 2003 15:00:53 -0700, george anzinger <george@mvista.com> said:
> 
> 
>   George> As a test, you might try your test with HZ=1000 (a number I
>   George> recommend for ia64, if at all possible).
> 
> I suspect you might have a slightly biased view on this. ;-) Yes,
> HZ=1000 makes some problems easier to convert ticks to real time, but
> slower to convert real time to ticks.

Ulrich has written something on this.  Maybe he could comment  :)

-g

> 
> Besides, the Linux kernel MUST work with (fairly) arbitrary HZ values,
> because some platforms just don't have much of a choice (e.g., Alpha
> is pretty much forced to 1024Hz).
> 
> But, yes, on ia64 we can choose HZ to our liking.  If someone presents
> evidence that shows a real benefit for a value other than 1024, I'm
> certainly willing to listen.
> 
> 	--david
> 
> 

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

* Re:  setitimer 1 usec fails
  2003-05-26 22:00 ` george anzinger
  2003-05-27  9:05   ` Eric Piel
@ 2003-05-27 18:27   ` David Mosberger
  2003-05-27 20:01     ` george anzinger
  1 sibling, 1 reply; 6+ messages in thread
From: David Mosberger @ 2003-05-27 18:27 UTC (permalink / raw)
  To: george anzinger; +Cc: Andrew Morton, Richard C Bilson, linux-kernel, Eric Piel

>>>>> On Mon, 26 May 2003 15:00:53 -0700, george anzinger <george@mvista.com> said:

  George> As a test, you might try your test with HZ=1000 (a number I
  George> recommend for ia64, if at all possible).

I suspect you might have a slightly biased view on this. ;-) Yes,
HZ=1000 makes some problems easier to convert ticks to real time, but
slower to convert real time to ticks.

Besides, the Linux kernel MUST work with (fairly) arbitrary HZ values,
because some platforms just don't have much of a choice (e.g., Alpha
is pretty much forced to 1024Hz).

But, yes, on ia64 we can choose HZ to our liking.  If someone presents
evidence that shows a real benefit for a value other than 1024, I'm
certainly willing to listen.

	--david

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

* Re: setitimer 1 usec fails
@ 2003-05-27 17:19 Richard C Bilson
  0 siblings, 0 replies; 6+ messages in thread
From: Richard C Bilson @ 2003-05-27 17:19 UTC (permalink / raw)
  To: Eric.Piel, george; +Cc: akpm, davidm, linux-kernel

> From Eric.Piel@Bull.Net  Tue May 27 05:05:53 2003
> 
> With the patch atatched the bug seems to go away, for the 030521 release
> of IA64 patch (and probably the previous release also). Could you
> confirm, Richard? I think it's kind of architecture specific because
> this bug shouldn't happen with HZ=1000 (i386) ;-)

Yes -- it fixes the program I posted, as well as my original program.
Thanks very much, Eric!

- Richard

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

* Re: setitimer 1 usec fails
  2003-05-26 22:00 ` george anzinger
@ 2003-05-27  9:05   ` Eric Piel
  2003-05-27 18:27   ` David Mosberger
  1 sibling, 0 replies; 6+ messages in thread
From: Eric Piel @ 2003-05-27  9:05 UTC (permalink / raw)
  To: george anzinger
  Cc: Andrew Morton, Richard C Bilson, linux-kernel, David Mosberger

[-- Attachment #1: Type: text/plain, Size: 2281 bytes --]

george anzinger wrote:
> 
> > I have only had the opportunity to try this on a single architecture
> > (ia64), so if anyone can convince me that it's a platform-specific
> > problem I'll be happy to take my gripe to the ia64 list.  I've tried to
> > figure out how the usecs are converted to jiffies, but the code is
> > sufficiently convoluted that I thought I'd throw it out in the hope of
> > finding someone who understands the situation a little better.
> 
> I am not sure, but this could be related to the HZ=1024 problem Eric
> Piel and I are trying to run down.  This is a rather bad choice for HZ
> due to round off error on the conversions to usec.  We THINK the
> right thing to do is to convert to nsec (this is for TICK_NSEC()),
> directly rather than first to usec and then to nsec.
With the patch atatched the bug seems to go away, for the 030521 release
of IA64 patch (and probably the previous release also). Could you
confirm, Richard? I think it's kind of architecture specific because
this bug shouldn't happen with HZ=1000 (i386) ;-)
David, would you mind checking this patch does keep profil() working on
your latest release? That's a kind of pre-patch for the problems
encountered recently with the timers and sleeps.

 
> The additional problem is that the ntp code attempts to correct for
> the roundoff error which makes for an always correcting wall clock
> (even without turning on ntp).  What is needed and what I am trying to
> find time to do, is to convert the ntp code to work from the nsec
> resolution of xtime rather from the old usec resolution.  Problem is I
> don't know the ntp code so it is a bit of a learning curve.
George, are you saying you are converting the internal code of ntp to
nsec or only modifying it a little bit to get nsec resolution on the "HZ
rounding error correction"? Anyway, I would be pleased to try your code
on IA64 :-)

> 
> Help here is welcome!!
> 
> As a test, you might try your test with HZ=1000 (a number I recommend
> for ia64, if at all possible).
IMHO if it works with HZ=1000 it's just thanks to some particular case
when HZ is multiple of 10. But the kernel should work with any HZ, I've
no idea why HZ=1024 for most architectures but it shouldn't have to be
changed just to suit some broken code.

Eric

[-- Attachment #2: sleep-too-short-HZ-conversion-030526a.patch --]
[-- Type: text/plain, Size: 5970 bytes --]

diff -urN -X /home/piele/dontdiff linux-2.5.69-ia64-030521.orig/Makefile linux-2.5.69-ia64-sleep/Makefile
--- linux-2.5.69-ia64-030521.orig/Makefile	2003-05-26 12:03:13.000000000 +0200
+++ linux-2.5.69-ia64-sleep/Makefile	2003-05-26 14:16:25.000000000 +0200
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 69
-EXTRAVERSION = -eric-2
+EXTRAVERSION = -eric-sleep-2
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
Binary files linux-2.5.69-ia64-030521.orig/arch/ia64/boot/vmlinux.gz and linux-2.5.69-ia64-sleep/arch/ia64/boot/vmlinux.gz differ
diff -urN -X /home/piele/dontdiff linux-2.5.69-ia64-030521.orig/fs/proc/proc_misc.c linux-2.5.69-ia64-sleep/fs/proc/proc_misc.c
--- linux-2.5.69-ia64-030521.orig/fs/proc/proc_misc.c	2003-05-05 01:53:02.000000000 +0200
+++ linux-2.5.69-ia64-sleep/fs/proc/proc_misc.c	2003-05-26 13:00:47.000000000 +0200
@@ -137,36 +137,20 @@
 static int uptime_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
-	u64 uptime;
-	unsigned long uptime_remainder;
+	u64 uptime, idle = init_task.utime + init_task.stime;
+	unsigned long uptime_remainder, idle_remainder;
 	int len;
 
 	uptime = get_jiffies_64() - INITIAL_JIFFIES;
 	uptime_remainder = (unsigned long) do_div(uptime, HZ);
+	idle_remainder = (unsigned long) do_div(idle, HZ);
 
-#if HZ!=100
-	{
-		u64 idle = init_task.utime + init_task.stime;
-		unsigned long idle_remainder;
-
-		idle_remainder = (unsigned long) do_div(idle, HZ);
-		len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
-			(unsigned long) uptime,
-			(uptime_remainder * 100) / HZ,
-			(unsigned long) idle,
-			(idle_remainder * 100) / HZ);
-	}
-#else
-	{
-		unsigned long idle = init_task.utime + init_task.stime;
-
-		len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
-			(unsigned long) uptime,
-			uptime_remainder,
-			idle / HZ,
-			idle % HZ);
-	}
-#endif
+	len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
+		(unsigned long) uptime,
+		(uptime_remainder * 100) / HZ,
+		(unsigned long) idle,
+		(idle_remainder * 100) / HZ);
+	
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
diff -urN -X /home/piele/dontdiff linux-2.5.69-ia64-030521.orig/include/linux/timex.h linux-2.5.69-ia64-sleep/include/linux/timex.h
--- linux-2.5.69-ia64-030521.orig/include/linux/timex.h	2003-05-26 11:01:49.000000000 +0200
+++ linux-2.5.69-ia64-sleep/include/linux/timex.h	2003-05-26 13:00:47.000000000 +0200
@@ -157,27 +157,12 @@
 /* LATCH is used in the interval timer and ftape setup. */
 #define LATCH  ((CLOCK_TICK_RATE + HZ/2) / HZ)	/* For divider */
 
-/* Suppose we want to devide two numbers NOM and DEN: NOM/DEN, the we can
- * improve accuracy by shifting LSH bits, hence calculating:
- *     (NOM << LSH) / DEN
- * This however means trouble for large NOM, because (NOM << LSH) may no
- * longer fit in 32 bits. The following way of calculating this gives us
- * some slack, under the following onditions:
- *   - (NOM / DEN) fits in (32 - LSH) bits.
- *   - (NOM % DEN) fits in (32 - LSH) bits.
- */
-#define SH_DIV(NOM,DEN,LSH) (   ((NOM / DEN) << LSH)                    \
-                             + (((NOM % DEN) << LSH) + DEN / 2) / DEN)
-
-/* HZ is the requested value. ACTHZ is actual HZ ("<< 8" is for accuracy) */
-#define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8))
-
 /* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */
-#define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ)
+#define TICK_USEC ((TICK_NSEC(TUSEC) + 1000UL/2) / 1000UL)
 
 /* TICK_NSEC is the time between ticks in nsec assuming real ACTHZ and	*/
 /* a value TUSEC for TICK_USEC (can be set bij adjtimex)		*/
-#define TICK_NSEC(TUSEC) (SH_DIV (TUSEC * USER_HZ * 1000, ACTHZ, 8))
+#define TICK_NSEC(TUSEC) ((1000000000UL + USER_HZ/2) / USER_HZ)
 
 #include <linux/time.h>
 /*
diff -urN -X /home/piele/dontdiff linux-2.5.69-ia64-030521.orig/kernel/posix-timers.c linux-2.5.69-ia64-sleep/kernel/posix-timers.c
--- linux-2.5.69-ia64-030521.orig/kernel/posix-timers.c	2003-05-26 11:01:49.000000000 +0200
+++ linux-2.5.69-ia64-sleep/kernel/posix-timers.c	2003-05-26 15:37:34.000000000 +0200
@@ -1210,8 +1210,8 @@
 		if (abs || !rq_time) {
 			adjust_abs_time(&posix_clocks[which_clock], &t, abs,
 					&rq_time);
+			rq_time += (t.tv_sec || t.tv_nsec);
 		}
-
 		left = rq_time - get_jiffies_64();
 		if (left >= (s64)MAX_JIFFY_OFFSET)
 			left = (s64)MAX_JIFFY_OFFSET;
diff -urN -X /home/piele/dontdiff linux-2.5.69-ia64-030521.orig/kernel/timer.c linux-2.5.69-ia64-sleep/kernel/timer.c
--- linux-2.5.69-ia64-030521.orig/kernel/timer.c	2003-05-26 11:01:50.000000000 +0200
+++ linux-2.5.69-ia64-sleep/kernel/timer.c	2003-05-26 13:00:47.000000000 +0200
@@ -469,7 +469,7 @@
 long time_maxerror = NTP_PHASE_LIMIT;	/* maximum error (us)		*/
 long time_esterror = NTP_PHASE_LIMIT;	/* estimated error (us)		*/
 long time_phase;			/* phase offset (scaled us)	*/
-long time_freq = ((1000000 + HZ/2) % HZ - HZ/2) << SHIFT_USEC;
+long time_freq = (((NSEC_PER_SEC + HZ/2) % HZ - HZ/2) << SHIFT_USEC) / NSEC_PER_USEC;
 					/* frequency offset (scaled ppm)*/
 long time_adj;				/* tick adjust (scaled 1 / HZ)	*/
 long time_reftime;			/* time at last adjustment (s)	*/
@@ -633,12 +633,12 @@
 	 * advance the tick more.
 	 */
 	time_phase += time_adj;
-	if (time_phase <= -FINEUSEC) {
-		long ltemp = -time_phase >> (SHIFT_SCALE - 10);
+	if (time_phase <= -(FINEUSEC >> 10)) {
+		long ltemp = -time_phase >> (SHIFT_SCALE - 10); /* quick fix for nsec : 2^10 ~ 1000 */
 		time_phase += ltemp << (SHIFT_SCALE - 10);
 		delta_nsec -= ltemp;
 	}
-	else if (time_phase >= FINEUSEC) {
+	else if (time_phase >= (FINEUSEC >> 10)) {
 		long ltemp = time_phase >> (SHIFT_SCALE - 10);
 		time_phase -= ltemp << (SHIFT_SCALE - 10);
 		delta_nsec += ltemp;
Binary files linux-2.5.69-ia64-030521.orig/scripts/kconfig/conf and linux-2.5.69-ia64-sleep/scripts/kconfig/conf differ
Binary files linux-2.5.69-ia64-030521.orig/vmlinux.gz and linux-2.5.69-ia64-sleep/vmlinux.gz differ

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

* Re:  setitimer 1 usec fails
       [not found] <20030526142555.67a79694.akpm@digeo.com>
@ 2003-05-26 22:00 ` george anzinger
  2003-05-27  9:05   ` Eric Piel
  2003-05-27 18:27   ` David Mosberger
  0 siblings, 2 replies; 6+ messages in thread
From: george anzinger @ 2003-05-26 22:00 UTC (permalink / raw)
  To: Andrew Morton, Richard C Bilson; +Cc: linux-kernel, Eric Piel

Andrew Morton wrote:
> Spotted on lkml...
> 
> 
> 
> Begin forwarded message:
> 
> Date: Mon, 26 May 2003 17:09:34 -0400
> From: Richard C Bilson <rcbilson@plg2.math.uwaterloo.ca>
> To: linux-kernel@vger.kernel.org
> Subject: setitimer 1 usec fails
> 
> 
> In trying the latest development kernel, I've noticed that calling
> setitimer with a 1 usec delay (the shortest possible delay) results in
> the timer never going off.  2 usec is ok but 1 is not, so I suspect
> that somehow things are being rounded off incorrectly.  The attached
> program demonstrates the problem on 2.5.69, but runs correctly on a
> 2.4.20 kernel.
> 
> I have only had the opportunity to try this on a single architecture
> (ia64), so if anyone can convince me that it's a platform-specific
> problem I'll be happy to take my gripe to the ia64 list.  I've tried to
> figure out how the usecs are converted to jiffies, but the code is
> sufficiently convoluted that I thought I'd throw it out in the hope of
> finding someone who understands the situation a little better.

I am not sure, but this could be related to the HZ=1024 problem Eric 
Piel and I are trying to run down.  This is a rather bad choice for HZ 
due to round off error on the conversions to usec.  We THINK the 
right thing to do is to convert to nsec (this is for TICK_NSEC()), 
directly rather than first to usec and then to nsec.

The additional problem is that the ntp code attempts to correct for 
the roundoff error which makes for an always correcting wall clock 
(even without turning on ntp).  What is needed and what I am trying to 
find time to do, is to convert the ntp code to work from the nsec 
resolution of xtime rather from the old usec resolution.  Problem is I 
don't know the ntp code so it is a bit of a learning curve.

Help here is welcome!!

As a test, you might try your test with HZ=1000 (a number I recommend 
for ia64, if at all possible).

-g
> 
> - Richard
> 
> // When run, this program should print "handled alarm" from within the
> // signal handler, and "out of sigsuspend" right after.  It works on
> // 2.4.20 or if MY_TIMER_USEC is >= 2, but not on 2.5.69 with
> // MY_TIMER_USEC = 1.
> 
> #define MY_TIMER_USEC 1
> 
> #include <stdio.h>
> #include <unistd.h>
> #include <signal.h>
> #include <sys/time.h>
> 
> void
> alarm_handler( int x )
> {
>   printf( "handled alarm\n" );
>   return;
> }
> 
> int
> main()
> {
>   struct itimerval it = { { 0, 0 }, { 0, MY_TIMER_USEC } };
>   sigset_t mask;
>   struct sigaction act;
> 
>   act.sa_handler = alarm_handler;
>   act.sa_flags = 0;
>   sigemptyset( &act.sa_mask );
>   if( sigaction(SIGALRM, &act, 0) ) {
>     perror( "sigaction" );
>     exit( 1 );
>   }
>   
>   if( setitimer(ITIMER_REAL, &it, 0) ) {
>     perror( "setitimer" );
>     exit( 1 );
>   }
>   
>   sigemptyset( &mask );
>   sigsuspend( &mask );
>   
>   printf( "out of sigsuspend\n" );
>   return 0;
> }
> 

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

end of thread, other threads:[~2003-05-27 19:50 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-26 21:09 setitimer 1 usec fails Richard C Bilson
     [not found] <20030526142555.67a79694.akpm@digeo.com>
2003-05-26 22:00 ` george anzinger
2003-05-27  9:05   ` Eric Piel
2003-05-27 18:27   ` David Mosberger
2003-05-27 20:01     ` george anzinger
2003-05-27 17:19 Richard C Bilson

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).