fio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dmitry Fomichev <Dmitry.Fomichev@wdc.com>
To: "fio@vger.kernel.org" <fio@vger.kernel.org>,
	"axboe@kernel.dk" <axboe@kernel.dk>,
	Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Cc: Damien Le Moal <Damien.LeMoal@wdc.com>,
	Niklas Cassel <Niklas.Cassel@wdc.com>
Subject: Re: [PATCH 2/4] zbd: Support zone reset by trim
Date: Tue, 3 Aug 2021 19:36:05 +0000	[thread overview]
Message-ID: <c64f93bcd740905a63ef4b8eeb05a13bdd67d275.camel@wdc.com> (raw)
In-Reply-To: <20210728104752.923770-3-shinichiro.kawasaki@wdc.com>

On Wed, 2021-07-28 at 19:47 +0900, Shin'ichiro Kawasaki wrote:
> Enable trim workload for zonemode=zbd by modifying do_io_u_trim() to
> call zoned block device unique function zbd_do_io_u_trim() which resets
> target zone. This allows fio to emulate workloads which mix data
> read/write and zone resets with zonemode=zbd.
> 
> To call reset zones, the trim I/O shall have offset aligned to zone
> start and block size same as zone size. Reset zone is called only to
> sequential write required zones and sequential write preferred zones.
> Conventional zones are handled in same manner as regular block devices
> by calling os_trim() function.
> 
> When zones are reset with random trim workload, choose only non-empty
> zones as trim target. This avoids meaningless trim to empty zones and
> makes the workload more realistic. To find the non-empty zones, utilize
> zbd_find_zone() helper function which is already used for read
> workload,
> specifying 1 byte as the minimum valid data size.
> 
> Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
> ---
>  HOWTO  |  3 +++
>  fio.1  |  2 ++
>  io_u.c |  9 ++++++++
>  zbd.c  | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
>  zbd.h  |  2 ++
>  5 files changed, 83 insertions(+), 4 deletions(-)
> 
> diff --git a/HOWTO b/HOWTO
> index 59c7f1ff..f1fd2045 100644
> --- a/HOWTO
> +++ b/HOWTO
> @@ -992,6 +992,9 @@ Target file/device
>                                 single zone. The :option:`zoneskip`
> parameter
>                                 is ignored. :option:`zonerange` and
>                                 :option:`zonesize` must be identical.
> +                               Trim is handled using a zone reset
> operation.
> +                               Trim only considers non-empty
> sequential write
> +                               required and sequential write preferred
> zones.

The documentation changes could be moved to a separate patch. While
looking at HOWTO file, I notice that libzbc is absent from the list of
i/o engines there. Perhaps, since you are making changes to this file,
you could add a small description of libzbc there and mention that it
supports read, write and trim workloads when run against zoned block
devices.

>  
>  .. option:: zonerange=int
>  
> diff --git a/fio.1 b/fio.1
> index 6cc82542..ef319062 100644
> --- a/fio.1
> +++ b/fio.1
> @@ -766,6 +766,8 @@ starts. The \fBzonecapacity\fR parameter is
> ignored.
>  Zoned block device mode. I/O happens sequentially in each zone, even
> if random32ad4373
>  I/O has been selected. Random I/O happens across all zones instead of
> being
>  restricted to a single zone.
> +Trim is handled using a zone reset operation. Trim only considers non-
> empty
> +sequential write required and sequential write preferred zones.
>  .RE
>  .RE
>  .TP
> diff --git a/io_u.c b/io_u.c
> index 9a1cd547..696d25cd 100644
> --- a/io_u.c
> +++ b/io_u.c
> @@ -2317,10 +2317,19 @@ int do_io_u_trim(const struct thread_data *td,
> struct io_u *io_u)
>         struct fio_file *f = io_u->file;
>         int ret;
>  
> +       if (td->o.zone_mode == ZONE_MODE_ZBD) {
> +               ret = zbd_do_io_u_trim(td, io_u);
> +               if (ret == io_u_completed)
> +                       return io_u->xfer_buflen;
> +               if (ret)
> +                       goto err;
> +       }
> +
>         ret = os_trim(f, io_u->offset, io_u->xfer_buflen);
>         if (!ret)
>                 return io_u->xfer_buflen;
>  
> +err:
>         io_u->error = ret;
>         return 0;
>  #endif
> diff --git a/zbd.c b/zbd.c
> index f10b3267..39060ecd 100644
> --- a/zbd.cpassing in an offset
        modifier with a value of 8. If the suffix is used with a
