Re: [PATCH 4/7] zbd: fix write zone accounting of trim workload

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jun 07, 2023 at 05:32:27PM +0900, Shin'ichiro Kawasaki wrote:
> The commit e3be810bf0fd ("zbd: Support zone reset by trim") supported
> trim for zonemode=zbd by introducing the function zbd_do_io_u_trim(),
> which calls zbd_reset_zone(). However, it did not call
> zbd_write_zone_put() to the trim target zone, then trim operation
> resulted in wrong accounting of write zones.
> 
> To fix the issue, call zbd_write_zone_put() from zbd_reset_zone(). To
> cover the case to reset zones without a zbd_write_zone_put() call,
> prepare another function __zbd_reset_zone(). While at it, simplify
> zbd_reset_zones() by calling the modified zbd_reset_zone().
> 
> Of note is that the constifier of the argument td of do_io_u_trim() is
> removed since zbd_write_zone_put() requires changes in that argument.
> 
> Fixes: e3be810bf0fd ("zbd: Support zone reset by trim")
> Suggested-by: Niklas Cassel <niklas.cassel@xxxxxxx>
> Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx>
> ---
>  engines/io_uring.c |  2 +-
>  io_u.c             |  2 +-
>  io_u.h             |  2 +-
>  zbd.c              | 40 ++++++++++++++++++++++++++++++++--------
>  zbd.h              |  2 +-
>  5 files changed, 36 insertions(+), 12 deletions(-)
> 
> diff --git a/engines/io_uring.c b/engines/io_uring.c
> index ff64fc9f..73e4a27a 100644
> --- a/engines/io_uring.c
> +++ b/engines/io_uring.c
> @@ -561,7 +561,7 @@ static inline void fio_ioring_cmdprio_prep(struct thread_data *td,
>  		ld->sqes[io_u->index].ioprio = io_u->ioprio;
>  }
>  
> -static int fio_ioring_cmd_io_u_trim(const struct thread_data *td,
> +static int fio_ioring_cmd_io_u_trim(struct thread_data *td,
>  				    struct io_u *io_u)
>  {
>  	struct fio_file *f = io_u->file;
> diff --git a/io_u.c b/io_u.c
> index 6f5fc94d..faf512e5 100644
> --- a/io_u.c
> +++ b/io_u.c
> @@ -2379,7 +2379,7 @@ int do_io_u_sync(const struct thread_data *td, struct io_u *io_u)
>  	return ret;
>  }
>  
> -int do_io_u_trim(const struct thread_data *td, struct io_u *io_u)
> +int do_io_u_trim(struct thread_data *td, struct io_u *io_u)
>  {
>  #ifndef FIO_HAVE_TRIM
>  	io_u->error = EINVAL;
> diff --git a/io_u.h b/io_u.h
> index 55b4d083..b432a540 100644
> --- a/io_u.h
> +++ b/io_u.h
> @@ -162,7 +162,7 @@ void io_u_mark_submit(struct thread_data *, unsigned int);
>  bool queue_full(const struct thread_data *);
>  
>  int do_io_u_sync(const struct thread_data *, struct io_u *);
> -int do_io_u_trim(const struct thread_data *, struct io_u *);
> +int do_io_u_trim(struct thread_data *, struct io_u *);
>  
>  #ifdef FIO_INC_DEBUG
>  static inline void dprint_io_u(struct io_u *io_u, const char *p)
> diff --git a/zbd.c b/zbd.c
> index 36b68d62..7eef49c6 100644
> --- a/zbd.c
> +++ b/zbd.c
> @@ -254,7 +254,7 @@ static int zbd_reset_wp(struct thread_data *td, struct fio_file *f,
>  }
>  
>  /**
> - * zbd_reset_zone - reset the write pointer of a single zone
> + * __zbd_reset_zone - reset the write pointer of a single zone
>   * @td: FIO thread data.
>   * @f: FIO file associated with the disk for which to reset a write pointer.
>   * @z: Zone to reset.
> @@ -263,8 +263,8 @@ static int zbd_reset_wp(struct thread_data *td, struct fio_file *f,
>   *
>   * The caller must hold z->mutex.
>   */
> -static int zbd_reset_zone(struct thread_data *td, struct fio_file *f,
> -			  struct fio_zone_info *z)
> +static int __zbd_reset_zone(struct thread_data *td, struct fio_file *f,
> +			    struct fio_zone_info *z)
>  {
>  	uint64_t offset = z->start;
>  	uint64_t length = (z+1)->start - offset;
> @@ -339,6 +339,33 @@ static void zbd_write_zone_put(struct thread_data *td, const struct fio_file *f,
>  	z->write = 0;
>  }
>  
> +/**
> + * zbd_reset_zone - reset the write pointer of a single zone and remove the zone
> + *                  from the array of write zones.
> + * @td: FIO thread data.
> + * @f: FIO file associated with the disk for which to reset a write pointer.
> + * @z: Zone to reset.
> + *
> + * Returns 0 upon success and a negative error code upon failure.

Please add an empty line before the "The caller must hold z->mutex" line,
such that we are consistent with other functions, e.g. __zbd_reset_zone().

> + * The caller must hold z->mutex.
> + */
> +static int zbd_reset_zone(struct thread_data *td, struct fio_file *f,
> +			  struct fio_zone_info *z)
> +{
> +	int ret;
> +
> +	ret = __zbd_reset_zone(td, f, z);
> +	if (ret)
> +		goto done;
> +
> +	pthread_mutex_lock(&f->zbd_info->mutex);
> +	zbd_write_zone_put(td, f, z);
> +	pthread_mutex_unlock(&f->zbd_info->mutex);
> +
> +done:
> +	return ret;
> +}
> +
>  /**
>   * zbd_finish_zone - finish the specified zone
>   * @td: FIO thread data.
> @@ -404,9 +431,6 @@ static int zbd_reset_zones(struct thread_data *td, struct fio_file *f,
>  			continue;
>  
>  		zone_lock(td, f, z);
> -		pthread_mutex_lock(&f->zbd_info->mutex);
> -		zbd_write_zone_put(td, f, z);
> -		pthread_mutex_unlock(&f->zbd_info->mutex);
>  
>  		if (z->wp != z->start) {
>  			dprint(FD_ZBD, "%s: resetting zone %u\n",
> @@ -2048,7 +2072,7 @@ retry:
>  			 */
>  			io_u_quiesce(td);
>  			zb->reset_zone = 0;
> -			if (zbd_reset_zone(td, f, zb) < 0)
> +			if (__zbd_reset_zone(td, f, zb) < 0)

Since you remove the zbd_write_zone_put() call, which I think is good,
I think that you should continue to call zbd_reset_zone() here.

>  				goto eof;
>  
>  			if (zb->capacity < min_bs) {
> @@ -2167,7 +2191,7 @@ char *zbd_write_status(const struct thread_stat *ts)
>   * 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)
> +int zbd_do_io_u_trim(struct thread_data *td, struct io_u *io_u)
>  {
>  	struct fio_file *f = io_u->file;
>  	struct fio_zone_info *z;
> diff --git a/zbd.h b/zbd.h
> index 25a3e0f1..f0ac9876 100644
> --- a/zbd.h
> +++ b/zbd.h
> @@ -100,7 +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);
> +int zbd_do_io_u_trim(struct thread_data *td, struct io_u *io_u);
>  
>  static inline void zbd_close_file(struct fio_file *f)
>  {
> -- 
> 2.40.1
> 



[Index of Archives]     [Linux Kernel]     [Linux SCSI]     [Linux IDE]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux