init: zonemode=zbd does not work with create_serialize=0
authorNiklas Cassel <niklas.cassel@wdc.com>
Thu, 22 Apr 2021 09:17:58 +0000 (11:17 +0200)
committerNiklas Cassel <niklas.cassel@wdc.com>
Thu, 22 Apr 2021 10:42:05 +0000 (12:42 +0200)
zbd_init_zone_info() has a comment that it only works correctly if it
called before the first fio fork() call.
However, right now, there is nothing that ensures this.

If the user specifies --create_serialize=0 and --numjobs=2, each thread
will get their own version of zbd_info.

zbd_info contains one mutex per zone, so if the threads get different
zbd_info, two threads can manage to lock the same zone at the same time,
which will lead to I/O errors.

Explicitly disallow --zonemode=zbd together with --create_serialize=0,
so that we know that all threads will use the same zbd_info, instead of
silently misbehaving.

Analysis:
setup_files() calls zbd_init_files() which calls zbd_init_zone_info().
zbd_init_zone_info() does a for_each_td(), where it checks if zbd_info
(for the same filename) has already been allocated by another thread.
This only works if create_serialize=1 (default).
If create_serialize=0, zbd_init_zone_info() will get called in parallel,
and in this case when the second thread checks if any other thread has
allocated zbd_info, the check will fail, since the first thread has not
yet been running long enough to allocate zbd_info.

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
init.c

diff --git a/init.c b/init.c
index 37bff8763cbb5bf924f3a3fc768f3352fbe10cf6..60c7cff405d70d8e974545026e2fe659b512b7ed 100644 (file)
--- a/init.c
+++ b/init.c
@@ -633,6 +633,11 @@ static int fixup_options(struct thread_data *td)
                ret |= 1;
        }
 
+       if (o->zone_mode == ZONE_MODE_ZBD && !o->create_serialize) {
+               log_err("fio: --zonemode=zbd and --create_serialize=0 are not compatible.\n");
+               ret |= 1;
+       }
+
        if (o->zone_mode == ZONE_MODE_STRIDED && !o->zone_size) {
                log_err("fio: --zonesize must be specified when using --zonemode=strided.\n");
                ret |= 1;