sequential I/O

> +++ b/zbd.c
> @@ -375,12 +375,24 @@ static bool zbd_verify_bs(void)
>         int i, j, k;
>  
>         for_each_td(td, i) {
> +               if (td_trim(td) &&
> +                   (td->o.min_bs[DDIR_TRIM] != td-
> >o.max_bs[DDIR_TRIM] ||
> +                    td->o.bssplit_nr[DDIR_TRIM])) {
> +                       log_info("bsrange and bssplit is not allowed
> for trim with zonemode=zbd\n");
> +                       return false;
> +               }
>                 for_each_file(td, f, j) {
>                         uint64_t zone_size;
>  
>                         if (!f->zbd_info)
>                                 continue;
>                         zone_size = f->zbd_info->zone_size;
> +                       if (td_trim(td) && td->o.bs[DDIR_TRIM] !=
> zone_size) {
> +                               log_info("%s: trim block size %llu is
> not the zone size %llu\n",
> +                                        f->file_name, td-
> >o.bs[DDIR_TRIM],
> +                                        (unsigned long
> long)zone_size);
> +                               return false;
> +                       }
>                         for (k = 0; k < FIO_ARRAY_SIZE(td->o.bs);
> k++) {
>                                 if (td->o.verify != VERIFY_NONE &&
>                                     zone_size % td->o.bs[k] != 0) {
> @@ -1528,9 +1540,6 @@ static void zbd_queue_io(struct thread_data
> *td, struct io_u *io_u, int q,
>                 pthread_mutex_unlock(&zbd_info->mutex);
>                 z->wp = zone_end;
>                 break;
> -       case DDIR_TRIM:
> -               assert(z->wp == z->start);
> -               break;
>         default:
>                 break;
>         }
> @@ -1910,8 +1919,23 @@ enum io_u_action zbd_adjust_block(struct
> thread_data *td, struct io_u *io_u)
>                         (zbd_zone_capacity_end(zb) - io_u->offset),
> min_bs);
>                 goto eof;
>         case DDIR_TRIM:
> -               /* fall-through */
> +               /* Check random trim targets a non-empty zone */
> +               if (!td_random(td) || zb->wp > zb->start)
> +                       goto accept;
> +
> +               /* Find out a non-empty zone to trim */
> +               zone_unlock(zb);
> +               zl = get_zone(f, f->max_zone);
> +               zb = zbd_find_zone(td, io_u, 1, zb, zl);
> +               if (zb) {
> +                       io_u->offset = zb->start;
> +                       dprint(FD_ZBD, "%s: found new zone(%lld) for
> trim\n",
> +                              f->file_name, io_u->offset);
> +                       goto accept;
> +               }
> +               goto eof;
>         case DDIR_SYNC:
> +               /* fall-through */
>         case DDIR_DATASYNC:
>         case DDIR_SYNC_FILE_RANGE:
>         case DDIR_WAIT:
> @@ -1952,3 +1976,42 @@ char *zbd_write_status(const struct
> thread_stat *ts)
>                 return NULL;
>         return res;
>  }
> +
> +/**
> + * zbd_do_io_u_trim - If reset zone is applicable, do reset zone
> instead of trim
> + *
> + * @td: FIO thread data.
> + * @io_u: FIO I/O unit.
> + *
> + * It is assumed that z->mutex is already locked.
> + * Return io_u_completed when reset zone succeeds. Return 0 when the
> target zone
> + * does not have write pointer. On error, return negative errno.
> + */
> +int zbd_do_io_u_trim(const struct thread_data *td, struct io_u
> *io_u)
> +{
> +       struct fio_file *f = io_u->file;
> +       struct fio_zone_info *z;
> +       uint32_t zone_idx;
> +       int ret;
> +
> +       zone_idx = zbd_zone_idx(f, io_u->offset);
> +       z = get_zone(f, zone_idx);
> +
> +       if (!z->has_wp)
> +               return 0;
> +
> +       if (io_u->offset != z->start) {
> +               log_err("Trim offset not at zone start (%lld)\n",
> io_u->offset);
> +               return -EINVAL;
> +       }
> +
> +       /*
> +        * Cast td to drop const modifier so that zbd_reset_zone()
> can change td
> +        * members.
> +        */

This comment is not really necessary.

> +       ret = zbd_reset_zone((struct thread_data *)td, f, z);
> +       if (ret < 0)
> +               return ret;
> +
> +       return io_u_completed;
> +}
> diff --git a/zbd.h b/zbd.h
> index 39dc45e3..0a73b41d 100644
> --- a/zbd.h
> +++ b/zbd.h
> @@ -17,6 +17,7 @@ struct fio_file;
>  enum io_u_action {
>         io_u_accept     = 0,
>         io_u_eof        = 1,
> +       io_u_completed  = 2,
>  };
>  
>  /**
> @@ -99,6 +100,7 @@ enum fio_ddir zbd_adjust_ddir(struct thread_data
> *td, struct io_u *io_u,
>                               enum fio_ddir ddir);
>  enum io_u_action zbd_adjust_block(struct thread_data *td, struct
> io_u *io_u);
>  char *zbd_write_status(const struct thread_stat *ts);
> +int zbd_do_io_u_trim(const struct thread_data *td, struct io_u
> *io_u);
>  
>  static inline void zbd_close_file(struct fio_file *f)
>  {


  reply	other threads:[~2021-08-03 19:36 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-28 10:47 [PATCH 0/4] zbd: Support zone reset by trim Shin'ichiro Kawasaki
2021-07-28 10:47 ` [PATCH 1/4] zbd: Add min_bytes argument to zbd_find_zone() Shin'ichiro Kawasaki
2021-08-03 19:35   ` Dmitry Fomichev
2021-07-28 10:47 ` [PATCH 2/4] zbd: Support zone reset by trim Shin'ichiro Kawasaki
2021-08-03 19:36   ` Dmitry Fomichev [this message]
2021-08-04  6:32     ` Shinichiro Kawasaki
2021-08-04 19:23       ` Dmitry Fomichev
2021-07-28 10:47 ` [PATCH 3/4] engines/libzbc: Enable trim for libzbc I/O engine Shin'ichiro Kawasaki
2021-08-03 19:36   ` Dmitry Fomichev
2021-08-04  6:39     ` Shinichiro Kawasaki
2021-08-04 19:29       ` Dmitry Fomichev
2021-08-05  3:32         ` Shinichiro Kawasaki
2021-07-28 10:47 ` [PATCH 4/4] t/zbd: Add test #58 to test zone reset by trim workload Shin'ichiro Kawasaki
2021-08-03 19:36   ` Dmitry Fomichev
  -- strict thread matches above, loose matches on Subject: below --
2021-07-06  0:59 [PATCH 0/4] zbd: Support zone reset by trim Shin'ichiro Kawasaki
2021-07-06  0:59 ` [PATCH 2/4] " Shin'ichiro Kawasaki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c64f93bcd740905a63ef4b8eeb05a13bdd67d275.camel@wdc.com \
    --to=dmitry.fomichev@wdc.com \
    --cc=Damien.LeMoal@wdc.com \
    --cc=Niklas.Cassel@wdc.com \
    --cc=axboe@kernel.dk \
    --cc=fio@vger.kernel.org \
    --cc=shinichiro.kawasaki@wdc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).