Fix io_u->buf calculation overflow
authorJens Axboe <axboe@kernel.dk>
Sat, 22 Oct 2011 16:47:21 +0000 (18:47 +0200)
committerJens Axboe <axboe@kernel.dk>
Sat, 22 Oct 2011 16:47:21 +0000 (18:47 +0200)
Jagadish reports:

----

following are the details of the bug in fio.

This bug in fio can show up as corruption of data when performing verify.

Description:
----------------

if  the product of block size and queudepth is greater than 4GB, io_u
buffer will not
be assigned properly due to overflow.

fio --bsrange=256k-4m --ioengine=libaio --iodepth=2064 --direct=1
--name=job3 --offset=2GB --size=14GB --rw=write
--verify_pattern=0xdeadbeef --filename=/dev/sdb

can show false corruption.

Version:
-----------
1.58

Explanation:
-----------------

in a loop fio tries to assign the data buffer to each i/o request.

static int init_io_u(struct thread_data *td)
{
        struct io_u *io_u;
        unsigned int max_bs;
        int cl_align, i, max_units;
        char *p;
...
         p = td->orig_buffer;
...
         for (i = 0; i < max_units; i++) {
...
                    io_u->buf = p + max_bs * i;
         }
}

at max_bs=4M i=1024, the integer overflows and the addresses are being
used again.
i,e i/o request 1024 will have the same data buffer as that of i/o request 0.

This is seen from fio debug log.

mem 11164 io_u alloc 0x219f530, index 0
mem 11164 io_u 0x219f530, mem 0x7f09bb62d000
mem 11164 io_u alloc 0x219f820, index 1
mem 11164 io_u 0x219f820, mem 0x7f09bba2d000

mem 11164 io_u alloc 0x225b530, index 1024
mem 11164 io_u 0x225b530, mem 0x7f09bb62d000
mem 11164 io_u alloc 0x225b820, index 1025
mem 11164 io_u 0x225b820, mem 0x7f09bba2d000

the fix is as follows:

                        io_u->buf = p + (unsigned long long)max_bs * i;

----

Fix this by continually incrementing 'p' instead, avoiding
the overflow as well.

Reported-by: Jagadish Kumar <jagadish.mukku@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fio.c

diff --git a/fio.c b/fio.c
index b492889f740b1745922fe2fb0a2388b73d91f7b2..8b1a6004958253dbcf22ac2cc721676775862161 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -871,7 +871,7 @@ static int init_io_u(struct thread_data *td)
                dprint(FD_MEM, "io_u alloc %p, index %u\n", io_u, i);
 
                if (!(td->io_ops->flags & FIO_NOIO)) {
-                       io_u->buf = p + max_bs * i;
+                       io_u->buf = p;
                        dprint(FD_MEM, "io_u %p, mem %p\n", io_u, io_u->buf);
 
                        if (td_write(td))
@@ -888,6 +888,7 @@ static int init_io_u(struct thread_data *td)
                io_u->index = i;
                io_u->flags = IO_U_F_FREE;
                flist_add(&io_u->list, &td->io_u_freelist);
+               p += max_bs;
        }
 
        return 0;