summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorDamien Le Moal <damien.lemoal@wdc.com>2020-11-20 10:55:15 +0900
committerJens Axboe <axboe@kernel.dk>2020-12-07 17:36:03 -0700
commit2e8c6e0e1d2d65562c637940747cfa30559f976a (patch)
tree7dbdf01e308099b11ea6ffd07be39ab4fcef2c9e /drivers/block
parent2b8b7ed7f3fc2b1536a0add3941ae159529d23bd (diff)
null_blk: Improve implicit zone close
When open zone resource management is enabled, that is, when a null_blk zoned device is created with zone_max_open different than 0, implicitly or explicitly opening a zone may require implicitly closing a zone that is already implicitly open. This operation is done using the function null_close_first_imp_zone(), which search for an implicitly open zone to close starting from the first sequential zone. This implementation is simple but may result in the same being constantly implicitly closed and then implicitly reopened on write, namely, the lowest numbered zone that is being written. Avoid this by starting the search for an implicitly open zone starting from the zone following the last zone that was implicitly closed. The function null_close_first_imp_zone() is renamed null_close_imp_open_zone(). Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/null_blk.h1
-rw-r--r--drivers/block/null_blk_zoned.c22
2 files changed, 18 insertions, 5 deletions
diff --git a/drivers/block/null_blk.h b/drivers/block/null_blk.h
index 14546ead1d66..29a8817fadfc 100644
--- a/drivers/block/null_blk.h
+++ b/drivers/block/null_blk.h
@@ -67,6 +67,7 @@ struct nullb_device {
unsigned int nr_zones_imp_open;
unsigned int nr_zones_exp_open;
unsigned int nr_zones_closed;
+ unsigned int imp_close_zone_no;
struct nullb_zone *zones;
sector_t zone_size_sects;
bool need_zone_res_mgmt;
diff --git a/drivers/block/null_blk_zoned.c b/drivers/block/null_blk_zoned.c
index 4d5c0b938618..4dad8748a61d 100644
--- a/drivers/block/null_blk_zoned.c
+++ b/drivers/block/null_blk_zoned.c
@@ -113,6 +113,7 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q)
pr_info("zone_max_open limit disabled, limit >= zone count\n");
}
dev->need_zone_res_mgmt = dev->zone_max_active || dev->zone_max_open;
+ dev->imp_close_zone_no = dev->zone_nr_conv;
for (i = 0; i < dev->zone_nr_conv; i++) {
zone = &dev->zones[i];
@@ -273,13 +274,24 @@ static blk_status_t __null_close_zone(struct nullb_device *dev,
return BLK_STS_OK;
}
-static void null_close_first_imp_zone(struct nullb_device *dev)
+static void null_close_imp_open_zone(struct nullb_device *dev)
{
- unsigned int i;
+ struct nullb_zone *zone;
+ unsigned int zno, i;
+
+ zno = dev->imp_close_zone_no;
+ if (zno >= dev->nr_zones)
+ zno = dev->zone_nr_conv;
for (i = dev->zone_nr_conv; i < dev->nr_zones; i++) {
- if (dev->zones[i].cond == BLK_ZONE_COND_IMP_OPEN) {
- __null_close_zone(dev, &dev->zones[i]);
+ zone = &dev->zones[zno];
+ zno++;
+ if (zno >= dev->nr_zones)
+ zno = dev->zone_nr_conv;
+
+ if (zone->cond == BLK_ZONE_COND_IMP_OPEN) {
+ __null_close_zone(dev, zone);
+ dev->imp_close_zone_no = zno;
return;
}
}
@@ -307,7 +319,7 @@ static blk_status_t null_check_open(struct nullb_device *dev)
if (dev->nr_zones_imp_open) {
if (null_check_active(dev) == BLK_STS_OK) {
- null_close_first_imp_zone(dev);
+ null_close_imp_open_zone(dev);
return BLK_STS_OK;
}
}