Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer fix from Ingo Molnar:
"This tree contains a clockevents regression fix for certain ARM
subarchitectures"

* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
clockevents: Sanitize ticks to nsec conversion

+51 -16
+51 -16
kernel/time/clockevents.c
··· 33 33 int res; 34 34 }; 35 35 36 + static u64 cev_delta2ns(unsigned long latch, struct clock_event_device *evt, 37 + bool ismax) 38 + { 39 + u64 clc = (u64) latch << evt->shift; 40 + u64 rnd; 41 + 42 + if (unlikely(!evt->mult)) { 43 + evt->mult = 1; 44 + WARN_ON(1); 45 + } 46 + rnd = (u64) evt->mult - 1; 47 + 48 + /* 49 + * Upper bound sanity check. If the backwards conversion is 50 + * not equal latch, we know that the above shift overflowed. 51 + */ 52 + if ((clc >> evt->shift) != (u64)latch) 53 + clc = ~0ULL; 54 + 55 + /* 56 + * Scaled math oddities: 57 + * 58 + * For mult <= (1 << shift) we can safely add mult - 1 to 59 + * prevent integer rounding loss. So the backwards conversion 60 + * from nsec to device ticks will be correct. 61 + * 62 + * For mult > (1 << shift), i.e. device frequency is > 1GHz we 63 + * need to be careful. Adding mult - 1 will result in a value 64 + * which when converted back to device ticks can be larger 65 + * than latch by up to (mult - 1) >> shift. For the min_delta 66 + * calculation we still want to apply this in order to stay 67 + * above the minimum device ticks limit. For the upper limit 68 + * we would end up with a latch value larger than the upper 69 + * limit of the device, so we omit the add to stay below the 70 + * device upper boundary. 71 + * 72 + * Also omit the add if it would overflow the u64 boundary. 73 + */ 74 + if ((~0ULL - clc > rnd) && 75 + (!ismax || evt->mult <= (1U << evt->shift))) 76 + clc += rnd; 77 + 78 + do_div(clc, evt->mult); 79 + 80 + /* Deltas less than 1usec are pointless noise */ 81 + return clc > 1000 ? clc : 1000; 82 + } 83 + 36 84 /** 37 85 * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds 38 86 * @latch: value to convert ··· 90 42 */ 91 43 u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt) 92 44 { 93 - u64 clc = (u64) latch << evt->shift; 94 - 95 - if (unlikely(!evt->mult)) { 96 - evt->mult = 1; 97 - WARN_ON(1); 98 - } 99 - 100 - do_div(clc, evt->mult); 101 - if (clc < 1000) 102 - clc = 1000; 103 - if (clc > KTIME_MAX) 104 - clc = KTIME_MAX; 105 - 106 - return clc; 45 + return cev_delta2ns(latch, evt, false); 107 46 } 108 47 EXPORT_SYMBOL_GPL(clockevent_delta2ns); 109 48 ··· 415 380 sec = 600; 416 381 417 382 clockevents_calc_mult_shift(dev, freq, sec); 418 - dev->min_delta_ns = clockevent_delta2ns(dev->min_delta_ticks, dev); 419 - dev->max_delta_ns = clockevent_delta2ns(dev->max_delta_ticks, dev); 383 + dev->min_delta_ns = cev_delta2ns(dev->min_delta_ticks, dev, false); 384 + dev->max_delta_ns = cev_delta2ns(dev->max_delta_ticks, dev, true); 420 385 } 421 386 422 387 /**