From 4662c206a07e408b1970a577fda107e4f9397a68 Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Thu, 22 Apr 2021 11:17:58 +0200 Subject: [PATCH] init: zonemode=zbd does not work with create_serialize=0 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 --- init.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/init.c b/init.c index 37bff876..60c7cff4 100644 --- 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; -- 2.25.1