bssplit: Fix handling of 0 percentage
authorDamien Le Moal <damien.lemoal@wdc.com>
Wed, 31 Jul 2019 04:32:07 +0000 (13:32 +0900)
committerJens Axboe <axboe@kernel.dk>
Wed, 31 Jul 2019 14:47:59 +0000 (08:47 -0600)
If a block size percentage is ispecified as 0 in bssplit, the block size
defined is not ignored by the loop in get_next_buflen(). In particular,
if the first (smallest) block size specified has a 0 percentage, the
loop is existed and that block size used as the next IO size, resulting
in a behavior equivalent to specifying 100%. E.g. using
--bssplit=64k/0,1024k/100 results in 100% of issued IOs to be 64KB
instead of 1MB.

Fix this by ignoring bssplit entries that have a 0 percentage. This is
safe as the initialization of the bssplit array ensure that the sum of
all percentages is always 100, guaranteeing that a block size will be
chosen for the next IO size.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_u.c

diff --git a/io_u.c b/io_u.c
index 910b7deb77ccba9a15b96fa1b66496b166623d11..80df28548efba23f52652abab32926fc8dbcf65b 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -557,10 +557,10 @@ static unsigned long long get_next_buflen(struct thread_data *td, struct io_u *i
                        for (i = 0; i < td->o.bssplit_nr[ddir]; i++) {
                                struct bssplit *bsp = &td->o.bssplit[ddir][i];
 
                        for (i = 0; i < td->o.bssplit_nr[ddir]; i++) {
                                struct bssplit *bsp = &td->o.bssplit[ddir][i];
 
+                               if (!bsp->perc)
+                                       continue;
                                buflen = bsp->bs;
                                perc += bsp->perc;
                                buflen = bsp->bs;
                                perc += bsp->perc;
-                               if (!perc)
-                                       break;
                                if ((r / perc <= frand_max / 100ULL) &&
                                    io_u_fits(td, io_u, buflen))
                                        break;
                                if ((r / perc <= frand_max / 100ULL) &&
                                    io_u_fits(td, io_u, buflen))
                                        break;