From: Shin'ichiro Kawasaki Date: Mon, 14 Apr 2025 06:27:20 +0000 (+0900) Subject: zbd: finish zone when all random write target zones have small remainder X-Git-Tag: fio-3.40~29 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=e2e29bf6f8300186d267fa46a7b266d14d174575;p=fio.git zbd: finish zone when all random write target zones have small remainder When a random write target offset points to a zone that is not writable, zbd_convert_to_write_zone() attempts to convert the write offset to a different, writable zone. However, the conversion fails when all of the following conditions are met: 1) the workload has the max_open_zones limit 2) every write target zones, up to the max_open_zones limit, has remainder sectors smaller than the block size 3) the next random write request targets a zone not in the write target zone list In this case, zbd_convert_to_write_zone() can not open another zone without exceeding the max_open_zones constraint. Therefore, It does not convert the write to a different zone printing with the debug message "did not choose another write zone". This leads to an unexpected stop of the random write workload. To prevent the unexpected write stop, finish one of the write target zones with small remainder sectors. Check if all write target zones have small remainder, and store the result in the new local boolean variable all_write_zones_have_small_remainder. When this condition is true, choose one of the write target zones and finish it. Then return the zone from zbd_convert_to_write_zone() enabling the write process to continue. Signed-off-by: Shin'ichiro Kawasaki Reviewed-by: Damien Le Moal Link: https://lore.kernel.org/r/20250414062721.87641-4-shinichiro.kawasaki@wdc.com Signed-off-by: Jens Axboe --- diff --git a/zbd.c b/zbd.c index d547bf3b..89519234 100644 --- a/zbd.c +++ b/zbd.c @@ -1460,6 +1460,7 @@ static struct fio_zone_info *zbd_convert_to_write_zone(struct thread_data *td, bool wait_zone_write; bool in_flight; bool should_retry = true; + bool need_zone_finish; assert(is_valid_offset(f, io_u->offset)); @@ -1611,6 +1612,7 @@ retry: /* Check whether the write fits in any of the write target zones. */ pthread_mutex_lock(&zbdi->mutex); + need_zone_finish = true; for (i = 0; i < zbdi->num_write_zones; i++) { zone_idx = zbdi->write_zones[i]; if (zone_idx < f->min_zone || zone_idx >= f->max_zone) @@ -1621,8 +1623,10 @@ retry: z = zbd_get_zone(f, zone_idx); zone_lock(td, f, z); - if (zbd_zone_remainder(z) >= min_bs) + if (zbd_zone_remainder(z) >= min_bs) { + need_zone_finish = false; goto out; + } pthread_mutex_lock(&zbdi->mutex); } @@ -1645,6 +1649,26 @@ retry: goto retry; } + if (td_random(td) && td->o.verify == VERIFY_NONE && need_zone_finish) + /* + * If all open zones have remainder smaller than the block size + * for random write jobs, choose one of the write target zones + * and finish it. When verify is enabled, skip this zone finish + * operation to avoid verify data corruption by overwrite to the + * zone. + */ + if (zbd_pick_write_zone(f, io_u, &zone_idx)) { + pthread_mutex_unlock(&zbdi->mutex); + zone_unlock(z); + z = zbd_get_zone(f, zone_idx); + zone_lock(td, f, z); + io_u_quiesce(td); + dprint(FD_ZBD, "%s(%s): All write target zones have remainder smaller than block size. Choose zone %d and finish.\n", + __func__, f->file_name, zone_idx); + zbd_finish_zone(td, f, z); + goto out; + } + pthread_mutex_unlock(&zbdi->mutex); zone_unlock(z);