zbd: reset one zone at a time
authorNaohiro Aota <naohiro.aota@wdc.com>
Fri, 28 Feb 2020 07:12:44 +0000 (16:12 +0900)
committerJens Axboe <axboe@kernel.dk>
Wed, 18 Mar 2020 02:05:54 +0000 (20:05 -0600)
zbd_rest_zones() currently scans over device zones and try to reset as much
zones as possible at a time. However, this routine takes all the lock on
the range and causes a lot of lock contentions with other threads.

This commit change the behavior to hold the lock and examine one zone at a
time. While it will increase the number of ioctl() call when it need to
reset contiguous, the overhead of increased number of ioctl()s are anyway
amortized by device side's reset performance.

Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>
Tested-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
zbd.c

diff --git a/zbd.c b/zbd.c
index ddf1e6f3e0081fa86ff3b28df2f46214828f2184..18a55ea46ef9f973c2602e135d2f81534a24de39 100644 (file)
--- a/zbd.c
+++ b/zbd.c
@@ -707,7 +707,7 @@ static int zbd_reset_zones(struct thread_data *td, struct fio_file *f,
                           struct fio_zone_info *const zb,
                           struct fio_zone_info *const ze, bool all_zones)
 {
-       struct fio_zone_info *z, *start_z = ze;
+       struct fio_zone_info *z;
        const uint32_t min_bs = td->o.min_bs[DDIR_WRITE];
        bool reset_wp;
        int res = 0;
@@ -717,48 +717,20 @@ static int zbd_reset_zones(struct thread_data *td, struct fio_file *f,
        assert(f->fd != -1);
        for (z = zb; z < ze; z++) {
                pthread_mutex_lock(&z->mutex);
-               switch (z->type) {
-               case BLK_ZONE_TYPE_SEQWRITE_REQ:
+               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 (start_z == ze && reset_wp) {
-                               start_z = z;
-                       } else if (start_z < ze && !reset_wp) {
-                               dprint(FD_ZBD,
-                                      "%s: resetting zones %u .. %u\n",
+                       if (reset_wp) {
+                               dprint(FD_ZBD, "%s: resetting zone %u\n",
                                       f->file_name,
-                                       zbd_zone_nr(f->zbd_info, start_z),
-                                       zbd_zone_nr(f->zbd_info, z));
-                               if (zbd_reset_range(td, f, start_z->start,
-                                               z->start - start_z->start) < 0)
+                                      zbd_zone_nr(f->zbd_info, z));
+                               if (zbd_reset_zone(td, f, z) < 0)
                                        res = 1;
-                               start_z = ze;
                        }
-                       break;
-               default:
-                       if (start_z == ze)
-                               break;
-                       dprint(FD_ZBD, "%s: resetting zones %u .. %u\n",
-                              f->file_name, zbd_zone_nr(f->zbd_info, start_z),
-                              zbd_zone_nr(f->zbd_info, z));
-                       if (zbd_reset_range(td, f, start_z->start,
-                                           z->start - start_z->start) < 0)
-                               res = 1;
-                       start_z = ze;
-                       break;
                }
-       }
-       if (start_z < ze) {
-               dprint(FD_ZBD, "%s: resetting zones %u .. %u\n", f->file_name,
-                       zbd_zone_nr(f->zbd_info, start_z),
-                       zbd_zone_nr(f->zbd_info, z));
-               if (zbd_reset_range(td, f, start_z->start,
-                                   z->start - start_z->start) < 0)
-                       res = 1;
-       }
-       for (z = zb; z < ze; z++)
                pthread_mutex_unlock(&z->mutex);
+       }
 
        return res;
 }