Skip to content

Commit 3ee3957

Browse files
damien-lemoalsnitm
authored andcommitted
dm zoned: Fix random zone reclaim selection
Commit 2094045 ("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: 2094045 ("dm zoned: prefer full zones for reclaim") Signed-off-by: Damien Le Moal <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent 415c79e commit 3ee3957

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

drivers/md/dm-zoned-metadata.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,7 +1950,7 @@ static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd,
19501950
unsigned int idx, bool idle)
19511951
{
19521952
struct dm_zone *dzone = NULL;
1953-
struct dm_zone *zone, *last = NULL;
1953+
struct dm_zone *zone, *maxw_z = NULL;
19541954
struct list_head *zone_list;
19551955

19561956
/* If we have cache zones select from the cache zone list */
@@ -1962,18 +1962,37 @@ static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd,
19621962
} else
19631963
zone_list = &zmd->dev[idx].map_rnd_list;
19641964

1965+
/*
1966+
* Find the buffer zone with the heaviest weight or the first (oldest)
1967+
* data zone that can be reclaimed.
1968+
*/
19651969
list_for_each_entry(zone, zone_list, link) {
19661970
if (dmz_is_buf(zone)) {
19671971
dzone = zone->bzone;
1968-
if (dzone->dev->dev_idx != idx)
1972+
if (dmz_is_rnd(dzone) && dzone->dev->dev_idx != idx)
19691973
continue;
1970-
if (!last) {
1971-
last = dzone;
1972-
continue;
1973-
}
1974-
if (last->weight < dzone->weight)
1974+
if (!maxw_z || maxw_z->weight < dzone->weight)
1975+
maxw_z = dzone;
1976+
} else {
1977+
dzone = zone;
1978+
if (dmz_lock_zone_reclaim(dzone))
1979+
return dzone;
1980+
}
1981+
}
1982+
1983+
if (maxw_z && dmz_lock_zone_reclaim(maxw_z))
1984+
return maxw_z;
1985+
1986+
/*
1987+
* If we come here, none of the zones inspected could be locked for
1988+
* reclaim. Try again, being more aggressive, that is, find the
1989+
* first zone that can be reclaimed regardless of its weitght.
1990+
*/
1991+
list_for_each_entry(zone, zone_list, link) {
1992+
if (dmz_is_buf(zone)) {
1993+
dzone = zone->bzone;
1994+
if (dmz_is_rnd(dzone) && dzone->dev->dev_idx != idx)
19751995
continue;
1976-
dzone = last;
19771996
} else
19781997
dzone = zone;
19791998
if (dmz_lock_zone_reclaim(dzone))

0 commit comments

Comments
 (0)