summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ktime.h27
-rw-r--r--kernel/time/hrtimer.c14
2 files changed, 29 insertions, 12 deletions
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index 5fc3d1083071..2b6a204bd8d4 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -166,19 +166,34 @@ static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2)
166} 166}
167 167
168#if BITS_PER_LONG < 64 168#if BITS_PER_LONG < 64
169extern u64 __ktime_divns(const ktime_t kt, s64 div); 169extern s64 __ktime_divns(const ktime_t kt, s64 div);
170static inline u64 ktime_divns(const ktime_t kt, s64 div) 170static inline s64 ktime_divns(const ktime_t kt, s64 div)
171{ 171{
172 /*
173 * Negative divisors could cause an inf loop,
174 * so bug out here.
175 */
176 BUG_ON(div < 0);
172 if (__builtin_constant_p(div) && !(div >> 32)) { 177 if (__builtin_constant_p(div) && !(div >> 32)) {
173 u64 ns = kt.tv64; 178 s64 ns = kt.tv64;
174 do_div(ns, div); 179 u64 tmp = ns < 0 ? -ns : ns;
175 return ns; 180
181 do_div(tmp, div);
182 return ns < 0 ? -tmp : tmp;
176 } else { 183 } else {
177 return __ktime_divns(kt, div); 184 return __ktime_divns(kt, div);
178 } 185 }
179} 186}
180#else /* BITS_PER_LONG < 64 */ 187#else /* BITS_PER_LONG < 64 */
181# define ktime_divns(kt, div) (u64)((kt).tv64 / (div)) 188static inline s64 ktime_divns(const ktime_t kt, s64 div)
189{
190 /*
191 * 32-bit implementation cannot handle negative divisors,
192 * so catch them on 64bit as well.
193 */
194 WARN_ON(div < 0);
195 return kt.tv64 / div;
196}
182#endif 197#endif
183 198
184static inline s64 ktime_to_us(const ktime_t kt) 199static inline s64 ktime_to_us(const ktime_t kt)
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 */
269u64 __ktime_divns(const ktime_t kt, s64 div) 269s64 __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}
285EXPORT_SYMBOL_GPL(__ktime_divns); 287EXPORT_SYMBOL_GPL(__ktime_divns);
286#endif /* BITS_PER_LONG >= 64 */ 288#endif /* BITS_PER_LONG >= 64 */