diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-23 20:57:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-23 20:57:40 -0400 |
commit | c5db6a3bdeb72f4238e1faefa4ce4eab7a64baea (patch) | |
tree | e0034ec600453c1c1377e6b42f8818d56127617c /kernel | |
parent | 9bd4459a3d31cfe79dfb5ea00912471537f219c3 (diff) | |
parent | f7bcb70ebae0dcdb5a2d859b09e4465784d99029 (diff) |
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fix from Thomas Gleixner:
"One more fix from the timer departement:
- Handle division of negative nanosecond values proper on 32bit.
A recent cleanup wrecked the sign handling of the dividend and
dropped the check for negative divisors"
* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
ktime: Fix ktime_divns to do signed division
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/time/hrtimer.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 76d4bd962b19..93ef7190bdea 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c | |||
@@ -266,21 +266,23 @@ lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags) | |||
266 | /* | 266 | /* |
267 | * Divide a ktime value by a nanosecond value | 267 | * Divide a ktime value by a nanosecond value |
268 | */ | 268 | */ |
269 | u64 __ktime_divns(const ktime_t kt, s64 div) | 269 | s64 __ktime_divns(const ktime_t kt, s64 div) |
270 | { | 270 | { |
271 | u64 dclc; | ||
272 | int sft = 0; | 271 | int sft = 0; |
272 | s64 dclc; | ||
273 | u64 tmp; | ||
273 | 274 | ||
274 | dclc = ktime_to_ns(kt); | 275 | dclc = ktime_to_ns(kt); |
276 | tmp = dclc < 0 ? -dclc : dclc; | ||
277 | |||
275 | /* Make sure the divisor is less than 2^32: */ | 278 | /* Make sure the divisor is less than 2^32: */ |
276 | while (div >> 32) { | 279 | while (div >> 32) { |
277 | sft++; | 280 | sft++; |
278 | div >>= 1; | 281 | div >>= 1; |
279 | } | 282 | } |
280 | dclc >>= sft; | 283 | tmp >>= sft; |
281 | do_div(dclc, (unsigned long) div); | 284 | do_div(tmp, (unsigned long) div); |
282 | 285 | return dclc < 0 ? -tmp : tmp; | |
283 | return dclc; | ||
284 | } | 286 | } |
285 | EXPORT_SYMBOL_GPL(__ktime_divns); | 287 | EXPORT_SYMBOL_GPL(__ktime_divns); |
286 | #endif /* BITS_PER_LONG >= 64 */ | 288 | #endif /* BITS_PER_LONG >= 64 */ |