[dm-devel] [PATCH 1/2] dm zoned: Fix random zone reclaim selection
Hannes Reinecke
hare at suse.de
Fri Jun 19 08:07:24 UTC 2020
On 6/19/20 9:49 AM, Damien Le Moal wrote:
> Commit 2094045fe5b5 ("dm zoned: prefer full zones for reclaim")
> modified dmz_get_rnd_zone_for_reclaim() to add a search for the buffer
> zone with the heaviest weight as an optimal candidate for reclaim. This
> modification uses the zone pointer variabl "last" which is set only once
> and never modified as zones are scanned, resulting in the search being
> inefective. Furthermore, if the selected buffer zone at the end of the
> search loop is active or already locked for reclaim,
> dmz_get_rnd_zone_for_reclaim() returns NULL even if other random zones
> with a lesser weight can be reclaimed.
>
> To fix the search and to guarantee that reclaim can make forward
> progress, fix dmz_get_rnd_zone_for_reclaim() loop to correctly find
> the buffer zone with the heaviest weight using the variable maxw_z.
> Also make sure to fallback to finding the first random zone that can
> be reclaimed if this best candidate zone cannot be reclaimed.
>
> While at it, also fix the device index check to consider only random
> zones, ignoring cache zones belonging to the cache device if one is
> used as that device does not have a reclaim process.
>
> Fixes: 2094045fe5b5 ("dm zoned: prefer full zones for reclaim")
> Signed-off-by: Damien Le Moal <damien.lemoal at wdc.com>
> ---
> drivers/md/dm-zoned-metadata.c | 35 ++++++++++++++++++++++++++--------
> 1 file changed, 27 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c
> index 130b5a6d9f12..8bdf71dce7fb 100644
> --- a/drivers/md/dm-zoned-metadata.c
> +++ b/drivers/md/dm-zoned-metadata.c
> @@ -1949,7 +1949,7 @@ static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd,
> unsigned int idx, bool idle)
> {
> struct dm_zone *dzone = NULL;
> - struct dm_zone *zone, *last = NULL;
> + struct dm_zone *zone, *maxw_z = NULL;
> struct list_head *zone_list;
>
> /* If we have cache zones select from the cache zone list */
> @@ -1961,18 +1961,37 @@ static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd,
> } else
> zone_list = &zmd->dev[idx].map_rnd_list;
>
> + /*
> + * Find the buffer zone with the heaviest weight or the first (oldest)
> + * data zone that can be reclaimed.
> + */
> list_for_each_entry(zone, zone_list, link) {
> if (dmz_is_buf(zone)) {
> dzone = zone->bzone;
> - if (dzone->dev->dev_idx != idx)
> + if (dmz_is_rnd(dzone) && dzone->dev->dev_idx != idx)
> continue;
> - if (!last) {
> - last = dzone;
> - continue;
> - }
> - if (last->weight < dzone->weight)
> + if (!maxw_z || maxw_z->weight < dzone->weight)
> + maxw_z = dzone;
> + } else {
> + dzone = zone;
> + if (dmz_lock_zone_reclaim(dzone))
> + return dzone;
> + }
> + }
> +
> + if (maxw_z && dmz_lock_zone_reclaim(maxw_z))
> + return maxw_z;
> +
> + /*
> + * If we come here, none of the zones inspected could be locked for
> + * reclaim. Try again, being more aggressive, that is, find the
> + * first zone that can be reclaimed regardless of its weitght.
> + */
> + list_for_each_entry(zone, zone_list, link) {
> + if (dmz_is_buf(zone)) {
> + dzone = zone->bzone;
> + if (dmz_is_rnd(dzone) && dzone->dev->dev_idx != idx)
> continue;
> - dzone = last;
> } else
> dzone = zone;
> if (dmz_lock_zone_reclaim(dzone))
>
I know it wasn't that easy. Thanks for the fix.
Reviewed-by: Hannes Reinecke <hare at suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
hare at suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer
More information about the dm-devel
mailing list