Fix 32-bit/LLP64 platform truncation issues
authorSitsofe Wheeler <sitsofe@yahoo.com>
Tue, 19 May 2020 21:41:49 +0000 (22:41 +0100)
committerSitsofe Wheeler <sitsofe@yahoo.com>
Tue, 19 May 2020 22:09:42 +0000 (23:09 +0100)
- After 140a6888 ("rate: Convert the rate and rate_min options to
  FIO_OPTS_ULL") landed 32-bit/LLP64 platforms need additional changes
  to cope with 64 bit I/O rate values
- The seed is 64 bit but was being being truncated to 32 bits in
  td_fill_rand_seeds_internal() on bit/LLP64 platforms

Prior to this commit when running an fio compiled with

CC=clang-9 ./configure \
  --extra-cflags="-fsanitize=undefined,implicit-integer-truncation "
  "-fno-builtin"

using this job

./fio --ioengine=null --bs=1M --rate=6G --rate_min=5G --name=test --size=100G

warnings like the following were produced

init.c:996:27: runtime error: implicit conversion from type 'uint64_t' (aka 'unsigned long long') of value 5942511153023025289 (64-bit, unsigned) to type 'unsigned int' changed the value to 2914779273 (32-bit, unsigned)
[..]
backend.c:212:25: runtime error: implicit conversion from type 'unsigned long long' of value 12886999040 (64-bit, unsigned) to type 'unsigned long' changed the value to 2097152 (32-bit, unsigned)

inside a 32-bit Ubuntu 18.04 docker container.

Fixes: https://github.com/axboe/fio/issues/716

fio.h
init.c
lib/rand.c
lib/rand.h

diff --git a/fio.h b/fio.h
index bbf057c104cd39ab79576bc1baf06725aaceeb61..dbdfdf86c88ae97a7be1d4c3fdf3f3409ddccd92 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -319,7 +319,7 @@ struct thread_data {
         */
        uint64_t rate_bps[DDIR_RWDIR_CNT];
        uint64_t rate_next_io_time[DDIR_RWDIR_CNT];
         */
        uint64_t rate_bps[DDIR_RWDIR_CNT];
        uint64_t rate_next_io_time[DDIR_RWDIR_CNT];
-       unsigned long rate_bytes[DDIR_RWDIR_CNT];
+       unsigned long long rate_bytes[DDIR_RWDIR_CNT];
        unsigned long rate_blocks[DDIR_RWDIR_CNT];
        unsigned long long rate_io_issue_bytes[DDIR_RWDIR_CNT];
        struct timespec lastrate[DDIR_RWDIR_CNT];
        unsigned long rate_blocks[DDIR_RWDIR_CNT];
        unsigned long long rate_io_issue_bytes[DDIR_RWDIR_CNT];
        struct timespec lastrate[DDIR_RWDIR_CNT];
diff --git a/init.c b/init.c
index b5315334c6ba9f6edc8aad0d477c25f7eff4ceaa..e220c323d13d1e4986a5ae0d2d26b07e5c3a0008 100644 (file)
--- a/init.c
+++ b/init.c
@@ -993,9 +993,9 @@ void td_fill_verify_state_seed(struct thread_data *td)
 
 static void td_fill_rand_seeds_internal(struct thread_data *td, bool use64)
 {
 
 static void td_fill_rand_seeds_internal(struct thread_data *td, bool use64)
 {
-       unsigned int read_seed = td->rand_seeds[FIO_RAND_BS_OFF];
-       unsigned int write_seed = td->rand_seeds[FIO_RAND_BS1_OFF];
-       unsigned int trim_seed = td->rand_seeds[FIO_RAND_BS2_OFF];
+       uint64_t read_seed = td->rand_seeds[FIO_RAND_BS_OFF];
+       uint64_t write_seed = td->rand_seeds[FIO_RAND_BS1_OFF];
+       uint64_t trim_seed = td->rand_seeds[FIO_RAND_BS2_OFF];
        int i;
 
        /*
        int i;
 
        /*
index 69acb06c14410296f959da96f27fe842f57eede1..5eb6e60aeb6b651e88595b4ba9c2d875d1a5748d 100644 (file)
@@ -85,12 +85,12 @@ void init_rand(struct frand_state *state, bool use64)
                __init_rand64(&state->state64, 1);
 }
 
                __init_rand64(&state->state64, 1);
 }
 
-void init_rand_seed(struct frand_state *state, unsigned int seed, bool use64)
+void init_rand_seed(struct frand_state *state, uint64_t seed, bool use64)
 {
        state->use64 = use64;
 
        if (!use64)
 {
        state->use64 = use64;
 
        if (!use64)
-               __init_rand32(&state->state32, seed);
+               __init_rand32(&state->state32, (unsigned int) seed);
        else
                __init_rand64(&state->state64, seed);
 }
        else
                __init_rand64(&state->state64, seed);
 }
index 95d4f6d4966d88a60700a09fba7a6487c032abd5..2ccc1b3723c42f4f90ab821bf2824611037d24dc 100644 (file)
@@ -149,7 +149,7 @@ static inline uint64_t rand_between(struct frand_state *state, uint64_t start,
 }
 
 extern void init_rand(struct frand_state *, bool);
 }
 
 extern void init_rand(struct frand_state *, bool);
-extern void init_rand_seed(struct frand_state *, unsigned int seed, bool);
+extern void init_rand_seed(struct frand_state *, uint64_t seed, bool);
 extern void __fill_random_buf(void *buf, unsigned int len, uint64_t seed);
 extern uint64_t fill_random_buf(struct frand_state *, void *buf, unsigned int len);
 extern void __fill_random_buf_percentage(uint64_t, void *, unsigned int, unsigned int, unsigned int, char *, unsigned int);
 extern void __fill_random_buf(void *buf, unsigned int len, uint64_t seed);
 extern uint64_t fill_random_buf(struct frand_state *, void *buf, unsigned int len);
 extern void __fill_random_buf_percentage(uint64_t, void *, unsigned int, unsigned int, unsigned int, char *, unsigned int);