mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
FROMLIST: null_blk: allow zoned devices with non power-of-2 zone sizes
Convert the power-of-2(po2) based calculation with zone size to be generic in null_zone_no with optimization for po2 zone sizes. The nr_zones calculation in null_init_zoned_dev has been replaced with a division without special handling for po2 zone sizes as this function is called only during the initialization and will not be invoked in the hot path. Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> Reviewed by: Adam Manzanares <a.manzanares@samsung.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Pankaj Raghav <p.raghav@samsung.com> Bug: 197782466 Bug: 269471019 Link: https://lore.kernel.org/linux-block/20220923173618.6899-7-p.raghav@samsung.com/ Change-Id: I8d1a915e6e09b04095acdf964d31837c4206bc49 Signed-off-by: Bart Van Assche <bvanassche@google.com>
This commit is contained in:
committed by
Treehugger Robot
parent
941c952c34
commit
5498feea6c
@@ -1770,9 +1770,8 @@ static int null_validate_conf(struct nullb_device *dev)
|
||||
if (dev->queue_mode == NULL_Q_BIO)
|
||||
dev->mbps = 0;
|
||||
|
||||
if (dev->zoned &&
|
||||
(!dev->zone_size || !is_power_of_2(dev->zone_size))) {
|
||||
pr_err("zone_size must be power-of-two\n");
|
||||
if (dev->zoned && !dev->zone_size) {
|
||||
pr_err("Invalid zero zone size\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ struct nullb_device {
|
||||
unsigned int imp_close_zone_no;
|
||||
struct nullb_zone *zones;
|
||||
sector_t zone_size_sects;
|
||||
unsigned int zone_size_sects_shift;
|
||||
bool need_zone_res_mgmt;
|
||||
spinlock_t zone_res_lock;
|
||||
|
||||
|
||||
@@ -13,7 +13,10 @@ static inline sector_t mb_to_sects(unsigned long mb)
|
||||
|
||||
static inline unsigned int null_zone_no(struct nullb_device *dev, sector_t sect)
|
||||
{
|
||||
return sect >> ilog2(dev->zone_size_sects);
|
||||
if (dev->zone_size_sects_shift)
|
||||
return sect >> dev->zone_size_sects_shift;
|
||||
|
||||
return div64_u64(sect, dev->zone_size_sects);
|
||||
}
|
||||
|
||||
static inline void null_lock_zone_res(struct nullb_device *dev)
|
||||
@@ -62,10 +65,6 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q)
|
||||
sector_t sector = 0;
|
||||
unsigned int i;
|
||||
|
||||
if (!is_power_of_2(dev->zone_size)) {
|
||||
pr_err("zone_size must be power-of-two\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (dev->zone_size > dev->size) {
|
||||
pr_err("Zone size larger than device capacity\n");
|
||||
return -EINVAL;
|
||||
@@ -83,9 +82,14 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q)
|
||||
zone_capacity_sects = mb_to_sects(dev->zone_capacity);
|
||||
dev_capacity_sects = mb_to_sects(dev->size);
|
||||
dev->zone_size_sects = mb_to_sects(dev->zone_size);
|
||||
dev->nr_zones = round_up(dev_capacity_sects, dev->zone_size_sects)
|
||||
>> ilog2(dev->zone_size_sects);
|
||||
|
||||
if (is_power_of_2(dev->zone_size_sects))
|
||||
dev->zone_size_sects_shift = ilog2(dev->zone_size_sects);
|
||||
else
|
||||
dev->zone_size_sects_shift = 0;
|
||||
|
||||
dev->nr_zones = DIV_ROUND_UP_SECTOR_T(dev_capacity_sects,
|
||||
dev->zone_size_sects);
|
||||
dev->zones = kvmalloc_array(dev->nr_zones, sizeof(struct nullb_zone),
|
||||
GFP_KERNEL | __GFP_ZERO);
|
||||
if (!dev->zones)
|
||||
|
||||
Reference in New Issue
Block a user