[dm-devel] [PATCH 1/3] dm-zoned: improve error handling in reclaim

Damien Le Moal Damien.LeMoal at wdc.com
Wed Aug 7 09:16:14 UTC 2019


On 2019/08/06 10:06, Dmitry Fomichev wrote:
> There are several places in reclaim code where errors are not
> propagated to the main function, dmz_reclaim(). This function
> is responsible for unlocking zones that might be still locked
> at the end of any failed reclaim iterations. As the result,
> some device zones may be left permanently locked for reclaim,
> degrading target's capability to reclaim zones.
> 
> This patch fixes these issues as follows -
> 
> Make sure that dmz_reclaim_buf(), dmz_reclaim_seq_data() and
> dmz_reclaim_rnd_data() return error codes to the caller.
> 
> dmz_reclaim() function is renamed to dmz_do_reclaim() to avoid
> clashing with "struct dmz_reclaim" and is modified to return the
> error to the caller.
> 
> dmz_get_zone_for_reclaim() now returns an error instead of NULL
> pointer and reclaim code checks for that error.
> 
> Error logging/debug messages are added where necessary.
> 
> Fixes: 3b1a94c88b79 ("dm zoned: drive-managed zoned block device target")
> Cc: stable at vger.kernel.org
> Signed-off-by: Dmitry Fomichev <dmitry.fomichev at wdc.com>
> ---
>  drivers/md/dm-zoned-metadata.c |  4 ++--
>  drivers/md/dm-zoned-reclaim.c  | 28 +++++++++++++++++++---------
>  2 files changed, 21 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c
> index ded4984d18c9..6b7fbbd735ef 100644
> --- a/drivers/md/dm-zoned-metadata.c
> +++ b/drivers/md/dm-zoned-metadata.c
> @@ -1543,7 +1543,7 @@ static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd)
>  	struct dm_zone *zone;
>  
>  	if (list_empty(&zmd->map_rnd_list))
> -		return NULL;
> +		return ERR_PTR(-EBUSY);
>  
>  	list_for_each_entry(zone, &zmd->map_rnd_list, link) {
>  		if (dmz_is_buf(zone))
> @@ -1554,7 +1554,7 @@ static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd)
>  			return dzone;
>  	}
>  
> -	return NULL;
> +	return ERR_PTR(-EBUSY);
>  }
>  
>  /*
> diff --git a/drivers/md/dm-zoned-reclaim.c b/drivers/md/dm-zoned-reclaim.c
> index 260e3598199e..26e34493a2db 100644
> --- a/drivers/md/dm-zoned-reclaim.c
> +++ b/drivers/md/dm-zoned-reclaim.c
> @@ -216,7 +216,7 @@ static int dmz_reclaim_buf(struct dmz_reclaim *zrc, struct dm_zone *dzone)
>  
>  	dmz_unlock_flush(zmd);
>  
> -	return 0;
> +	return ret;
>  }
>  
>  /*
> @@ -260,7 +260,7 @@ static int dmz_reclaim_seq_data(struct dmz_reclaim *zrc, struct dm_zone *dzone)
>  
>  	dmz_unlock_flush(zmd);
>  
> -	return 0;
> +	return ret;
>  }
>  
>  /*
> @@ -313,7 +313,7 @@ static int dmz_reclaim_rnd_data(struct dmz_reclaim *zrc, struct dm_zone *dzone)
>  
>  	dmz_unlock_flush(zmd);
>  
> -	return 0;
> +	return ret;
>  }
>  
>  /*
> @@ -335,7 +335,7 @@ static void dmz_reclaim_empty(struct dmz_reclaim *zrc, struct dm_zone *dzone)
>  /*
>   * Find a candidate zone for reclaim and process it.
>   */
> -static void dmz_reclaim(struct dmz_reclaim *zrc)
> +static int dmz_do_reclaim(struct dmz_reclaim *zrc)
>  {
>  	struct dmz_metadata *zmd = zrc->metadata;
>  	struct dm_zone *dzone;
> @@ -345,8 +345,8 @@ static void dmz_reclaim(struct dmz_reclaim *zrc)
>  
>  	/* Get a data zone */
>  	dzone = dmz_get_zone_for_reclaim(zmd);
> -	if (!dzone)
> -		return;
> +	if (IS_ERR(dzone))
> +		return PTR_ERR(dzone);
>  
>  	start = jiffies;
>  
> @@ -392,13 +392,20 @@ static void dmz_reclaim(struct dmz_reclaim *zrc)
>  out:
>  	if (ret) {
>  		dmz_unlock_zone_reclaim(dzone);
> -		return;
> +		return ret;
>  	}
>  
> -	(void) dmz_flush_metadata(zrc->metadata);
> +	ret = dmz_flush_metadata(zrc->metadata);
> +	if (ret) {
> +		dmz_dev_debug(zrc->dev,
> +			      "Metadata flush for zone %u failed, err %d\n",
> +			      dmz_id(zmd, rzone), ret);
> +		return ret;
> +	}
>  
>  	dmz_dev_debug(zrc->dev, "Reclaimed zone %u in %u ms",
>  		      dmz_id(zmd, rzone), jiffies_to_msecs(jiffies - start));
> +	return 0;
>  }
>  
>  /*
> @@ -443,6 +450,7 @@ static void dmz_reclaim_work(struct work_struct *work)
>  	struct dmz_metadata *zmd = zrc->metadata;
>  	unsigned int nr_rnd, nr_unmap_rnd;
>  	unsigned int p_unmap_rnd;
> +	int ret;
>  
>  	if (!dmz_should_reclaim(zrc)) {
>  		mod_delayed_work(zrc->wq, &zrc->work, DMZ_IDLE_PERIOD);
> @@ -472,7 +480,9 @@ static void dmz_reclaim_work(struct work_struct *work)
>  		      (dmz_target_idle(zrc) ? "Idle" : "Busy"),
>  		      p_unmap_rnd, nr_unmap_rnd, nr_rnd);
>  
> -	dmz_reclaim(zrc);
> +	ret = dmz_do_reclaim(zrc);
> +	if (ret)
> +		dmz_dev_debug(zrc->dev, "Reclaim error %d\n", ret);
>  
>  	dmz_schedule_reclaim(zrc);
>  }
> 

Reviewed-by: Damien Le Moal <damien.lemoal at wdc.com>

-- 
Damien Le Moal
Western Digital Research




More information about the dm-devel mailing list