From: Tim Schmielau Fixes the problem wherein nanosleep() is sleeping for the wrong duration. When starting out with timer_jiffies=0, the timer cascade is (unneccessarily) triggered on the first timer interrupt, incrementing all the higher indices. When starting with any other initial jiffies value, we miss that and end up with all higher indices being off by one. (forwarded by akpm@digeo.com) kernel/timer.c | 22 +++++++++++++++++----- 1 files changed, 17 insertions(+), 5 deletions(-) diff -puN kernel/timer.c~nanosleep-accuracy-fix-2 kernel/timer.c --- 25/kernel/timer.c~nanosleep-accuracy-fix-2 2003-03-20 03:11:41.000000000 -0800 +++ 25-akpm/kernel/timer.c 2003-03-20 03:11:41.000000000 -0800 @@ -1199,11 +1199,23 @@ static void __devinit init_timers_cpu(in INIT_LIST_HEAD(base->tv1.vec + j); base->timer_jiffies = INITIAL_JIFFIES; - base->tv1.index = INITIAL_JIFFIES & TVR_MASK; - base->tv2.index = (INITIAL_JIFFIES >> TVR_BITS) & TVN_MASK; - base->tv3.index = (INITIAL_JIFFIES >> (TVR_BITS+TVN_BITS)) & TVN_MASK; - base->tv4.index = (INITIAL_JIFFIES >> (TVR_BITS+2*TVN_BITS)) & TVN_MASK; - base->tv5.index = (INITIAL_JIFFIES >> (TVR_BITS+3*TVN_BITS)) & TVN_MASK; + /* + * The tv indices are always larger by one compared to the + * respective parts of timer_jiffies. If all lower indices are + * zero at initialisation, this is achieved by an (otherwise + * unneccessary) invocation of the timer cascade on the first + * timer interrupt. If not, we need to take it into account + * here: + */ + j = (base->tv1.index = INITIAL_JIFFIES & TVR_MASK) !=0; + j |= (base->tv2.index = ((INITIAL_JIFFIES >> TVR_BITS) + j) + & TVN_MASK) !=0; + j |= (base->tv3.index = ((INITIAL_JIFFIES >> (TVR_BITS+TVN_BITS)) + j) + & TVN_MASK) !=0; + j |= (base->tv4.index = ((INITIAL_JIFFIES >> (TVR_BITS+2*TVN_BITS)) + j) + & TVN_MASK) !=0; + base->tv5.index = ((INITIAL_JIFFIES >> (TVR_BITS+3*TVN_BITS)) + j) + & TVN_MASK; } static int __devinit timer_cpu_notify(struct notifier_block *self, _