From a7bc9ac8f8a398fd11d10104a7aa26edd9b2f5a7 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Fri, 28 Sep 2007 11:21:47 +0000 Subject: [PATCH] hdparm: reduce possibility of numeric overflow in -T. do_time 386 410 +24 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/0 up/down: 24/0) Total: 24 bytes --- miscutils/hdparm.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index 8a7204f29..1f85644d6 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c @@ -1375,10 +1375,13 @@ static void print_timing(unsigned long m, unsigned elapsed_us) printf("%5lu MB in %u.%02u seconds = %lu kB/s\n", m, sec, hs, /* Trying to not overflow 32-bit arith in m * CONST - * by keeping CONST not so big. + 1 prevents div-by-0. */ - (m * (1024 * 1000000 / (64*1024))) / (elapsed_us / (64*1024) + 1) - // ~= (m * 1024 * 1000000) / elapsed_ms - // = (m * 1024) / (elapsed_ms / 1000000) + * by keeping CONST not so big. But elapsed_us / CONST2 + * also should not introduce big errors. Currently, + * 16000us is ~1.6% of 1 second. + * "+ 1" prevents div-by-0. */ + (m * (1024 * 1000000 / (16*1024))) / (elapsed_us / (16*1024) + 1) + // ~= (m * 1024 * 1000000) / elapsed_us + // = (m * 1024) / (elapsed_us / 1000000) // = kb / elapsed_sec ); } @@ -1418,6 +1421,11 @@ static void do_time(int cache /*,int fd*/) /* Now do the timing */ iterations = 0; + /* Max time to run (small for cache, avoids getting + * huge total_MB which can overlow on print_timing) */ + elapsed2 = 510000; /* cache */ + if (!cache) + elapsed2 = 3000000; /* not cache */ start = monotonic_us(); do { if (cache) @@ -1425,11 +1433,11 @@ static void do_time(int cache /*,int fd*/) read_big_block(buf); elapsed = (unsigned)monotonic_us() - start; ++iterations; - } while (elapsed < 3000000 && iterations < max_iterations); + } while (elapsed < elapsed2 && iterations < max_iterations); total_MB = (unsigned long)iterations * TIMING_BUF_MB; //printf(" elapsed:%u iterations:%u ", elapsed, iterations); if (cache) { - /* Now remove the lseek() and monotonic_us() overheads + /* Cache: remove lseek() and monotonic_us() overheads * from elapsed */ start = monotonic_us(); do {