Recent changes (master)

Jens Axboe
2020-04-07T12:00:05Z

The following changes since commit 6463db6c1d3a2a961008e87a86d464b596886f1a:

fio: fix interaction between offset/size limited threads and "max_open_zones" (2020-04-02 13:33:49 -0600)

are available in the Git repository at:

git://git.kernel.dk/fio.git master

for you to fetch changes up to ebc403fe282864eddfd68ab1793f149a1b0eb1cd:

zbd: fixup ->zone_size_log2 if zone size is not power of 2 (2020-04-06 19:41:45 -0600)

----------------------------------------------------------------
Alexey Dobriyan (1):
zbd: fixup ->zone_size_log2 if zone size is not power of 2

Damien Le Moal (1):
zbd: Fix potential zone lock deadlock

zbd.c | 64 ++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 32 insertions(+), 32 deletions(-)

---

Diff of recent changes:

diff --git a/zbd.c b/zbd.c
index 0dd5a619..e2f3f52f 100644
--- a/zbd.c
+++ b/zbd.c
@@ -58,6 +58,24 @@ static bool zbd_zone_full(const struct fio_file *f, struct fio_zone_info *z,
z->wp + required > z->start + f->zbd_info->zone_size;
}

+static void zone_lock(struct thread_data *td, struct fio_zone_info *z)
+{
+ /*
+ * Lock the io_u target zone. The zone will be unlocked if io_u offset
+ * is changed or when io_u completes and zbd_put_io() executed.
+ * To avoid multiple jobs doing asynchronous I/Os from deadlocking each
+ * other waiting for zone locks when building an io_u batch, first
+ * only trylock the zone. If the zone is already locked by another job,
+ * process the currently queued I/Os so that I/O progress is made and
+ * zones unlocked.
+ */
+ if (pthread_mutex_trylock(&z->mutex) != 0) {
+ if (!td_ioengine_flagged(td, FIO_SYNCIO))
+ io_u_quiesce(td);
+ pthread_mutex_lock(&z->mutex);
+ }
+}
+
static bool is_valid_offset(const struct fio_file *f, uint64_t offset)
{
return (uint64_t)(offset - f->file_offset) < f->io_size;
@@ -380,7 +398,7 @@ static int init_zone_info(struct thread_data *td, struct fio_file *f)
f->zbd_info = zbd_info;
f->zbd_info->zone_size = zone_size;
f->zbd_info->zone_size_log2 = is_power_of_2(zone_size) ?
- ilog2(zone_size) : -1;
+ ilog2(zone_size) : 0;
f->zbd_info->nr_zones = nr_zones;
pthread_mutexattr_destroy(&attr);
return 0;
@@ -497,7 +515,7 @@ static int parse_zone_info(struct thread_data *td, struct fio_file *f)
f->zbd_info = zbd_info;
f->zbd_info->zone_size = zone_size;
f->zbd_info->zone_size_log2 = is_power_of_2(zone_size) ?
- ilog2(zone_size) : -1;
+ ilog2(zone_size) : 0;
f->zbd_info->nr_zones = nr_zones;
zbd_info = NULL;
ret = 0;
@@ -716,18 +734,18 @@ static int zbd_reset_zones(struct thread_data *td, struct fio_file *f,
zbd_zone_nr(f->zbd_info, zb), zbd_zone_nr(f->zbd_info, ze));
assert(f->fd != -1);
for (z = zb; z < ze; z++) {
- pthread_mutex_lock(&z->mutex);
- if (z->type == BLK_ZONE_TYPE_SEQWRITE_REQ) {
- reset_wp = all_zones ? z->wp != z->start :
- (td->o.td_ddir & TD_DDIR_WRITE) &&
- z->wp % min_bs != 0;
- if (reset_wp) {
- dprint(FD_ZBD, "%s: resetting zone %u\n",
- f->file_name,
- zbd_zone_nr(f->zbd_info, z));
- if (zbd_reset_zone(td, f, z) < 0)
- res = 1;
- }
+ if (z->type != BLK_ZONE_TYPE_SEQWRITE_REQ)
+ continue;
+ zone_lock(td, z);
+ reset_wp = all_zones ? z->wp != z->start :
+ (td->o.td_ddir & TD_DDIR_WRITE) &&
+ z->wp % min_bs != 0;
+ if (reset_wp) {
+ dprint(FD_ZBD, "%s: resetting zone %u\n",
+ f->file_name,
+ zbd_zone_nr(f->zbd_info, z));
+ if (zbd_reset_zone(td, f, z) < 0)
+ res = 1;
}
pthread_mutex_unlock(&z->mutex);
}
@@ -927,24 +945,6 @@ static void zbd_close_zone(struct thread_data *td, const struct fio_file *f,
f->zbd_info->zone_info[zone_idx].open = 0;
}

-static void zone_lock(struct thread_data *td, struct fio_zone_info *z)
-{
- /*
- * Lock the io_u target zone. The zone will be unlocked if io_u offset
- * is changed or when io_u completes and zbd_put_io() executed.
- * To avoid multiple jobs doing asynchronous I/Os from deadlocking each
- * other waiting for zone locks when building an io_u batch, first
- * only trylock the zone. If the zone is already locked by another job,
- * process the currently queued I/Os so that I/O progress is made and
- * zones unlocked.
- */
- if (pthread_mutex_trylock(&z->mutex) != 0) {
- if (!td_ioengine_flagged(td, FIO_SYNCIO))
- io_u_quiesce(td);
- pthread_mutex_lock(&z->mutex);
- }
-}
-
/* Anything goes as long as it is not a constant. */
static uint32_t pick_random_zone_idx(const struct fio_file *f,
const struct io_u *io_u)