If this multiplication overflows:
usecs = (t * inv_cycles_per_usec) / 16777216UL;
then usecs is 2^64/2^24, which is
1099511627776. Divide that by
10^6 to get seconds, and that is
1099511. Since we cached the
old value previously, we'd get stuck with this amount of seconds.
To avoid turning this into an expensive division, have a check
and only divide if we have to. This avoids the overflow.
Signed-off-by: Jens Axboe <axboe@fb.com>
#if defined(ARCH_HAVE_CPU_CLOCK) && !defined(ARCH_CPU_CLOCK_CYCLES_PER_USEC)
static unsigned long cycles_per_usec;
static unsigned long inv_cycles_per_usec;
#if defined(ARCH_HAVE_CPU_CLOCK) && !defined(ARCH_CPU_CLOCK_CYCLES_PER_USEC)
static unsigned long cycles_per_usec;
static unsigned long inv_cycles_per_usec;
+static uint64_t max_cycles_for_mult;
#endif
int tsc_reliable = 0;
#endif
int tsc_reliable = 0;
#ifdef ARCH_CPU_CLOCK_CYCLES_PER_USEC
usecs = t / ARCH_CPU_CLOCK_CYCLES_PER_USEC;
#else
#ifdef ARCH_CPU_CLOCK_CYCLES_PER_USEC
usecs = t / ARCH_CPU_CLOCK_CYCLES_PER_USEC;
#else
- usecs = (t * inv_cycles_per_usec) / 16777216UL;
+ if (t < max_cycles_for_mult)
+ usecs = (t * inv_cycles_per_usec) / 16777216UL;
+ else
+ usecs = t / cycles_per_usec;
#endif
tp->tv_sec = usecs / 1000000;
tp->tv_usec = usecs % 1000000;
#endif
tp->tv_sec = usecs / 1000000;
tp->tv_usec = usecs % 1000000;
cycles_per_usec = avg;
inv_cycles_per_usec = 16777216UL / cycles_per_usec;
cycles_per_usec = avg;
inv_cycles_per_usec = 16777216UL / cycles_per_usec;
+ max_cycles_for_mult = ~0ULL / inv_cycles_per_usec;
dprint(FD_TIME, "inv_cycles_per_usec=%lu\n", inv_cycles_per_usec);
return 0;
}
dprint(FD_TIME, "inv_cycles_per_usec=%lu\n", inv_cycles_per_usec);
return 0;
}