Commit d8e0b647 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] fix nanosleep() granularity bumps

From: Tim Schmielau <tim@physik3.uni-rostock.de>

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.
parent e28b748d
......@@ -1199,11 +1199,23 @@ static void __devinit init_timers_cpu(int cpu)
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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment