block: pass a queue_limits argument to blk_alloc_disk

Pass a queue_limits to blk_alloc_disk and apply it if non-NULL.  This
will allow allocating queues with valid queue limits instead of setting
the values one at a time later.

Also change blk_alloc_disk to return an ERR_PTR instead of just NULL
which can't distinguish errors.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Link: https://lore.kernel.org/r/20240215071055.2201424-2-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Christoph Hellwig 2024-02-15 08:10:47 +01:00 committed by Jens Axboe
parent 31edf4bbe0
commit 74fa8f9c55
18 changed files with 69 additions and 52 deletions

View File

@ -117,9 +117,11 @@ static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
dev->bsize = bsize; dev->bsize = bsize;
dev->bshift = ffs(bsize) - 10; dev->bshift = ffs(bsize) - 10;
dev->disk = blk_alloc_disk(NUMA_NO_NODE); dev->disk = blk_alloc_disk(NULL, NUMA_NO_NODE);
if (!dev->disk) if (IS_ERR(dev->disk)) {
err = PTR_ERR(dev->disk);
goto free_dev; goto free_dev;
}
dev->disk->major = major_num; dev->disk->major = major_num;
dev->disk->first_minor = dev_id * 16; dev->disk->first_minor = dev_id * 16;

View File

@ -264,16 +264,18 @@ static int __init simdisk_setup(struct simdisk *dev, int which,
struct proc_dir_entry *procdir) struct proc_dir_entry *procdir)
{ {
char tmp[2] = { '0' + which, 0 }; char tmp[2] = { '0' + which, 0 };
int err = -ENOMEM; int err;
dev->fd = -1; dev->fd = -1;
dev->filename = NULL; dev->filename = NULL;
spin_lock_init(&dev->lock); spin_lock_init(&dev->lock);
dev->users = 0; dev->users = 0;
dev->gd = blk_alloc_disk(NUMA_NO_NODE); dev->gd = blk_alloc_disk(NULL, NUMA_NO_NODE);
if (!dev->gd) if (IS_ERR(dev->gd)) {
err = PTR_ERR(dev->gd);
goto out; goto out;
}
dev->gd->major = simdisk_major; dev->gd->major = simdisk_major;
dev->gd->first_minor = which; dev->gd->first_minor = which;
dev->gd->minors = SIMDISK_MINORS; dev->gd->minors = SIMDISK_MINORS;

View File

@ -1391,20 +1391,21 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
return NULL; return NULL;
} }
struct gendisk *__blk_alloc_disk(int node, struct lock_class_key *lkclass) struct gendisk *__blk_alloc_disk(struct queue_limits *lim, int node,
struct lock_class_key *lkclass)
{ {
struct queue_limits lim = { }; struct queue_limits default_lim = { };
struct request_queue *q; struct request_queue *q;
struct gendisk *disk; struct gendisk *disk;
q = blk_alloc_queue(&lim, node); q = blk_alloc_queue(lim ? lim : &default_lim, node);
if (IS_ERR(q)) if (IS_ERR(q))
return NULL; return ERR_CAST(q);
disk = __alloc_disk_node(q, node, lkclass); disk = __alloc_disk_node(q, node, lkclass);
if (!disk) { if (!disk) {
blk_put_queue(q); blk_put_queue(q);
return NULL; return ERR_PTR(-ENOMEM);
} }
set_bit(GD_OWNS_QUEUE, &disk->state); set_bit(GD_OWNS_QUEUE, &disk->state);
return disk; return disk;

View File

@ -335,10 +335,11 @@ static int brd_alloc(int i)
debugfs_create_u64(buf, 0444, brd_debugfs_dir, debugfs_create_u64(buf, 0444, brd_debugfs_dir,
&brd->brd_nr_pages); &brd->brd_nr_pages);
disk = brd->brd_disk = blk_alloc_disk(NUMA_NO_NODE); disk = brd->brd_disk = blk_alloc_disk(NULL, NUMA_NO_NODE);
if (!disk) if (IS_ERR(disk)) {
err = PTR_ERR(disk);
goto out_free_dev; goto out_free_dev;
}
disk->major = RAMDISK_MAJOR; disk->major = RAMDISK_MAJOR;
disk->first_minor = i * max_part; disk->first_minor = i * max_part;
disk->minors = max_part; disk->minors = max_part;

View File

@ -2708,9 +2708,11 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
drbd_init_set_defaults(device); drbd_init_set_defaults(device);
disk = blk_alloc_disk(NUMA_NO_NODE); disk = blk_alloc_disk(NULL, NUMA_NO_NODE);
if (!disk) if (IS_ERR(disk)) {
err = PTR_ERR(disk);
goto out_no_disk; goto out_no_disk;
}
device->vdisk = disk; device->vdisk = disk;
device->rq_queue = disk->queue; device->rq_queue = disk->queue;

View File

@ -131,9 +131,11 @@ static int __init n64cart_probe(struct platform_device *pdev)
if (IS_ERR(reg_base)) if (IS_ERR(reg_base))
return PTR_ERR(reg_base); return PTR_ERR(reg_base);
disk = blk_alloc_disk(NUMA_NO_NODE); disk = blk_alloc_disk(NULL, NUMA_NO_NODE);
if (!disk) if (IS_ERR(disk)) {
err = PTR_ERR(disk);
goto out; goto out;
}
disk->first_minor = 0; disk->first_minor = 0;
disk->flags = GENHD_FL_NO_PART; disk->flags = GENHD_FL_NO_PART;

View File

@ -2154,10 +2154,11 @@ static int null_add_dev(struct nullb_device *dev)
} }
nullb->q = nullb->disk->queue; nullb->q = nullb->disk->queue;
} else if (dev->queue_mode == NULL_Q_BIO) { } else if (dev->queue_mode == NULL_Q_BIO) {
rv = -ENOMEM; nullb->disk = blk_alloc_disk(NULL, nullb->dev->home_node);
nullb->disk = blk_alloc_disk(nullb->dev->home_node); if (IS_ERR(nullb->disk)) {
if (!nullb->disk) rv = PTR_ERR(nullb->disk);
goto out_cleanup_queues; goto out_cleanup_queues;
}
nullb->q = nullb->disk->queue; nullb->q = nullb->disk->queue;
rv = init_driver_queues(nullb); rv = init_driver_queues(nullb);

View File

@ -2673,10 +2673,11 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
pd->write_congestion_on = write_congestion_on; pd->write_congestion_on = write_congestion_on;
pd->write_congestion_off = write_congestion_off; pd->write_congestion_off = write_congestion_off;
ret = -ENOMEM; disk = blk_alloc_disk(NULL, NUMA_NO_NODE);
disk = blk_alloc_disk(NUMA_NO_NODE); if (IS_ERR(disk)) {
if (!disk) ret = PTR_ERR(disk);
goto out_mem; goto out_mem;
}
pd->disk = disk; pd->disk = disk;
disk->major = pktdev_major; disk->major = pktdev_major;
disk->first_minor = idx; disk->first_minor = idx;

View File

@ -730,10 +730,10 @@ static int ps3vram_probe(struct ps3_system_bus_device *dev)
ps3vram_proc_init(dev); ps3vram_proc_init(dev);
gendisk = blk_alloc_disk(NUMA_NO_NODE); gendisk = blk_alloc_disk(NULL, NUMA_NO_NODE);
if (!gendisk) { if (IS_ERR(gendisk)) {
dev_err(&dev->core, "blk_alloc_disk failed\n"); dev_err(&dev->core, "blk_alloc_disk failed\n");
error = -ENOMEM; error = PTR_ERR(gendisk);
goto out_cache_cleanup; goto out_cache_cleanup;
} }

View File

@ -2195,11 +2195,11 @@ static int zram_add(void)
#endif #endif
/* gendisk structure */ /* gendisk structure */
zram->disk = blk_alloc_disk(NUMA_NO_NODE); zram->disk = blk_alloc_disk(NULL, NUMA_NO_NODE);
if (!zram->disk) { if (IS_ERR(zram->disk)) {
pr_err("Error allocating disk structure for device %d\n", pr_err("Error allocating disk structure for device %d\n",
device_id); device_id);
ret = -ENOMEM; ret = PTR_ERR(zram->disk);
goto out_free_idr; goto out_free_idr;
} }

View File

@ -935,8 +935,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size,
BIOSET_NEED_BVECS|BIOSET_NEED_RESCUER)) BIOSET_NEED_BVECS|BIOSET_NEED_RESCUER))
goto out_ida_remove; goto out_ida_remove;
d->disk = blk_alloc_disk(NUMA_NO_NODE); d->disk = blk_alloc_disk(NULL, NUMA_NO_NODE);
if (!d->disk) if (IS_ERR(d->disk))
goto out_bioset_exit; goto out_bioset_exit;
set_capacity(d->disk, sectors); set_capacity(d->disk, sectors);

