Bug 3289

Summary: timer created by setitimer(ITIMER_REAL, ...) accumulates ~850 microseconds per second
Product: Timers Reporter: Maxym Makhota (makhota)
Component: Interval TimersAssignee: Thomas Gleixner (tglx)
Status: CLOSED PATCH_ALREADY_AVAILABLE    
Severity: blocking CC: akpm, john.stultz
Priority: P2    
Hardware: i386   
OS: Linux   
Kernel Version: 2.6.7 Subsystem:
Regression: --- Bisected commit-id:
Attachments: Sample code of SIGALARM time difference

Description Maxym Makhota 2004-08-27 10:11:26 UTC
Distribution: (built myself)
Hardware Environments: 
     - Intel Pentium 4 @ 2.8Ghz
     - Intel Pentium 3 @ 850 MHz
     - Cyrix MadiaGX @ 300 MHz
 
Software Environments: 
     - gcc 2.95.3; 
     - kernel 2.6.7
     - kernel 2.6.5

Problem Description: When creating a timer by setitimer(ITIMER_REAL, ...) for 
1 sec, SIGALARM is sent every 1.00085 seconds. Switching back to 2.4.27 
(2.4.10, 2.4.24, 2.4.26) kernel fixes the problem. 

Steps to reproduce: use setitimer(ITIMER_REAL, { 1, 0, 1, 0 }, NULL) call and 
then watch the time difference between SIGALARM (see attached sample code)
Comment 1 Maxym Makhota 2004-08-27 10:14:37 UTC
Created attachment 3580 [details]
Sample code of SIGALARM time difference
Comment 2 Maxym Makhota 2004-08-27 15:44:11 UTC
The same problem happens to be with 2.6.8.1 kernel. HPET timer option 
enabling/disabling doesn't make any difference.
Comment 3 George Anzinger 2004-08-27 16:07:23 UTC
More exactly, it will alarm every 1.000848849 seconds.  This is because the
resolution of the system timer is 999849 nanoseconds when HZ = 1000.  I am
sorry, but this is just the way it is given the PIT and its clock source, an
xtal of 14.3181818MHZ divided by 12.  The resolution is much closer to the
expected power of 10 if you use HZ = 100.

Since the itimer stuff uses timeval structures (i.e. microseconds) you will not
see this in the getitimer() return, however, if you use the POSIX timers and do
a timer_gettime() you will see the above nanosecond value reflected in the
repeat times.  You will see it more directly in the clock_getres() call.

George
Comment 4 Henry Margies 2004-09-13 07:19:32 UTC
Hi,

maybe this problem belongs to a wrong conversion of timeval to jiffies. I
discovered this problem on my arm device, where the TICK value is 10ms (in
contrast to 1ms on x86 platform).

If I start an itimer with an interval of 10ms, it is converted to 2ticks (or
jiffies) (and 11 ticks on x86). In my opinion this is one to much.

I think, something is wrong with USEC_ROUND.

I wrote an email to the kernel mailing list, please have a look for further
explanations:
http://marc.theaimsgroup.com/?l=linux-kernel&m=109473824507290&w=2

Comment 5 john stultz 2005-03-15 11:32:12 UTC
This bug is a bit stale, is it still an issue or is it considered resolved?
Comment 6 George Anzinger 2005-03-15 12:59:47 UTC
I would reject it as invalid, if I had the power :)
Comment 7 john stultz 2005-03-15 13:18:32 UTC
Rejecting as invalid, as suggested by George.

If someone disagrees, it can be re-opened.
Comment 8 Maxym Makhota 2005-03-15 15:40:09 UTC
Hi Guys,

I disagree. Based on George explanation, the way kernel works is the only 
possible way to work. However, 2.4.x kernel works different. It keeps sending 
SIGALARM every 1.0 seconds. Yes, it has some jitters (~0.01%), but next 
samples compensate instability. And - the most important - average stays at 
exactly 1.0. In contrast, 2.6.x kernel is _accumulating_ deviations, which 
affects the average. In my case this is unacceptable and this is what prevents 
me from using 2.6.x. Again, I'm very happy with 2.4.x. 

So, I reformulate my question to the following: why are they different? I want 
old behavior back! :))

George said this is because of switching to 1000 Hz. Re-defining HZ as "100" 
should fix the problem. However, after recompiling the kernel with HZ 100, 
nothing changed at all! Well, except that I cannot receive SIALARM faster then 
100 HZ anymore (actually, 99HZ). BTW, with HZ 1000, if I need to get SIALARM 
every 0.0005 sec, I need to set up the timer a little faster. 

Comment 9 Petr Cvachoucek 2005-04-15 05:56:48 UTC
Hi,
I agree with Maxym, I just encountered the same problem when switched
to 2.6.8 kernel (from 2.4.21). Interval timer (when started in periodic mode)
is accumulating error. Thats a bad behavior and I think that arguments
given by George Anzinger are wrong.
Well, for simplicity assume we have interval timer of 100 msec interval.
It should be signalled on these times (measured from calling setitimer()):
<100 msec     ... 100 msec + 1 jiffy>
<200 msec     ... 200 msec + 1 jiffy>
...
<n * interval ... n * interval + 1 jiffy>

Current 2.6 behavior is
<100 msec             ... 100 msec + 1 jiffy>
<200 msec + 1 jiffy   ... 200 msec + 2 jiffies>
<300 msec + 2 jiffies ... 300 msec + 3 jiffies>
... and so on

I think its a serious bug, it brokes all applications which use periodic
interval timer for their own time base.
Comment 10 Thomas Gleixner 2006-01-30 03:24:51 UTC
Can you please try 2.6.16-rc1-mm4 ?

Comment 11 Thomas Gleixner 2006-02-01 02:10:22 UTC
Run the test case on 2.6.16-rc1-mm4. HZ=250. PIII 400MHz

The maximum deviation of the expected timeline was 4ms. No summing up error.
Average is 1sec.

The patches are scheduled for 2.6.16