dm zoned: select reclaim zone based on device index
authorHannes Reinecke <hare@suse.de>
Tue, 2 Jun 2020 11:09:54 +0000 (13:09 +0200)
committerMike Snitzer <snitzer@redhat.com>
Fri, 5 Jun 2020 18:59:53 +0000 (14:59 -0400)
per-device reclaim should select zones on that device only.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/dm-zoned-metadata.c
drivers/md/dm-zoned-reclaim.c
drivers/md/dm-zoned-target.c
drivers/md/dm-zoned.h

index 1a6cdab3e4efe544656d2766e1e39c19d413e20c..0cb90799b8ceaa783b8e09abfb26a5f840302e9a 100644 (file)
@@ -1938,7 +1938,7 @@ static void dmz_wait_for_reclaim(struct dmz_metadata *zmd, struct dm_zone *zone)
  * Select a cache or random write zone for reclaim.
  */
 static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd,
-                                                   bool idle)
+                                                   unsigned int idx, bool idle)
 {
        struct dm_zone *dzone = NULL;
        struct dm_zone *zone;
@@ -1948,24 +1948,17 @@ static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd,
        if (zmd->nr_cache) {
                zone_list = &zmd->map_cache_list;
                /* Try to relaim random zones, too, when idle */
-               if (idle && list_empty(zone_list)) {
-                       int i;
-
-                       for (i = 1; i < zmd->nr_devs; i++) {
-                               zone_list = &zmd->dev[i].map_rnd_list;
-                               if (!list_empty(zone_list))
-                                       break;
-                       }
-               }
-       } else {
-               /* Otherwise the random zones are on the first disk */
-               zone_list = &zmd->dev[0].map_rnd_list;
-       }
+               if (idle && list_empty(zone_list))
+                       zone_list = &zmd->dev[idx].map_rnd_list;
+       } else
+               zone_list = &zmd->dev[idx].map_rnd_list;
 
        list_for_each_entry(zone, zone_list, link) {
-               if (dmz_is_buf(zone))
+               if (dmz_is_buf(zone)) {
                        dzone = zone->bzone;
-               else
+                       if (dzone->dev->dev_idx != idx)
+                               continue;
+               } else
                        dzone = zone;
                if (dmz_lock_zone_reclaim(dzone))
                        return dzone;
@@ -1977,20 +1970,16 @@ static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd,
 /*
  * Select a buffered sequential zone for reclaim.
  */
-static struct dm_zone *dmz_get_seq_zone_for_reclaim(struct dmz_metadata *zmd)
+static struct dm_zone *dmz_get_seq_zone_for_reclaim(struct dmz_metadata *zmd,
+                                                   unsigned int idx)
 {
        struct dm_zone *zone;
-       int i;
-
-       for (i = 0; i < zmd->nr_devs; i++) {
-               struct dmz_dev *dev = &zmd->dev[i];
 
-               list_for_each_entry(zone, &dev->map_seq_list, link) {
-                       if (!zone->bzone)
-                               continue;
-                       if (dmz_lock_zone_reclaim(zone))
-                               return zone;
-               }
+       list_for_each_entry(zone, &zmd->dev[idx].map_seq_list, link) {
+               if (!zone->bzone)
+                       continue;
+               if (dmz_lock_zone_reclaim(zone))
+                       return zone;
        }
 
        return NULL;
@@ -1999,7 +1988,8 @@ static struct dm_zone *dmz_get_seq_zone_for_reclaim(struct dmz_metadata *zmd)
 /*
  * Select a zone for reclaim.
  */
-struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd, bool idle)
+struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd,
+                                        unsigned int dev_idx, bool idle)
 {
        struct dm_zone *zone;
 
@@ -2013,9 +2003,9 @@ struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd, bool idle)
         */
        dmz_lock_map(zmd);
        if (list_empty(&zmd->reserved_seq_zones_list))
-               zone = dmz_get_seq_zone_for_reclaim(zmd);
+               zone = dmz_get_seq_zone_for_reclaim(zmd, dev_idx);
        else
-               zone = dmz_get_rnd_zone_for_reclaim(zmd, idle);
+               zone = dmz_get_rnd_zone_for_reclaim(zmd, dev_idx, idle);
        dmz_unlock_map(zmd);
 
        return zone;
index 5a04e34d17a97315e5ba92bce744948d3aa77a28..2261b4dd60b749318776e537e127ba2c8865365f 100644 (file)
@@ -370,7 +370,8 @@ static int dmz_do_reclaim(struct dmz_reclaim *zrc)
        int ret;
 
        /* Get a data zone */
-       dzone = dmz_get_zone_for_reclaim(zmd, dmz_target_idle(zrc));
+       dzone = dmz_get_zone_for_reclaim(zmd, zrc->dev_idx,
+                                        dmz_target_idle(zrc));
        if (!dzone) {
                DMDEBUG("(%s/%u): No zone found to reclaim",
                        dmz_metadata_label(zmd), zrc->dev_idx);
index fc30c78dffdb2d2e6bc42ca91523d6b365dd0b36..a907a9446c0b5c9eec4315802890dd0cbf5d864b 100644 (file)
@@ -738,6 +738,7 @@ static int dmz_get_zoned_device(struct dm_target *ti, char *path,
                dev = &dmz->dev[idx];
        }
        dev->bdev = bdev;
+       dev->dev_idx = idx;
        (void)bdevname(dev->bdev, dev->name);
 
        dev->capacity = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
index ec020bb1caf75b1c5cff3c1e452e333a49aafcae..22f11440b423bc23655dbc253b68d1f75c690cd0 100644 (file)
@@ -61,6 +61,8 @@ struct dmz_dev {
 
        sector_t                capacity;
 
+       unsigned int            dev_idx;
+
        unsigned int            nr_zones;
        unsigned int            zone_offset;
 
@@ -243,7 +245,8 @@ static inline void dmz_activate_zone(struct dm_zone *zone)
 
 int dmz_lock_zone_reclaim(struct dm_zone *zone);
 void dmz_unlock_zone_reclaim(struct dm_zone *zone);
-struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd, bool idle);
+struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd,
+                                        unsigned int dev_idx, bool idle);
 
 struct dm_zone *dmz_get_chunk_mapping(struct dmz_metadata *zmd,
                                      unsigned int chunk, int op);