From 9b38bb4b1e6de47b379afaad2c707df639bb4dc7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 3 Dec 2019 10:39:04 +0100 Subject: block: simplify blkdev_nr_zones Simplify the arguments to blkdev_nr_zones by passing a gendisk instead of the block_device and capacity. This also removes the need for __blkdev_nr_zones as all callers are outside the fast path and can deal with the additional branch. Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include/linux/blkdev.h') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 6012e2592628..c5852de402b6 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -357,8 +357,7 @@ typedef int (*report_zones_cb)(struct blk_zone *zone, unsigned int idx, #define BLK_ALL_ZONES ((unsigned int)-1) int blkdev_report_zones(struct block_device *bdev, sector_t sector, unsigned int nr_zones, report_zones_cb cb, void *data); - -extern unsigned int blkdev_nr_zones(struct block_device *bdev); +unsigned int blkdev_nr_zones(struct gendisk *disk); extern int blkdev_zone_mgmt(struct block_device *bdev, enum req_opf op, sector_t sectors, sector_t nr_sectors, gfp_t gfp_mask); @@ -371,7 +370,7 @@ extern int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode, #else /* CONFIG_BLK_DEV_ZONED */ -static inline unsigned int blkdev_nr_zones(struct block_device *bdev) +static inline unsigned int blkdev_nr_zones(struct gendisk *disk) { return 0; } -- cgit v1.2.3 From f216fdd77b5654f8c4f6fac6020d6aabc58878ef Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 3 Dec 2019 10:39:05 +0100 Subject: block: replace seq_zones_bitmap with conv_zones_bitmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Invert the meaning of seq_zones_bitmap by keeping a bitmap of conventional zones. This allows not having a bitmap for devices that do not have conventional zones. Reviewed-by: Javier González Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- block/blk-zoned.c | 18 +++++++++--------- include/linux/blkdev.h | 14 ++++++++------ 2 files changed, 17 insertions(+), 15 deletions(-) (limited to 'include/linux/blkdev.h') diff --git a/block/blk-zoned.c b/block/blk-zoned.c index 65a9bdc9fe27..9c3931051f4f 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -332,15 +332,15 @@ static inline unsigned long *blk_alloc_zone_bitmap(int node, void blk_queue_free_zone_bitmaps(struct request_queue *q) { - kfree(q->seq_zones_bitmap); - q->seq_zones_bitmap = NULL; + kfree(q->conv_zones_bitmap); + q->conv_zones_bitmap = NULL; kfree(q->seq_zones_wlock); q->seq_zones_wlock = NULL; } struct blk_revalidate_zone_args { struct gendisk *disk; - unsigned long *seq_zones_bitmap; + unsigned long *conv_zones_bitmap; unsigned long *seq_zones_wlock; sector_t sector; }; @@ -394,8 +394,8 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx, return -ENODEV; } - if (zone->type != BLK_ZONE_TYPE_CONVENTIONAL) - set_bit(idx, args->seq_zones_bitmap); + if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) + set_bit(idx, args->conv_zones_bitmap); args->sector += zone->len; return 0; @@ -415,8 +415,8 @@ static int blk_update_zone_info(struct gendisk *disk, unsigned int nr_zones, args->seq_zones_wlock = blk_alloc_zone_bitmap(q->node, nr_zones); if (!args->seq_zones_wlock) return -ENOMEM; - args->seq_zones_bitmap = blk_alloc_zone_bitmap(q->node, nr_zones); - if (!args->seq_zones_bitmap) + args->conv_zones_bitmap = blk_alloc_zone_bitmap(q->node, nr_zones); + if (!args->conv_zones_bitmap) return -ENOMEM; ret = disk->fops->report_zones(disk, 0, nr_zones, @@ -465,7 +465,7 @@ int blk_revalidate_disk_zones(struct gendisk *disk) if (ret >= 0) { q->nr_zones = nr_zones; swap(q->seq_zones_wlock, args.seq_zones_wlock); - swap(q->seq_zones_bitmap, args.seq_zones_bitmap); + swap(q->conv_zones_bitmap, args.conv_zones_bitmap); ret = 0; } else { pr_warn("%s: failed to revalidate zones\n", disk->disk_name); @@ -474,7 +474,7 @@ int blk_revalidate_disk_zones(struct gendisk *disk) blk_mq_unfreeze_queue(q); kfree(args.seq_zones_wlock); - kfree(args.seq_zones_bitmap); + kfree(args.conv_zones_bitmap); return ret; } EXPORT_SYMBOL_GPL(blk_revalidate_disk_zones); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index c5852de402b6..503c4d4c5884 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -503,9 +503,9 @@ struct request_queue { /* * Zoned block device information for request dispatch control. * nr_zones is the total number of zones of the device. This is always - * 0 for regular block devices. seq_zones_bitmap is a bitmap of nr_zones - * bits which indicates if a zone is conventional (bit clear) or - * sequential (bit set). seq_zones_wlock is a bitmap of nr_zones + * 0 for regular block devices. conv_zones_bitmap is a bitmap of nr_zones + * bits which indicates if a zone is conventional (bit set) or + * sequential (bit clear). seq_zones_wlock is a bitmap of nr_zones * bits which indicates if a zone is write locked, that is, if a write * request targeting the zone was dispatched. All three fields are * initialized by the low level device driver (e.g. scsi/sd.c). @@ -518,7 +518,7 @@ struct request_queue { * blk_mq_unfreeze_queue(). */ unsigned int nr_zones; - unsigned long *seq_zones_bitmap; + unsigned long *conv_zones_bitmap; unsigned long *seq_zones_wlock; #endif /* CONFIG_BLK_DEV_ZONED */ @@ -723,9 +723,11 @@ static inline unsigned int blk_queue_zone_no(struct request_queue *q, static inline bool blk_queue_zone_is_seq(struct request_queue *q, sector_t sector) { - if (!blk_queue_is_zoned(q) || !q->seq_zones_bitmap) + if (!blk_queue_is_zoned(q)) return false; - return test_bit(blk_queue_zone_no(q, sector), q->seq_zones_bitmap); + if (!q->conv_zones_bitmap) + return true; + return !test_bit(blk_queue_zone_no(q, sector), q->conv_zones_bitmap); } #else /* CONFIG_BLK_DEV_ZONED */ static inline unsigned int blk_queue_nr_zones(struct request_queue *q) -- cgit v1.2.3 From ae58954d8734c44298f55ed71e683ea944994fab Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 3 Dec 2019 10:39:07 +0100 Subject: block: don't handle bio based drivers in blk_revalidate_disk_zones MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bio based drivers only need to update q->nr_zones. Do that manually instead of overloading blk_revalidate_disk_zones to keep that function simpler for the next round of changes that will rely even more on the request based functionality. Reviewed-by: Javier González Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- block/blk-zoned.c | 16 +++++----------- drivers/block/null_blk_main.c | 12 +++++++++--- drivers/md/dm-table.c | 12 +++++++----- include/linux/blkdev.h | 5 ----- 4 files changed, 21 insertions(+), 24 deletions(-) (limited to 'include/linux/blkdev.h') diff --git a/block/blk-zoned.c b/block/blk-zoned.c index 0131f9e14bd1..51d427659ce7 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -419,8 +419,9 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx, * * Helper function for low-level device drivers to (re) allocate and initialize * a disk request queue zone bitmaps. This functions should normally be called - * within the disk ->revalidate method. For BIO based queues, no zone bitmap - * is allocated. + * within the disk ->revalidate method for blk-mq based drivers. For BIO based + * drivers only q->nr_zones needs to be updated so that the sysfs exposed value + * is correct. */ int blk_revalidate_disk_zones(struct gendisk *disk) { @@ -433,15 +434,8 @@ int blk_revalidate_disk_zones(struct gendisk *disk) if (WARN_ON_ONCE(!blk_queue_is_zoned(q))) return -EIO; - - /* - * BIO based queues do not use a scheduler so only q->nr_zones - * needs to be updated so that the sysfs exposed value is correct. - */ - if (!queue_is_mq(q)) { - q->nr_zones = args.nr_zones; - return 0; - } + if (WARN_ON_ONCE(!queue_is_mq(q))) + return -EIO; /* * Ensure that all memory allocations in this context are done as diff --git a/drivers/block/null_blk_main.c b/drivers/block/null_blk_main.c index dd6026289fbf..068cd0ae6e2c 100644 --- a/drivers/block/null_blk_main.c +++ b/drivers/block/null_blk_main.c @@ -1576,11 +1576,17 @@ static int null_gendisk_register(struct nullb *nullb) disk->queue = nullb->q; strncpy(disk->disk_name, nullb->disk_name, DISK_NAME_LEN); +#ifdef CONFIG_BLK_DEV_ZONED if (nullb->dev->zoned) { - ret = blk_revalidate_disk_zones(disk); - if (ret) - return ret; + if (queue_is_mq(nullb->q)) { + ret = blk_revalidate_disk_zones(disk); + if (ret) + return ret; + } else { + nullb->q->nr_zones = blkdev_nr_zones(disk); + } } +#endif add_disk(disk); return 0; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 2ae0c1913766..0a2cc197f62b 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1954,12 +1954,14 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, /* * For a zoned target, the number of zones should be updated for the * correct value to be exposed in sysfs queue/nr_zones. For a BIO based - * target, this is all that is needed. For a request based target, the - * queue zone bitmaps must also be updated. - * Use blk_revalidate_disk_zones() to handle this. + * target, this is all that is needed. */ - if (blk_queue_is_zoned(q)) - blk_revalidate_disk_zones(t->md->disk); +#ifdef CONFIG_BLK_DEV_ZONED + if (blk_queue_is_zoned(q)) { + WARN_ON_ONCE(queue_is_mq(q)); + q->nr_zones = blkdev_nr_zones(t->md->disk); + } +#endif /* Allow reads to exceed readahead limits */ q->backing_dev_info->io_pages = limits->max_sectors >> (PAGE_SHIFT - 9); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 503c4d4c5884..47eb22a3b7f9 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -375,11 +375,6 @@ static inline unsigned int blkdev_nr_zones(struct gendisk *disk) return 0; } -static inline int blk_revalidate_disk_zones(struct gendisk *disk) -{ - return 0; -} - static inline int blkdev_report_zones_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) -- cgit v1.2.3