From 8bd0fe749c98e67ee4150b6eaf3b66f361413ec0 Mon Sep 17 00:00:00 2001 From: Salman Qazi Date: Fri, 9 Mar 2012 16:41:01 -0800 Subject: [PATCH] --- yaml --- r: 288767 b: refs/heads/master c: 9993bc635d01a6ee7f6b833b4ee65ce7c06350b1 h: refs/heads/master i: 288765: cb5407fede03c372b07ae080c44ec94423e412c8 288763: 569c3f9d1b0dbb7216ee596f733a26d6b80ab40e 288759: 96e02350090689e2bf60e56ffbc6394aa092c4c9 288751: b9a20c8b0c30002a5855d120b6029d1c043c1df2 288735: 373226b5c95a72c5aeeb8f901199b9d6e7c11791 288703: 783d1710c2438bf7a2316af5b8ccbaabc56f2187 288639: 04077cd75932a81bcf262cfe98fa59d57042d2d3 288511: c86ec1a70f3d84b21dda5fcd5600fc576d6aeaeb 288255: 5852ec89ed1ae6f0d75518d954fe38328e63f157 287743: 4f58ce1bbf10f99c33a162bc9a5cbb662052a2a7 286719: 66d4c0fd3b051803633a7e1f7e2fb3b66e0c2fe6 v: v3 --- [refs] | 2 +- trunk/arch/x86/include/asm/timer.h | 8 ++------ trunk/arch/x86/kernel/tsc.c | 3 ++- trunk/include/linux/kernel.h | 13 +++++++++++++ 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index 82eb0ef52b1a..d13ebf2f9e89 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 47258cf3c4aa5d56e678bafe0dd0d03ddd980b88 +refs/heads/master: 9993bc635d01a6ee7f6b833b4ee65ce7c06350b1 diff --git a/trunk/arch/x86/include/asm/timer.h b/trunk/arch/x86/include/asm/timer.h index 431793e5d484..34baa0eb5d0c 100644 --- a/trunk/arch/x86/include/asm/timer.h +++ b/trunk/arch/x86/include/asm/timer.h @@ -57,14 +57,10 @@ DECLARE_PER_CPU(unsigned long long, cyc2ns_offset); static inline unsigned long long __cycles_2_ns(unsigned long long cyc) { - unsigned long long quot; - unsigned long long rem; int cpu = smp_processor_id(); unsigned long long ns = per_cpu(cyc2ns_offset, cpu); - quot = (cyc >> CYC2NS_SCALE_FACTOR); - rem = cyc & ((1ULL << CYC2NS_SCALE_FACTOR) - 1); - ns += quot * per_cpu(cyc2ns, cpu) + - ((rem * per_cpu(cyc2ns, cpu)) >> CYC2NS_SCALE_FACTOR); + ns += mult_frac(cyc, per_cpu(cyc2ns, cpu), + (1UL << CYC2NS_SCALE_FACTOR)); return ns; } diff --git a/trunk/arch/x86/kernel/tsc.c b/trunk/arch/x86/kernel/tsc.c index a62c201c97ec..183c5925a9fe 100644 --- a/trunk/arch/x86/kernel/tsc.c +++ b/trunk/arch/x86/kernel/tsc.c @@ -620,7 +620,8 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) if (cpu_khz) { *scale = (NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR)/cpu_khz; - *offset = ns_now - (tsc_now * *scale >> CYC2NS_SCALE_FACTOR); + *offset = ns_now - mult_frac(tsc_now, *scale, + (1UL << CYC2NS_SCALE_FACTOR)); } sched_clock_idle_wakeup_event(0); diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index e8343422240a..d801acb5e680 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -85,6 +85,19 @@ } \ ) +/* + * Multiplies an integer by a fraction, while avoiding unnecessary + * overflow or loss of precision. + */ +#define mult_frac(x, numer, denom)( \ +{ \ + typeof(x) quot = (x) / (denom); \ + typeof(x) rem = (x) % (denom); \ + (quot * (numer)) + ((rem * (numer)) / (denom)); \ +} \ +) + + #define _RET_IP_ (unsigned long)__builtin_return_address(0) #define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })