diff options
author | Henrik Austad <henrik@austad.us> | 2014-03-04 09:20:53 +0100 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2014-03-06 17:53:12 +0100 |
commit | 767f30210bee1bb74ab042e237c2a21e77874070 (patch) | |
tree | 83d5b3ea8f10688b80262172dda68e23b68816ff /arch/tile/kernel/time.c | |
parent | Linux 3.14-rc5 (diff) | |
download | linux-767f30210bee1bb74ab042e237c2a21e77874070.tar.xz linux-767f30210bee1bb74ab042e237c2a21e77874070.zip |
tile: avoid overflow in ns2cycles
In commit 4cecf6d401a ("sched, x86: Avoid unnecessary overflow in
sched_clock") and in recent patch "clocksource: avoid unnecessary
overflow in cyclecounter_cyc2ns()" https://lkml.org/lkml/2014/3/4/17,
the mult-shift approach is replaced by 2 steps to avoid storing a large,
intermediate value that could overflow.
arch/tile/kernel/time.c has a similar pattern in cycles2ns, and this
copies the same pattern in this function
CC: John Stultz <johnstul@us.ibm.com>
CC: Mike Galbraith <bitbucket@online.de>
CC: Salman Qazi <sqazi@google.com>
Signed-off-by: Henrik Austad <henrik@austad.us>
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/kernel/time.c')
-rw-r--r-- | arch/tile/kernel/time.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c index 5d10642db63e..462dcd0c1700 100644 --- a/arch/tile/kernel/time.c +++ b/arch/tile/kernel/time.c @@ -236,7 +236,15 @@ cycles_t ns2cycles(unsigned long nsecs) * clock frequency. */ struct clock_event_device *dev = &__raw_get_cpu_var(tile_timer); - return ((u64)nsecs * dev->mult) >> dev->shift; + + /* + * as in clocksource.h and x86's timer.h, we split the calculation + * into 2 parts to avoid unecessary overflow of the intermediate + * value. This will not lead to any loss of precision. + */ + u64 quot = (u64)nsecs >> dev->shift; + u64 rem = (u64)nsecs & ((1ULL << dev->shift) - 1); + return quot * dev->mult + ((rem * dev->mult) >> dev->shift); } void update_vsyscall_tz(void) |