On Thu, Dec 08, 2016 at 08:49:38PM -0000, Thomas Gleixner wrote: > The resume code must deal with a clocksource delta which is potentially big > enough to overflow the 64bit mult. > > Replace the open coded handling with the proper function. > > Signed-off-by: Thomas Gleixner Reviewed-by: David Gibson > --- > kernel/time/timekeeping.c | 26 +++++--------------------- > 1 file changed, 5 insertions(+), 21 deletions(-) > > --- a/kernel/time/timekeeping.c > +++ b/kernel/time/timekeeping.c > @@ -1615,7 +1615,7 @@ void timekeeping_resume(void) > struct clocksource *clock = tk->tkr_mono.clock; > unsigned long flags; > struct timespec64 ts_new, ts_delta; > - cycle_t cycle_now, cycle_delta; > + cycle_t cycle_now; > > sleeptime_injected = false; > read_persistent_clock64(&ts_new); > @@ -1641,27 +1641,11 @@ void timekeeping_resume(void) > cycle_now = tk->tkr_mono.read(clock); > if ((clock->flags & CLOCK_SOURCE_SUSPEND_NONSTOP) && > cycle_now > tk->tkr_mono.cycle_last) { > - u64 num, max = ULLONG_MAX; > - u32 mult = clock->mult; > - u32 shift = clock->shift; > - s64 nsec = 0; > - > - cycle_delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, > - tk->tkr_mono.mask); > - > - /* > - * "cycle_delta * mutl" may cause 64 bits overflow, if the > - * suspended time is too long. In that case we need do the > - * 64 bits math carefully > - */ > - do_div(max, mult); > - if (cycle_delta > max) { > - num = div64_u64(cycle_delta, max); > - nsec = (((u64) max * mult) >> shift) * num; > - cycle_delta -= num * max; > - } > - nsec += ((u64) cycle_delta * mult) >> shift; > + u64 nsec, cyc_delta; > > + cyc_delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, > + tk->tkr_mono.mask); > + nsec = mul_u64_u32_shr(cyc_delta, clock->mult, clock->shift); > ts_delta = ns_to_timespec64(nsec); > sleeptime_injected = true; > } else if (timespec64_compare(&ts_new, &timekeeping_suspend_time) > 0) { > > -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson