From: Pankaj Raghav <p.raghav@samsung.com> To: axboe@kernel.dk, damien.lemoal@opensource.wdc.com, snitzer@redhat.com, Johannes.Thumshirn@wdc.com, hch@lst.de, hare@suse.de Cc: dsterba@suse.com, dm-devel@redhat.com, jiangbo.365@bytedance.com, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nvme@lists.infradead.org, jaegeuk@kernel.org, gost.dev@samsung.com, Pankaj Raghav <p.raghav@samsung.com>, Luis Chamberlain <mcgrof@kernel.org> Subject: [PATCH v6 2/8] block: allow blk-zoned devices to have non-power-of-2 zone size Date: Wed, 25 May 2022 17:49:51 +0200 [thread overview] Message-ID: <20220525154957.393656-3-p.raghav@samsung.com> (raw) In-Reply-To: <20220525154957.393656-1-p.raghav@samsung.com> Checking if a given sector is aligned to a zone is a common operation that is performed for zoned devices. Add blk_queue_is_zone_start helper to check for this instead of opencoding it everywhere. Convert the calculations on zone size to be generic instead of relying on power_of_2 based logic in the block layer using the helpers wherever possible. The only hot path affected by this change for power_of_2 zoned devices is in blk_check_zone_append() but blk_queue_is_zone_start() helper is used to optimize the calculation for po2 zone sizes. Note that the append path cannot be accessed by direct raw access to the block device but only through a filesystem abstraction. Finally, allow non power of 2 zoned devices provided that their zone capacity and zone size are equal. The main motivation to allow non power_of_2 zoned device is to remove the unmapped LBA between zcap and zsze for devices that cannot have a power_of_2 zcap. Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Pankaj Raghav <p.raghav@samsung.com> --- block/blk-core.c | 3 +-- block/blk-zoned.c | 25 +++++++++++++++++++------ include/linux/blkdev.h | 21 +++++++++++++++++++++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index bc0506772152..bf1eae142118 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -630,8 +630,7 @@ static inline blk_status_t blk_check_zone_append(struct request_queue *q, return BLK_STS_NOTSUPP; /* The bio sector must point to the start of a sequential zone */ - if (pos & (blk_queue_zone_sectors(q) - 1) || - !blk_queue_zone_is_seq(q, pos)) + if (!blk_queue_is_zone_start(q, pos) || !blk_queue_zone_is_seq(q, pos)) return BLK_STS_IOERR; /* diff --git a/block/blk-zoned.c b/block/blk-zoned.c index 8b0615287cd3..7957eec04ff6 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -288,10 +288,10 @@ int blkdev_zone_mgmt(struct block_device *bdev, enum req_opf op, return -EINVAL; /* Check alignment (handle eventual smaller last zone) */ - if (sector & (zone_sectors - 1)) + if (!blk_queue_is_zone_start(q, sector)) return -EINVAL; - if ((nr_sectors & (zone_sectors - 1)) && end_sector != capacity) + if (!blk_queue_is_zone_start(q, nr_sectors) && end_sector != capacity) return -EINVAL; /* @@ -489,14 +489,27 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx, * smaller last zone. */ if (zone->start == 0) { - if (zone->len == 0 || !is_power_of_2(zone->len)) { - pr_warn("%s: Invalid zoned device with non power of two zone size (%llu)\n", - disk->disk_name, zone->len); + if (zone->len == 0) { + pr_warn("%s: Invalid zone size", disk->disk_name); + return -ENODEV; + } + + /* + * Don't allow zoned device with non power_of_2 zone size with + * zone capacity less than zone size. + */ + if (!is_power_of_2(zone->len) && zone->capacity < zone->len) { + pr_warn("%s: Invalid zone capacity for non power of 2 zone size", + disk->disk_name); return -ENODEV; } args->zone_sectors = zone->len; - args->nr_zones = (capacity + zone->len - 1) >> ilog2(zone->len); + /* + * Division is used to calculate nr_zones for both power_of_2 + * and non power_of_2 zone sizes as it is not in the hot path. + */ + args->nr_zones = div64_u64(capacity + zone->len - 1, zone->len); } else if (zone->start + args->zone_sectors < capacity) { if (zone->len != args->zone_sectors) { pr_warn("%s: Invalid zoned device with non constant zone size\n", diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index c4e4c7071b7b..f5c7a41032ba 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -676,6 +676,21 @@ static inline unsigned int blk_queue_zone_no(struct request_queue *q, return div64_u64(sector, zone_sectors); } +static inline bool blk_queue_is_zone_start(struct request_queue *q, sector_t sec) +{ + sector_t zone_sectors = blk_queue_zone_sectors(q); + u64 remainder = 0; + + if (!blk_queue_is_zoned(q)) + return false; + + if (is_power_of_2(zone_sectors)) + return IS_ALIGNED(sec, zone_sectors); + + div64_u64_rem(sec, zone_sectors, &remainder); + return remainder == 0; +} + static inline bool blk_queue_zone_is_seq(struct request_queue *q, sector_t sector) { @@ -722,6 +737,12 @@ static inline unsigned int blk_queue_zone_no(struct request_queue *q, { return 0; } + +static inline bool blk_queue_is_zone_start(struct request_queue *q, sector_t sec) +{ + return false; +} + static inline unsigned int queue_max_open_zones(const struct request_queue *q) { return 0; -- 2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Pankaj Raghav <p.raghav@samsung.com> To: axboe@kernel.dk, damien.lemoal@opensource.wdc.com, snitzer@redhat.com, Johannes.Thumshirn@wdc.com, hch@lst.de, hare@suse.de Cc: Pankaj Raghav <p.raghav@samsung.com>, gost.dev@samsung.com, jiangbo.365@bytedance.com, linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, linux-block@vger.kernel.org, dm-devel@redhat.com, Luis Chamberlain <mcgrof@kernel.org>, dsterba@suse.com, jaegeuk@kernel.org Subject: [dm-devel] [PATCH v6 2/8] block: allow blk-zoned devices to have non-power-of-2 zone size Date: Wed, 25 May 2022 17:49:51 +0200 [thread overview] Message-ID: <20220525154957.393656-3-p.raghav@samsung.com> (raw) In-Reply-To: <20220525154957.393656-1-p.raghav@samsung.com> Checking if a given sector is aligned to a zone is a common operation that is performed for zoned devices. Add blk_queue_is_zone_start helper to check for this instead of opencoding it everywhere. Convert the calculations on zone size to be generic instead of relying on power_of_2 based logic in the block layer using the helpers wherever possible. The only hot path affected by this change for power_of_2 zoned devices is in blk_check_zone_append() but blk_queue_is_zone_start() helper is used to optimize the calculation for po2 zone sizes. Note that the append path cannot be accessed by direct raw access to the block device but only through a filesystem abstraction. Finally, allow non power of 2 zoned devices provided that their zone capacity and zone size are equal. The main motivation to allow non power_of_2 zoned device is to remove the unmapped LBA between zcap and zsze for devices that cannot have a power_of_2 zcap. Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Pankaj Raghav <p.raghav@samsung.com> --- block/blk-core.c | 3 +-- block/blk-zoned.c | 25 +++++++++++++++++++------ include/linux/blkdev.h | 21 +++++++++++++++++++++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index bc0506772152..bf1eae142118 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -630,8 +630,7 @@ static inline blk_status_t blk_check_zone_append(struct request_queue *q, return BLK_STS_NOTSUPP; /* The bio sector must point to the start of a sequential zone */ - if (pos & (blk_queue_zone_sectors(q) - 1) || - !blk_queue_zone_is_seq(q, pos)) + if (!blk_queue_is_zone_start(q, pos) || !blk_queue_zone_is_seq(q, pos)) return BLK_STS_IOERR; /* diff --git a/block/blk-zoned.c b/block/blk-zoned.c index 8b0615287cd3..7957eec04ff6 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -288,10 +288,10 @@ int blkdev_zone_mgmt(struct block_device *bdev, enum req_opf op, return -EINVAL; /* Check alignment (handle eventual smaller last zone) */ - if (sector & (zone_sectors - 1)) + if (!blk_queue_is_zone_start(q, sector)) return -EINVAL; - if ((nr_sectors & (zone_sectors - 1)) && end_sector != capacity) + if (!blk_queue_is_zone_start(q, nr_sectors) && end_sector != capacity) return -EINVAL; /* @@ -489,14 +489,27 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx, * smaller last zone. */ if (zone->start == 0) { - if (zone->len == 0 || !is_power_of_2(zone->len)) { - pr_warn("%s: Invalid zoned device with non power of two zone size (%llu)\n", - disk->disk_name, zone->len); + if (zone->len == 0) { + pr_warn("%s: Invalid zone size", disk->disk_name); + return -ENODEV; + } + + /* + * Don't allow zoned device with non power_of_2 zone size with + * zone capacity less than zone size. + */ + if (!is_power_of_2(zone->len) && zone->capacity < zone->len) { + pr_warn("%s: Invalid zone capacity for non power of 2 zone size", + disk->disk_name); return -ENODEV; } args->zone_sectors = zone->len; - args->nr_zones = (capacity + zone->len - 1) >> ilog2(zone->len); + /* + * Division is used to calculate nr_zones for both power_of_2 + * and non power_of_2 zone sizes as it is not in the hot path. + */ + args->nr_zones = div64_u64(capacity + zone->len - 1, zone->len); } else if (zone->start + args->zone_sectors < capacity) { if (zone->len != args->zone_sectors) { pr_warn("%s: Invalid zoned device with non constant zone size\n", diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index c4e4c7071b7b..f5c7a41032ba 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -676,6 +676,21 @@ static inline unsigned int blk_queue_zone_no(struct request_queue *q, return div64_u64(sector, zone_sectors); } +static inline bool blk_queue_is_zone_start(struct request_queue *q, sector_t sec) +{ + sector_t zone_sectors = blk_queue_zone_sectors(q); + u64 remainder = 0; + + if (!blk_queue_is_zoned(q)) + return false; + + if (is_power_of_2(zone_sectors)) + return IS_ALIGNED(sec, zone_sectors); + + div64_u64_rem(sec, zone_sectors, &remainder); + return remainder == 0; +} + static inline bool blk_queue_zone_is_seq(struct request_queue *q, sector_t sector) { @@ -722,6 +737,12 @@ static inline unsigned int blk_queue_zone_no(struct request_queue *q, { return 0; } + +static inline bool blk_queue_is_zone_start(struct request_queue *q, sector_t sec) +{ + return false; +} + static inline unsigned int queue_max_open_zones(const struct request_queue *q) { return 0; -- 2.25.1 -- dm-devel mailing list dm-devel@redhat.com https://listman.redhat.com/mailman/listinfo/dm-devel
next prev parent reply other threads:[~2022-05-25 15:50 UTC|newest] Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <CGME20220525154958eucas1p2f6af3db8ab178be28eb6c42e9e1be591@eucas1p2.samsung.com> 2022-05-25 15:49 ` [PATCH v6 0/8] support non power of 2 zoned devices Pankaj Raghav 2022-05-25 15:49 ` [dm-devel] " Pankaj Raghav [not found] ` <CGME20220525155000eucas1p200ac7e1c844980e728c9e88f51c4590e@eucas1p2.samsung.com> 2022-05-25 15:49 ` [PATCH v6 1/8] block: make blkdev_nr_zones and blk_queue_zone_no generic for npo2 zsze Pankaj Raghav 2022-05-25 15:49 ` [dm-devel] " Pankaj Raghav [not found] ` <CGME20220525155001eucas1p13e64a05367144fc6965f486bb07b55a2@eucas1p1.samsung.com> 2022-05-25 15:49 ` Pankaj Raghav [this message] 2022-05-25 15:49 ` [dm-devel] [PATCH v6 2/8] block: allow blk-zoned devices to have non-power-of-2 zone size Pankaj Raghav [not found] ` <CGME20220525155002eucas1p140ca05edf5219f38e8f1a45801c2ed62@eucas1p1.samsung.com> 2022-05-25 15:49 ` [PATCH v6 3/8] nvme: zns: Allow ZNS drives that have non-power_of_2 " Pankaj Raghav 2022-05-25 15:49 ` [dm-devel] " Pankaj Raghav [not found] ` <CGME20220525155004eucas1p162c6f43536424f93800ba788ed045363@eucas1p1.samsung.com> 2022-05-25 15:49 ` [PATCH v6 4/8] nvmet: Allow ZNS target to support non-power_of_2 zone sizes Pankaj Raghav 2022-05-25 15:49 ` [dm-devel] " Pankaj Raghav [not found] ` <CGME20220525155005eucas1p13b6204e84c2dbb1eeefc2645f69b45b0@eucas1p1.samsung.com> 2022-05-25 15:49 ` [PATCH v6 5/8] null_blk: allow non power of 2 zoned devices Pankaj Raghav 2022-05-25 15:49 ` [dm-devel] " Pankaj Raghav [not found] ` <CGME20220525155006eucas1p13888214b1d9e23a26d04a75fbc5bf72b@eucas1p1.samsung.com> 2022-05-25 15:49 ` [PATCH v6 6/8] null_blk: use zone_size_sects_shift for " Pankaj Raghav 2022-05-25 15:49 ` [dm-devel] " Pankaj Raghav [not found] ` <CGME20220525155007eucas1p1b7fc82f9e42be028e8f00109d55e6a62@eucas1p1.samsung.com> 2022-05-25 15:49 ` [PATCH v6 7/8] dm-zoned: ensure only power of 2 zone sizes are allowed Pankaj Raghav 2022-05-25 15:49 ` [dm-devel] " Pankaj Raghav [not found] ` <CGME20220525155008eucas1p2c843cc9098f2920e961f80ffaf535789@eucas1p2.samsung.com> 2022-05-25 15:49 ` [PATCH v6 8/8] dm: " Pankaj Raghav 2022-05-25 15:49 ` [dm-devel] " Pankaj Raghav 2022-05-25 23:13 ` Damien Le Moal 2022-05-25 23:13 ` [dm-devel] " Damien Le Moal 2022-05-26 8:12 ` Pankaj Raghav 2022-05-26 8:12 ` [dm-devel] " Pankaj Raghav 2022-05-26 8:25 ` Damien Le Moal 2022-05-26 8:25 ` [dm-devel] " Damien Le Moal 2022-05-30 14:59 ` Pankaj Raghav 2022-05-30 14:59 ` [dm-devel] " Pankaj Raghav
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220525154957.393656-3-p.raghav@samsung.com \ --to=p.raghav@samsung.com \ --cc=Johannes.Thumshirn@wdc.com \ --cc=axboe@kernel.dk \ --cc=damien.lemoal@opensource.wdc.com \ --cc=dm-devel@redhat.com \ --cc=dsterba@suse.com \ --cc=gost.dev@samsung.com \ --cc=hare@suse.de \ --cc=hch@lst.de \ --cc=jaegeuk@kernel.org \ --cc=jiangbo.365@bytedance.com \ --cc=linux-block@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-nvme@lists.infradead.org \ --cc=mcgrof@kernel.org \ --cc=snitzer@redhat.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.