Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Thu, 21 Apr 2005, Chris Friesen wrote: > > Does mainline have a high precision monotonic wallclock that is not > affected by time-of-day changes? Something like "nano/mico seconds > since boot"? On newer kernels with the posix timers (I think 2.6 - not sure though) there's clock_gettime(CLOCK_MONOTONIC, ...). Linus Torvalds wrote: > > Getting "approximate uptime" really really _really_ fast > might be useful for some things, but I don't know how many. I bet most users of gettimeofday actually want a strictly monotonic increasing clock where the actual base time is irrelevant. Just strace some apps - those issuing hundreds and thousands of gettimeofday calls are most likely in this class. Those who only call gettimeofday once or twice or the ones that really want the wall clock time. How often does the kernel use jiffies (the monotonic clock) and how often xtime (the wall clock)? Ciao, ET. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Thu, 21 Apr 2005, Chris Friesen wrote: > > Does mainline have a high precision monotonic wallclock that is not > affected by time-of-day changes? Something like "nano/mico seconds > since boot"? High precision? No. We do have "jiffies since boot". We don't actually expose it anywhere, although you _can_ get it's "standardized version", aka "centi-seconds per boot" from things like /proc/uptime. (Not high-performance, but such an interface _could_ be. It's one of the few things we could trivially map into the "system call page", and have accessible to user space with just a simple read - faster even than the "fast gettimeofday" implementations). The thing is, most people who want the time of day want a real time with some precision. Getting "approximate uptime" really really _really_ fast might be useful for some things, but I don't know how many. Linus - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
Linus Torvalds wrote: If you calculate the expected timeout from the time-of-day in the caller, your drift not only goes away, but you'll actually be able to handle things like "oops, the machine is under load so I missed an event". Does mainline have a high precision monotonic wallclock that is not affected by time-of-day changes? Something like "nano/mico seconds since boot"? Chris - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Thu, 2005-04-21 at 07:58 -0700, Linus Torvalds wrote: > > On Thu, 21 Apr 2005, Steven Rostedt wrote: > > > > Thanks, I forgot about the guarantee of "at least" the time requested. > > I took this on because I noticed this in a driver I wrote. With the user > > passing in a timeval for a periodic condition. I noticed that this would > > drift quite a bit. > > Your user is doing things wrong. If he wants a non-drifting clock, he > should look at _realtime_ and then always re-calculate the "how long do I > want to sleep" from that. Because even if the kernel was able to do all > offsets with nanosecond precision and wake you up _exactly_, you'd still > be drifting because of the time spent in between calls (and scheduling > events etc). > It's even stranger than this. I'm working on a custom kernel for a customer based off of Ingo's RT patches. They want to be able to make a process run for a percentage of the CPU. So you can make a process run 10 jiffies out of every 100. Using Ingo's RT patch helps to keep the latencies down from interrupts. > > I guess I need to write my own timeval_to_jiffies > > conversion so that i remove the added jiffy. For this case, I actually > > want a true rounded value to the closest jiffy. > > No, if you're looking at reliable wall-clock time, you really need to use > wall-clock, not successive time offsets. The time offsets will always > drift: you can make the drift small enough that your particular > application doesn't happen to care (or, quite often - make it drift in a > _direction_ you don't happen to care about), but it's still wrong. > The customer understands that the precision would be in jiffies, and hopefully better, when/if I can get the high res timers patch working with this as well. The problem arises with the API using timeval to determine the percentage and period. With the added jiffy, the calculations are wrong. > If you calculate the expected timeout from the time-of-day in the caller, > your drift not only goes away, but you'll actually be able to handle > things like "oops, the machine is under load so I missed an event". > Hopefully there is never a missed event (this is checked for though), since the process would be running at the highest priority. It's OK for the process to come in late, as long as it runs the required amount within the given period. > Yes, it gets slightly more complicated (and a _lot_ more complicated if > your app needs to do something special for the missed case, like dropping > data and re-syncing, which is common in things like video or sound > streaming), but the fact is, it's just the right thing to do. This project is much more complicated than what I've mentioned here, but it shows what I need. Currently we are using jiffies as the timer, but eventually we will be using a better source and the whole timeval_to_jiffies conversion wouldn't matter. -- Steve - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Thu, 21 Apr 2005, Steven Rostedt wrote: > > Thanks, I forgot about the guarantee of "at least" the time requested. > I took this on because I noticed this in a driver I wrote. With the user > passing in a timeval for a periodic condition. I noticed that this would > drift quite a bit. Your user is doing things wrong. If he wants a non-drifting clock, he should look at _realtime_ and then always re-calculate the "how long do I want to sleep" from that. Because even if the kernel was able to do all offsets with nanosecond precision and wake you up _exactly_, you'd still be drifting because of the time spent in between calls (and scheduling events etc). >I guess I need to write my own timeval_to_jiffies > conversion so that i remove the added jiffy. For this case, I actually > want a true rounded value to the closest jiffy. No, if you're looking at reliable wall-clock time, you really need to use wall-clock, not successive time offsets. The time offsets will always drift: you can make the drift small enough that your particular application doesn't happen to care (or, quite often - make it drift in a _direction_ you don't happen to care about), but it's still wrong. If you calculate the expected timeout from the time-of-day in the caller, your drift not only goes away, but you'll actually be able to handle things like "oops, the machine is under load so I missed an event". Yes, it gets slightly more complicated (and a _lot_ more complicated if your app needs to do something special for the missed case, like dropping data and re-syncing, which is common in things like video or sound streaming), but the fact is, it's just the right thing to do. Linus - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Thu, 2005-04-21 at 09:51 +0100, Russell King wrote: [...] > The problem is that when you add a timer, you don't have any idea > which point you're going to be starting your timer at. > > This is why we always round up to the next jiffy when we convert > times to jiffies - this ensures that you will get at _least_ the > timeout you requested, which is in itself a very important > guarantee. > Thanks, I forgot about the guarantee of "at least" the time requested. I took this on because I noticed this in a driver I wrote. With the user passing in a timeval for a periodic condition. I noticed that this would drift quite a bit. I guess I need to write my own timeval_to_jiffies conversion so that i remove the added jiffy. For this case, I actually want a true rounded value to the closest jiffy. Thanks again, -- Steve - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Wed, Apr 20, 2005 at 11:40:16PM -0400, Steven Rostedt wrote: > Is 11 jiffies correct for 10ms? Consider the 1 jiffy case. How long does waiting one jiffy actually wait? j=01 2 +--+--+--> t A B C D If you start timing one jiffy from A, you're looking for j=1, so your timer expires close to D and you have waited one jiffy. If you start timing one jiffy from B, you're still looking for j=1. Your timer expires at the same point (D) but you've waited less than one jiffy. If you start timing one jiffy from C, it's the same - expires at D. This time, you've waited virtually no time at all. The problem is that when you add a timer, you don't have any idea which point you're going to be starting your timer at. This is why we always round up to the next jiffy when we convert times to jiffies - this ensures that you will get at _least_ the timeout you requested, which is in itself a very important guarantee. -- Russell King Linux kernel2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 Serial core - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Wed, Apr 20, 2005 at 11:40:16PM -0400, Steven Rostedt wrote: Is 11 jiffies correct for 10ms? Consider the 1 jiffy case. How long does waiting one jiffy actually wait? j=01 2 +--+--+-- t A B C D If you start timing one jiffy from A, you're looking for j=1, so your timer expires close to D and you have waited one jiffy. If you start timing one jiffy from B, you're still looking for j=1. Your timer expires at the same point (D) but you've waited less than one jiffy. If you start timing one jiffy from C, it's the same - expires at D. This time, you've waited virtually no time at all. The problem is that when you add a timer, you don't have any idea which point you're going to be starting your timer at. This is why we always round up to the next jiffy when we convert times to jiffies - this ensures that you will get at _least_ the timeout you requested, which is in itself a very important guarantee. -- Russell King Linux kernel2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 Serial core - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Thu, 2005-04-21 at 09:51 +0100, Russell King wrote: [...] The problem is that when you add a timer, you don't have any idea which point you're going to be starting your timer at. This is why we always round up to the next jiffy when we convert times to jiffies - this ensures that you will get at _least_ the timeout you requested, which is in itself a very important guarantee. Thanks, I forgot about the guarantee of at least the time requested. I took this on because I noticed this in a driver I wrote. With the user passing in a timeval for a periodic condition. I noticed that this would drift quite a bit. I guess I need to write my own timeval_to_jiffies conversion so that i remove the added jiffy. For this case, I actually want a true rounded value to the closest jiffy. Thanks again, -- Steve - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Thu, 21 Apr 2005, Steven Rostedt wrote: Thanks, I forgot about the guarantee of at least the time requested. I took this on because I noticed this in a driver I wrote. With the user passing in a timeval for a periodic condition. I noticed that this would drift quite a bit. Your user is doing things wrong. If he wants a non-drifting clock, he should look at _realtime_ and then always re-calculate the how long do I want to sleep from that. Because even if the kernel was able to do all offsets with nanosecond precision and wake you up _exactly_, you'd still be drifting because of the time spent in between calls (and scheduling events etc). I guess I need to write my own timeval_to_jiffies conversion so that i remove the added jiffy. For this case, I actually want a true rounded value to the closest jiffy. No, if you're looking at reliable wall-clock time, you really need to use wall-clock, not successive time offsets. The time offsets will always drift: you can make the drift small enough that your particular application doesn't happen to care (or, quite often - make it drift in a _direction_ you don't happen to care about), but it's still wrong. If you calculate the expected timeout from the time-of-day in the caller, your drift not only goes away, but you'll actually be able to handle things like oops, the machine is under load so I missed an event. Yes, it gets slightly more complicated (and a _lot_ more complicated if your app needs to do something special for the missed case, like dropping data and re-syncing, which is common in things like video or sound streaming), but the fact is, it's just the right thing to do. Linus - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Thu, 2005-04-21 at 07:58 -0700, Linus Torvalds wrote: On Thu, 21 Apr 2005, Steven Rostedt wrote: Thanks, I forgot about the guarantee of at least the time requested. I took this on because I noticed this in a driver I wrote. With the user passing in a timeval for a periodic condition. I noticed that this would drift quite a bit. Your user is doing things wrong. If he wants a non-drifting clock, he should look at _realtime_ and then always re-calculate the how long do I want to sleep from that. Because even if the kernel was able to do all offsets with nanosecond precision and wake you up _exactly_, you'd still be drifting because of the time spent in between calls (and scheduling events etc). It's even stranger than this. I'm working on a custom kernel for a customer based off of Ingo's RT patches. They want to be able to make a process run for a percentage of the CPU. So you can make a process run 10 jiffies out of every 100. Using Ingo's RT patch helps to keep the latencies down from interrupts. I guess I need to write my own timeval_to_jiffies conversion so that i remove the added jiffy. For this case, I actually want a true rounded value to the closest jiffy. No, if you're looking at reliable wall-clock time, you really need to use wall-clock, not successive time offsets. The time offsets will always drift: you can make the drift small enough that your particular application doesn't happen to care (or, quite often - make it drift in a _direction_ you don't happen to care about), but it's still wrong. The customer understands that the precision would be in jiffies, and hopefully better, when/if I can get the high res timers patch working with this as well. The problem arises with the API using timeval to determine the percentage and period. With the added jiffy, the calculations are wrong. If you calculate the expected timeout from the time-of-day in the caller, your drift not only goes away, but you'll actually be able to handle things like oops, the machine is under load so I missed an event. Hopefully there is never a missed event (this is checked for though), since the process would be running at the highest priority. It's OK for the process to come in late, as long as it runs the required amount within the given period. Yes, it gets slightly more complicated (and a _lot_ more complicated if your app needs to do something special for the missed case, like dropping data and re-syncing, which is common in things like video or sound streaming), but the fact is, it's just the right thing to do. This project is much more complicated than what I've mentioned here, but it shows what I need. Currently we are using jiffies as the timer, but eventually we will be using a better source and the whole timeval_to_jiffies conversion wouldn't matter. -- Steve - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
Linus Torvalds wrote: If you calculate the expected timeout from the time-of-day in the caller, your drift not only goes away, but you'll actually be able to handle things like oops, the machine is under load so I missed an event. Does mainline have a high precision monotonic wallclock that is not affected by time-of-day changes? Something like nano/mico seconds since boot? Chris - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Thu, 21 Apr 2005, Chris Friesen wrote: Does mainline have a high precision monotonic wallclock that is not affected by time-of-day changes? Something like nano/mico seconds since boot? High precision? No. We do have jiffies since boot. We don't actually expose it anywhere, although you _can_ get it's standardized version, aka centi-seconds per boot from things like /proc/uptime. (Not high-performance, but such an interface _could_ be. It's one of the few things we could trivially map into the system call page, and have accessible to user space with just a simple read - faster even than the fast gettimeofday implementations). The thing is, most people who want the time of day want a real time with some precision. Getting approximate uptime really really _really_ fast might be useful for some things, but I don't know how many. Linus - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Thu, 21 Apr 2005, Chris Friesen wrote: Does mainline have a high precision monotonic wallclock that is not affected by time-of-day changes? Something like nano/mico seconds since boot? On newer kernels with the posix timers (I think 2.6 - not sure though) there's clock_gettime(CLOCK_MONOTONIC, ...). Linus Torvalds wrote: Getting approximate uptime really really _really_ fast might be useful for some things, but I don't know how many. I bet most users of gettimeofday actually want a strictly monotonic increasing clock where the actual base time is irrelevant. Just strace some apps - those issuing hundreds and thousands of gettimeofday calls are most likely in this class. Those who only call gettimeofday once or twice or the ones that really want the wall clock time. How often does the kernel use jiffies (the monotonic clock) and how often xtime (the wall clock)? Ciao, ET. - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Wed, 2005-04-20 at 22:58 -0400, Steven Rostedt wrote: > I looked into the problem that jdavis had and found that the conversion > of the timeval_to_jiffies was off by one. > > To convert tv.tv_sec = 0, tv.tv_usec = 1 to jiffies, you come up > with an answer of 11 (assuming 1000 HZ). > OK, this bothered me that this patch seems to work, since the comments around the USEC_ROUND seem to make sense. So I looked more closely into this. Is 11 jiffies correct for 10ms? Since the the USEC_CONVERSION contains a TICK_NSEC which is suppose to (I believe) convert the number of CPU ticks to nanoseconds. Since ticks don't map nicely to nanoseconds there can be a discrepancy for the actual time. But this doesn't explain why the patch changes everything into the desired result, assuming that 10 ms == 10 jiffies. Maybe there's too much rounding going on. I'll have to take a deeper look into this, but feel free to look yourselves! I'm going to bed. I've attached my userland program if you want to play around with the numbers. > Here's the patch: > > --- ./include/linux/jiffies.h.orig2005-04-20 22:30:34.0 -0400 > +++ ./include/linux/jiffies.h 2005-04-20 22:39:42.0 -0400 > @@ -231,7 +231,7 @@ > * in jiffies (albit scaled), it is nothing but the bits we will shift > * off. > */ > -#define USEC_ROUND (u64)(((u64)1 << USEC_JIFFIE_SC) - 1) > +#define USEC_ROUND (u64)(((u64)1 << (USEC_JIFFIE_SC - 1))) > /* > * The maximum jiffie value is (MAX_INT >> 1). Here we translate that > * into seconds. The 64-bit case will overflow if we are not careful, -- Steve #include #include #include typedef unsigned long long u64; #define HZ 1000 #ifndef div_long_long_rem #define div_long_long_rem(dividend,divisor,remainder) \ ({ \ u64 result = dividend;\ *remainder = do_div(result,divisor); \ result; \ }) #endif # define CLOCK_TICK_RATE 1193182 /* Underlying HZ */ #define NSEC_PER_SEC (10L) #define NSEC_PER_USEC (1000L) /* * The following defines establish the engineering parameters of the PLL * model. The HZ variable establishes the timer interrupt frequency, 100 Hz * for the SunOS kernel, 256 Hz for the Ultrix kernel and 1024 Hz for the * OSF/1 kernel. The SHIFT_HZ define expresses the same value as the * nearest power of two in order to avoid hardware multiply operations. */ #if HZ >= 12 && HZ < 24 # define SHIFT_HZ 4 #elif HZ >= 24 && HZ < 48 # define SHIFT_HZ 5 #elif HZ >= 48 && HZ < 96 # define SHIFT_HZ 6 #elif HZ >= 96 && HZ < 192 # define SHIFT_HZ 7 #elif HZ >= 192 && HZ < 384 # define SHIFT_HZ 8 #elif HZ >= 384 && HZ < 768 # define SHIFT_HZ 9 #elif HZ >= 768 && HZ < 1536 # define SHIFT_HZ 10 #else # error You lose. #endif /* 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 conditions: * - (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_NSEC is the time between ticks in nsec assuming real ACTHZ */ #define TICK_NSEC (SH_DIV (100UL * 1000, ACTHZ, 8)) /* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */ #define TICK_USEC ((100UL + USER_HZ/2) / USER_HZ) /* TICK_USEC_TO_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_USEC_TO_NSEC(TUSEC) (SH_DIV (TUSEC * USER_HZ * 1000, ACTHZ, 8)) /* some arch's have a small-data section that can be accessed register-relative * but that can only take up to, say, 4-byte variables. jiffies being part of * an 8-byte variable may not be correctly accessed unless we force the issue */ #define __jiffy_data __attribute__((section(".data"))) /* * The 64-bit value is not volatile - you MUST NOT read it * without sampling the sequence number in xtime_lock. * get_jiffies_64() will do this for you as appropriate. */ extern u64 __jiffy_data jiffies_64; extern unsigned long volatile __jiffy_data jiffies; #if (BITS_PER_LONG < 64) u64 get_jiffies_64(void); #else static inline u64 get_jiffies_64(void) { return (u64)jiffies; } #endif /* * These inlines deal with timer wrapping correctly. You are * strongly encouraged to use them * 1. Because people otherwise forget * 2. Because if the timer wrap changes in future you won't have to * alter your driver code. * *
[PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
I looked into the problem that jdavis had and found that the conversion of the timeval_to_jiffies was off by one. To convert tv.tv_sec = 0, tv.tv_usec = 1 to jiffies, you come up with an answer of 11 (assuming 1000 HZ). Here's the patch: --- ./include/linux/jiffies.h.orig 2005-04-20 22:30:34.0 -0400 +++ ./include/linux/jiffies.h 2005-04-20 22:39:42.0 -0400 @@ -231,7 +231,7 @@ * in jiffies (albit scaled), it is nothing but the bits we will shift * off. */ -#define USEC_ROUND (u64)(((u64)1 << USEC_JIFFIE_SC) - 1) +#define USEC_ROUND (u64)(((u64)1 << (USEC_JIFFIE_SC - 1))) /* * The maximum jiffie value is (MAX_INT >> 1). Here we translate that * into seconds. The 64-bit case will overflow if we are not careful, I wrote a user program that copies all of the jiffies.h and shows the output of the conversion. Without this patch you get: usec=1 jiffies = 11 usec=10010 jiffies = 11 usec=10020 jiffies = 11 . . . usec=10980 jiffies = 11 usec=10990 jiffies = 11 usec=11000 jiffies = 12 With the patch, you get: usec=1 jiffies = 10 usec=10010 jiffies = 10 usec=10020 jiffies = 10 . . . usec=10480 jiffies = 10 usec=10490 jiffies = 10 usec=10500 jiffies = 11 usec=10510 jiffies = 11 . . . usec=10990 jiffies = 11 usec=11000 jiffies = 11 Which I believe is the more desired result. I've kept jdavis original email to show where this was discovered. -- Steve On Fri, 2005-04-08 at 10:39 -0700, [EMAIL PROTECTED] wrote: > > Hello, > > I've created a pretty straight forward timer using setitimer, and noticed > some odd differences between 2.4 and 2.6, I wonder if I could get a > clarification if this is the way it should work, or if I should continue to > try to "fix" it. > > I create a RealTime Thread( SCHED_FIFO, maxPriority-1 ) (also tried > SCHED_RR) ... > > that creates a timer ...setitimer( ITIMER_REAL, SIGALRM) with a 10 milli > period. (I've also tried timer_create with CLOCK_REALTIME and SIGRTMIN) > > and then the thread does a sem_wait() on a semaphore. > > the signal handler does a sem_post() . > > > on 2.4.X the (idle) worst case latency is ~40 microseconds, > on 2.6.X the (idle) latency is about the same plus 1 tick of the scheduler > ~1000 micro seconds... Always.. Every time. > So to work around this on 2.6 I simply subtract 1 millisecond from my timer > as a fudge factor and everything works as expected. > > I've tried compiling various kernels (2.6.9, 2.6.11) with kernel pre-empting > on, etc.. > > Is this the correct behavior? If so I'm curious who is using up the extra > Tick? > Does the asynch signal handler use up the whole tick even though it only has > to sem_post()? > > I am not subscribed to the list, so I would appreciate a CC. > Thanks, > -JD > - - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
I looked into the problem that jdavis had and found that the conversion of the timeval_to_jiffies was off by one. To convert tv.tv_sec = 0, tv.tv_usec = 1 to jiffies, you come up with an answer of 11 (assuming 1000 HZ). Here's the patch: --- ./include/linux/jiffies.h.orig 2005-04-20 22:30:34.0 -0400 +++ ./include/linux/jiffies.h 2005-04-20 22:39:42.0 -0400 @@ -231,7 +231,7 @@ * in jiffies (albit scaled), it is nothing but the bits we will shift * off. */ -#define USEC_ROUND (u64)(((u64)1 USEC_JIFFIE_SC) - 1) +#define USEC_ROUND (u64)(((u64)1 (USEC_JIFFIE_SC - 1))) /* * The maximum jiffie value is (MAX_INT 1). Here we translate that * into seconds. The 64-bit case will overflow if we are not careful, I wrote a user program that copies all of the jiffies.h and shows the output of the conversion. Without this patch you get: usec=1 jiffies = 11 usec=10010 jiffies = 11 usec=10020 jiffies = 11 . . . usec=10980 jiffies = 11 usec=10990 jiffies = 11 usec=11000 jiffies = 12 With the patch, you get: usec=1 jiffies = 10 usec=10010 jiffies = 10 usec=10020 jiffies = 10 . . . usec=10480 jiffies = 10 usec=10490 jiffies = 10 usec=10500 jiffies = 11 usec=10510 jiffies = 11 . . . usec=10990 jiffies = 11 usec=11000 jiffies = 11 Which I believe is the more desired result. I've kept jdavis original email to show where this was discovered. -- Steve On Fri, 2005-04-08 at 10:39 -0700, [EMAIL PROTECTED] wrote: Hello, I've created a pretty straight forward timer using setitimer, and noticed some odd differences between 2.4 and 2.6, I wonder if I could get a clarification if this is the way it should work, or if I should continue to try to fix it. I create a RealTime Thread( SCHED_FIFO, maxPriority-1 ) (also tried SCHED_RR) ... that creates a timer ...setitimer( ITIMER_REAL, SIGALRM) with a 10 milli period. (I've also tried timer_create with CLOCK_REALTIME and SIGRTMIN) and then the thread does a sem_wait() on a semaphore. the signal handler does a sem_post() . on 2.4.X the (idle) worst case latency is ~40 microseconds, on 2.6.X the (idle) latency is about the same plus 1 tick of the scheduler ~1000 micro seconds... Always.. Every time. So to work around this on 2.6 I simply subtract 1 millisecond from my timer as a fudge factor and everything works as expected. I've tried compiling various kernels (2.6.9, 2.6.11) with kernel pre-empting on, etc.. Is this the correct behavior? If so I'm curious who is using up the extra Tick? Does the asynch signal handler use up the whole tick even though it only has to sem_post()? I am not subscribed to the list, so I would appreciate a CC. Thanks, -JD - - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Bad rounding in timeval_to_jiffies [was: Re: Odd Timer behavior in 2.6 vs 2.4 (1 extra tick)]
On Wed, 2005-04-20 at 22:58 -0400, Steven Rostedt wrote: I looked into the problem that jdavis had and found that the conversion of the timeval_to_jiffies was off by one. To convert tv.tv_sec = 0, tv.tv_usec = 1 to jiffies, you come up with an answer of 11 (assuming 1000 HZ). OK, this bothered me that this patch seems to work, since the comments around the USEC_ROUND seem to make sense. So I looked more closely into this. Is 11 jiffies correct for 10ms? Since the the USEC_CONVERSION contains a TICK_NSEC which is suppose to (I believe) convert the number of CPU ticks to nanoseconds. Since ticks don't map nicely to nanoseconds there can be a discrepancy for the actual time. But this doesn't explain why the patch changes everything into the desired result, assuming that 10 ms == 10 jiffies. Maybe there's too much rounding going on. I'll have to take a deeper look into this, but feel free to look yourselves! I'm going to bed. I've attached my userland program if you want to play around with the numbers. Here's the patch: --- ./include/linux/jiffies.h.orig2005-04-20 22:30:34.0 -0400 +++ ./include/linux/jiffies.h 2005-04-20 22:39:42.0 -0400 @@ -231,7 +231,7 @@ * in jiffies (albit scaled), it is nothing but the bits we will shift * off. */ -#define USEC_ROUND (u64)(((u64)1 USEC_JIFFIE_SC) - 1) +#define USEC_ROUND (u64)(((u64)1 (USEC_JIFFIE_SC - 1))) /* * The maximum jiffie value is (MAX_INT 1). Here we translate that * into seconds. The 64-bit case will overflow if we are not careful, -- Steve #include stdio.h #include stdlib.h #include string.h typedef unsigned long long u64; #define HZ 1000 #ifndef div_long_long_rem #define div_long_long_rem(dividend,divisor,remainder) \ ({ \ u64 result = dividend;\ *remainder = do_div(result,divisor); \ result; \ }) #endif # define CLOCK_TICK_RATE 1193182 /* Underlying HZ */ #define NSEC_PER_SEC (10L) #define NSEC_PER_USEC (1000L) /* * The following defines establish the engineering parameters of the PLL * model. The HZ variable establishes the timer interrupt frequency, 100 Hz * for the SunOS kernel, 256 Hz for the Ultrix kernel and 1024 Hz for the * OSF/1 kernel. The SHIFT_HZ define expresses the same value as the * nearest power of two in order to avoid hardware multiply operations. */ #if HZ = 12 HZ 24 # define SHIFT_HZ 4 #elif HZ = 24 HZ 48 # define SHIFT_HZ 5 #elif HZ = 48 HZ 96 # define SHIFT_HZ 6 #elif HZ = 96 HZ 192 # define SHIFT_HZ 7 #elif HZ = 192 HZ 384 # define SHIFT_HZ 8 #elif HZ = 384 HZ 768 # define SHIFT_HZ 9 #elif HZ = 768 HZ 1536 # define SHIFT_HZ 10 #else # error You lose. #endif /* 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 conditions: * - (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_NSEC is the time between ticks in nsec assuming real ACTHZ */ #define TICK_NSEC (SH_DIV (100UL * 1000, ACTHZ, 8)) /* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */ #define TICK_USEC ((100UL + USER_HZ/2) / USER_HZ) /* TICK_USEC_TO_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_USEC_TO_NSEC(TUSEC) (SH_DIV (TUSEC * USER_HZ * 1000, ACTHZ, 8)) /* some arch's have a small-data section that can be accessed register-relative * but that can only take up to, say, 4-byte variables. jiffies being part of * an 8-byte variable may not be correctly accessed unless we force the issue */ #define __jiffy_data __attribute__((section(.data))) /* * The 64-bit value is not volatile - you MUST NOT read it * without sampling the sequence number in xtime_lock. * get_jiffies_64() will do this for you as appropriate. */ extern u64 __jiffy_data jiffies_64; extern unsigned long volatile __jiffy_data jiffies; #if (BITS_PER_LONG 64) u64 get_jiffies_64(void); #else static inline u64 get_jiffies_64(void) { return (u64)jiffies; } #endif /* * These inlines deal with timer wrapping correctly. You are * strongly encouraged to use them * 1. Because people otherwise forget * 2. Because if the timer wrap changes in future you won't have to * alter your driver code. * * time_after(a,b) returns true if the time a is