View File

@ -2098,8 +2098,8 @@ static struct mapped_device *alloc_dev(int minor)
* established. If request-based table is loaded: blk-mq will * established. If request-based table is loaded: blk-mq will
* override accordingly. * override accordingly.
*/ */
md->disk = blk_alloc_disk(md->numa_node_id); md->disk = blk_alloc_disk(NULL, md->numa_node_id);
if (!md->disk) if (IS_ERR(md->disk))
goto bad; goto bad;
md->queue = md->disk->queue; md->queue = md->disk->queue;

View File

@ -5763,10 +5763,11 @@ struct mddev *md_alloc(dev_t dev, char *name)
*/ */
mddev->hold_active = UNTIL_STOP; mddev->hold_active = UNTIL_STOP;
error = -ENOMEM; disk = blk_alloc_disk(NULL, NUMA_NO_NODE);
disk = blk_alloc_disk(NUMA_NO_NODE); if (IS_ERR(disk)) {
if (!disk) error = PTR_ERR(disk);
goto out_free_mddev; goto out_free_mddev;
}
disk->major = MAJOR(mddev->unit); disk->major = MAJOR(mddev->unit);
disk->first_minor = unit << shift; disk->first_minor = unit << shift;

View File

@ -1496,11 +1496,11 @@ static int btt_blk_init(struct btt *btt)
{ {
struct nd_btt *nd_btt = btt->nd_btt; struct nd_btt *nd_btt = btt->nd_btt;
struct nd_namespace_common *ndns = nd_btt->ndns; struct nd_namespace_common *ndns = nd_btt->ndns;
int rc = -ENOMEM; int rc;
btt->btt_disk = blk_alloc_disk(NUMA_NO_NODE); btt->btt_disk = blk_alloc_disk(NULL, NUMA_NO_NODE);
if (!btt->btt_disk) if (IS_ERR(btt->btt_disk))
return -ENOMEM; return PTR_ERR(btt->btt_disk);
nvdimm_namespace_disk_name(ndns, btt->btt_disk->disk_name); nvdimm_namespace_disk_name(ndns, btt->btt_disk->disk_name);
btt->btt_disk->first_minor = 0; btt->btt_disk->first_minor = 0;

View File

@ -497,9 +497,9 @@ static int pmem_attach_disk(struct device *dev,
return -EBUSY; return -EBUSY;
} }
disk = blk_alloc_disk(nid); disk = blk_alloc_disk(NULL, nid);
if (!disk) if (IS_ERR(disk))
return -ENOMEM; return PTR_ERR(disk);
q = disk->queue; q = disk->queue;
pmem->disk = disk; pmem->disk = disk;

View File

@ -532,9 +532,9 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
!nvme_is_unique_nsid(ctrl, head) || !multipath) !nvme_is_unique_nsid(ctrl, head) || !multipath)
return 0; return 0;
head->disk = blk_alloc_disk(ctrl->numa_node); head->disk = blk_alloc_disk(NULL, ctrl->numa_node);
if (!head->disk) if (IS_ERR(head->disk))
return -ENOMEM; return PTR_ERR(head->disk);
head->disk->fops = &nvme_ns_head_ops; head->disk->fops = &nvme_ns_head_ops;
head->disk->private_data = head; head->disk->private_data = head;
sprintf(head->disk->disk_name, "nvme%dn%d", sprintf(head->disk->disk_name, "nvme%dn%d",

View File

@ -629,9 +629,9 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
dev_info->dev.release = dcssblk_release_segment; dev_info->dev.release = dcssblk_release_segment;
dev_info->dev.groups = dcssblk_dev_attr_groups; dev_info->dev.groups = dcssblk_dev_attr_groups;
INIT_LIST_HEAD(&dev_info->lh); INIT_LIST_HEAD(&dev_info->lh);
dev_info->gd = blk_alloc_disk(NUMA_NO_NODE); dev_info->gd = blk_alloc_disk(NULL, NUMA_NO_NODE);
if (dev_info->gd == NULL) { if (IS_ERR(dev_info->gd)) {
rc = -ENOMEM; rc = PTR_ERR(dev_info->gd);
goto seg_list_del; goto seg_list_del;
} }
dev_info->gd->major = dcssblk_major; dev_info->gd->major = dcssblk_major;

View File

@ -766,22 +766,26 @@ static inline u64 sb_bdev_nr_blocks(struct super_block *sb)
int bdev_disk_changed(struct gendisk *disk, bool invalidate); int bdev_disk_changed(struct gendisk *disk, bool invalidate);
void put_disk(struct gendisk *disk); void put_disk(struct gendisk *disk);
struct gendisk *__blk_alloc_disk(int node, struct lock_class_key *lkclass); struct gendisk *__blk_alloc_disk(struct queue_limits *lim, int node,
struct lock_class_key *lkclass);
/** /**
* blk_alloc_disk - allocate a gendisk structure * blk_alloc_disk - allocate a gendisk structure
* @lim: queue limits to be used for this disk.
* @node_id: numa node to allocate on * @node_id: numa node to allocate on
* *
* Allocate and pre-initialize a gendisk structure for use with BIO based * Allocate and pre-initialize a gendisk structure for use with BIO based
* drivers. * drivers.
* *
* Returns an ERR_PTR on error, else the allocated disk.
*
* Context: can sleep * Context: can sleep
*/ */
#define blk_alloc_disk(node_id) \ #define blk_alloc_disk(lim, node_id) \
({ \ ({ \
static struct lock_class_key __key; \ static struct lock_class_key __key; \
\ \
__blk_alloc_disk(node_id, &__key); \ __blk_alloc_disk(lim, node_id, &__key); \
}) })
int __register_blkdev(unsigned int major, const char *name, int __register_blkdev(unsigned int major, const char *name,