lkml.org 
[lkml]   [2016]   [Dec]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 4/6] timekeeping: Use mul_u64_u32_shr() instead of open coding it
    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 <tglx@linutronix.de>
    ---
    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) {

    \
     
     \ /
      Last update: 2016-12-08 21:54    [W:4.124 / U:0.144 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site