[PATCH] nomadik: prevent sched_clock() wraparound

Russell King - ARM Linux linux at arm.linux.org.uk
Tue Nov 16 17:31:16 EST 2010


On Tue, Nov 16, 2010 at 11:15:02PM +0100, Linus Walleij wrote:
> 2010/11/16 john stultz <johnstul at us.ibm.com>:
> > On Tue, 2010-11-16 at 10:11 +0100, Linus Walleij wrote:
> 
> > The cycle value being passed as v is likely to be large, and the
> > clocksource mult and shift are calculated to be as large as possible
> > without overflowing when given only a few seconds worth of cycles.
> >
> > So its very likely that after a few seconds of running (or even less,
> > with the 32_to_63 conversion), the cyc2ns function will overflow, as
> > v*mult will be greater then 64bits.
> 
> Darn you're right of course.
> 
> I'll attempt to use
> clocks_calc_mult_shift(&mult, &shift, rate, NSEC_PER_SEC, 3600*24*365);
> 
> For getting a somewhat more proper mult+shift for sched_clock().

What kind of mult are you expecting?  Let's look at the code again:

> +     /* The highest bit is not valid */
> +     v &= 0x7FFFFFFFFFFFFFFFLLU;
> +     return clocksource_cyc2ns(v, nmdk_clksrc.mult, nmdk_clksrc.shift);

v is 63-bit.  Any multiply greater than two will result in an overflow,
which means the best you can achieve with this is basically a divide by
a power of two.  So you've lost accuracy in the factor conversion.

You might be better off limiting the size of 'v' to a smaller number of
bits, and then use clocksource_cyc2ns() with a multiplier which guarantees
that it won't overflow 64-bit math, but putting up with it wrapping more
often than a 63-bit value would give you.

I think you have a trade-off to make here, between time between wraps
and conversion accuracy.



More information about the linux-arm-kernel mailing list