time: fix overflow in timespec_add_msec
authorSitsofe Wheeler <sitsofe@yahoo.com>
Tue, 22 Aug 2017 05:19:29 +0000 (06:19 +0100)
committerSitsofe Wheeler <sitsofe@yahoo.com>
Tue, 22 Aug 2017 16:23:52 +0000 (17:23 +0100)
commit90e2cd1e1cfc6c2bb4c5643b4864347445f9571e
tree6556c53d95f8c3b6314e4f46c92bcdb6ede6ad4b
parent168bb5875da97004163c6b755de162ad481134c4
time: fix overflow in timespec_add_msec

Commit 8b6a404cdd2c40715885e562416c3db039912773 ("nanosecond: initial
commit changing timeval to timespec") introduced a change to
timespec_add_msec that decreased the time to (unsigned) overflow of
adj_nsec leading to strange values in the write_*_log files when using
log_avg_msec. The following fio job reproduces the problem:

./fio --ioengine=null --size=2G --time_based --runtime=11s \
 --ramp_time=5s --write_iops_log=overflow --log_avg_msec=5000 \
 --name=overflow

cat overflow_iops.1.log shows the following:
5000, 997853, 0, 0
10640, 141323, 0, 0

Compiling fio with clang's undefined behaviour
sanitizer with unsigned wraparound detection turned on by using

CC=clang ./configure --extra-cflags="-fsanitize=undefined,integer"

and running the previous job produces a lot of false positives but also
flags up this:

time.c:11:35: runtime error: unsigned integer overflow: 1000000 * 5000 cannot be represented in type 'unsigned int'

Fix this by forcing the type of the integer literal to ensure that a 64
bit multiplication takes place. Further, force the result variables to
be uint64_t allowing us to remove UL from other literals. Finally adjust
some spacing while we're here.

Fixes https://github.com/axboe/fio/issues/426 (which was also reported
on the mailing list - http://www.spinics.net/lists/fio/msg06190.html ).

Reported-by: Joseph R Gruher <joseph.r.gruher@intel.com>
Suggested-by: Vincent Fu <vincent.fu@wdc.com>
Suggested-by: Jeff Furlong <jeff.furlong@wdc.com>
Reviewed-by: Vincent Fu <vincent.fu@wdc.com>
Tested-by: Joseph R Gruher <joseph.r.gruher@intel.com>
Signed-off-by: Sitsofe Wheeler <sitsofe@yahoo.com>
time.c