* drop bio mode from null_blk and convert it to atomic queue limits
@ 2024-02-14 9:54 Christoph Hellwig
2024-02-14 9:54 ` [PATCH 1/5] null_blk: remove the bio based I/O path Christoph Hellwig
` (5 more replies)
0 siblings, 6 replies; 20+ messages in thread
From: Christoph Hellwig @ 2024-02-14 9:54 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-block
Hi Jens,
this series drops the obsolete bio mode from the null_blk driver and
then converts the driver to pass the queue limits to blk_mq_alloc_disk.
Diffstat:
main.c | 500 +++++++++++++++----------------------------------------------
null_blk.h | 17 --
trace.h | 5
zoned.c | 17 --
4 files changed, 134 insertions(+), 405 deletions(-)
^ permalink raw reply [flat|nested] 20+ messages in thread* [PATCH 1/5] null_blk: remove the bio based I/O path 2024-02-14 9:54 drop bio mode from null_blk and convert it to atomic queue limits Christoph Hellwig @ 2024-02-14 9:54 ` Christoph Hellwig 2024-02-14 11:25 ` Damien Le Moal 2024-02-14 17:25 ` Keith Busch 2024-02-14 9:54 ` [PATCH 2/5] null_blk: initialize the tag_set timeout in null_init_tag_set Christoph Hellwig ` (4 subsequent siblings) 5 siblings, 2 replies; 20+ messages in thread From: Christoph Hellwig @ 2024-02-14 9:54 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block The bio based I/O path complicates null_blk and also make various data structures, including the per-command one way bigger than required for the main request based interface. As the bio-based path is mostly used by stacking drivers and simple memory based drivers, and brd is a good example driver for the latter there is no need to have a bio based path in null_blk. Remove the path to simplify the driver and make future block layer API changes simpler by not having to deal with the complex two API setup in null_blk. Signed-off-by: Christoph Hellwig <hch@lst.de> --- drivers/block/null_blk/main.c | 364 ++++++------------------------ drivers/block/null_blk/null_blk.h | 17 -- drivers/block/null_blk/trace.h | 5 +- drivers/block/null_blk/zoned.c | 10 +- 4 files changed, 69 insertions(+), 327 deletions(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index eeb895ec6f34ae..d6836327eefb42 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -115,6 +115,18 @@ module_param_string(init_hctx, g_init_hctx_str, sizeof(g_init_hctx_str), 0444); MODULE_PARM_DESC(init_hctx, "Fault injection to fail hctx init. init_hctx=<interval>,<probability>,<space>,<times>"); #endif +/* + * Historic queue modes. + * + * These days nothing but NULL_Q_MQ is actually supported, but we keep it the + * enum for error reporting. + */ +enum { + NULL_Q_BIO = 0, + NULL_Q_RQ = 1, + NULL_Q_MQ = 2, +}; + static int g_queue_mode = NULL_Q_MQ; static int null_param_store_val(const char *str, int *val, int min, int max) @@ -756,98 +768,11 @@ static void null_free_dev(struct nullb_device *dev) kfree(dev); } -static void put_tag(struct nullb_queue *nq, unsigned int tag) -{ - clear_bit_unlock(tag, nq->tag_map); - - if (waitqueue_active(&nq->wait)) - wake_up(&nq->wait); -} - -static unsigned int get_tag(struct nullb_queue *nq) -{ - unsigned int tag; - - do { - tag = find_first_zero_bit(nq->tag_map, nq->queue_depth); - if (tag >= nq->queue_depth) - return -1U; - } while (test_and_set_bit_lock(tag, nq->tag_map)); - - return tag; -} - -static void free_cmd(struct nullb_cmd *cmd) -{ - put_tag(cmd->nq, cmd->tag); -} - -static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer); - -static struct nullb_cmd *__alloc_cmd(struct nullb_queue *nq) -{ - struct nullb_cmd *cmd; - unsigned int tag; - - tag = get_tag(nq); - if (tag != -1U) { - cmd = &nq->cmds[tag]; - cmd->tag = tag; - cmd->error = BLK_STS_OK; - cmd->nq = nq; - if (nq->dev->irqmode == NULL_IRQ_TIMER) { - hrtimer_init(&cmd->timer, CLOCK_MONOTONIC, - HRTIMER_MODE_REL); - cmd->timer.function = null_cmd_timer_expired; - } - return cmd; - } - - return NULL; -} - -static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, struct bio *bio) -{ - struct nullb_cmd *cmd; - DEFINE_WAIT(wait); - - do { - /* - * This avoids multiple return statements, multiple calls to - * __alloc_cmd() and a fast path call to prepare_to_wait(). - */ - cmd = __alloc_cmd(nq); - if (cmd) { - cmd->bio = bio; - return cmd; - } - prepare_to_wait(&nq->wait, &wait, TASK_UNINTERRUPTIBLE); - io_schedule(); - finish_wait(&nq->wait, &wait); - } while (1); -} - -static void end_cmd(struct nullb_cmd *cmd) -{ - int queue_mode = cmd->nq->dev->queue_mode; - - switch (queue_mode) { - case NULL_Q_MQ: - blk_mq_end_request(cmd->rq, cmd->error); - return; - case NULL_Q_BIO: - cmd->bio->bi_status = cmd->error; - bio_endio(cmd->bio); - break; - } - - free_cmd(cmd); -} - static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) { - end_cmd(container_of(timer, struct nullb_cmd, timer)); + struct nullb_cmd *cmd = container_of(timer, struct nullb_cmd, timer); + blk_mq_end_request(blk_mq_rq_from_pdu(cmd), cmd->error); return HRTIMER_NORESTART; } @@ -860,7 +785,9 @@ static void null_cmd_end_timer(struct nullb_cmd *cmd) static void null_complete_rq(struct request *rq) { - end_cmd(blk_mq_rq_to_pdu(rq)); + struct nullb_cmd *cmd = blk_mq_rq_to_pdu(rq); + + blk_mq_end_request(rq, cmd->error); } static struct nullb_page *null_alloc_page(void) @@ -1277,7 +1204,7 @@ static int null_transfer(struct nullb *nullb, struct page *page, static int null_handle_rq(struct nullb_cmd *cmd) { - struct request *rq = cmd->rq; + struct request *rq = blk_mq_rq_from_pdu(cmd); struct nullb *nullb = cmd->nq->dev->nullb; int err; unsigned int len; @@ -1302,63 +1229,21 @@ static int null_handle_rq(struct nullb_cmd *cmd) return 0; } -static int null_handle_bio(struct nullb_cmd *cmd) -{ - struct bio *bio = cmd->bio; - struct nullb *nullb = cmd->nq->dev->nullb; - int err; - unsigned int len; - sector_t sector = bio->bi_iter.bi_sector; - struct bio_vec bvec; - struct bvec_iter iter; - - spin_lock_irq(&nullb->lock); - bio_for_each_segment(bvec, bio, iter) { - len = bvec.bv_len; - err = null_transfer(nullb, bvec.bv_page, len, bvec.bv_offset, - op_is_write(bio_op(bio)), sector, - bio->bi_opf & REQ_FUA); - if (err) { - spin_unlock_irq(&nullb->lock); - return err; - } - sector += len >> SECTOR_SHIFT; - } - spin_unlock_irq(&nullb->lock); - return 0; -} - -static void null_stop_queue(struct nullb *nullb) -{ - struct request_queue *q = nullb->q; - - if (nullb->dev->queue_mode == NULL_Q_MQ) - blk_mq_stop_hw_queues(q); -} - -static void null_restart_queue_async(struct nullb *nullb) -{ - struct request_queue *q = nullb->q; - - if (nullb->dev->queue_mode == NULL_Q_MQ) - blk_mq_start_stopped_hw_queues(q, true); -} - static inline blk_status_t null_handle_throttled(struct nullb_cmd *cmd) { struct nullb_device *dev = cmd->nq->dev; struct nullb *nullb = dev->nullb; blk_status_t sts = BLK_STS_OK; - struct request *rq = cmd->rq; + struct request *rq = blk_mq_rq_from_pdu(cmd); if (!hrtimer_active(&nullb->bw_timer)) hrtimer_restart(&nullb->bw_timer); if (atomic_long_sub_return(blk_rq_bytes(rq), &nullb->cur_bytes) < 0) { - null_stop_queue(nullb); + blk_mq_stop_hw_queues(nullb->q); /* race with timer */ if (atomic_long_read(&nullb->cur_bytes) > 0) - null_restart_queue_async(nullb); + blk_mq_start_stopped_hw_queues(nullb->q, true); /* requeue request */ sts = BLK_STS_DEV_RESOURCE; } @@ -1385,37 +1270,29 @@ static inline blk_status_t null_handle_memory_backed(struct nullb_cmd *cmd, sector_t nr_sectors) { struct nullb_device *dev = cmd->nq->dev; - int err; if (op == REQ_OP_DISCARD) return null_handle_discard(dev, sector, nr_sectors); + return errno_to_blk_status(null_handle_rq(cmd)); - if (dev->queue_mode == NULL_Q_BIO) - err = null_handle_bio(cmd); - else - err = null_handle_rq(cmd); - - return errno_to_blk_status(err); } static void nullb_zero_read_cmd_buffer(struct nullb_cmd *cmd) { + struct request *rq = blk_mq_rq_from_pdu(cmd); struct nullb_device *dev = cmd->nq->dev; struct bio *bio; - if (dev->memory_backed) - return; - - if (dev->queue_mode == NULL_Q_BIO && bio_op(cmd->bio) == REQ_OP_READ) { - zero_fill_bio(cmd->bio); - } else if (req_op(cmd->rq) == REQ_OP_READ) { - __rq_for_each_bio(bio, cmd->rq) + if (!dev->memory_backed && req_op(rq) == REQ_OP_READ) { + __rq_for_each_bio(bio, rq) zero_fill_bio(bio); } } static inline void nullb_complete_cmd(struct nullb_cmd *cmd) { + struct request *rq = blk_mq_rq_from_pdu(cmd); + /* * Since root privileges are required to configure the null_blk * driver, it is fine that this driver does not initialize the @@ -1429,20 +1306,10 @@ static inline void nullb_complete_cmd(struct nullb_cmd *cmd) /* Complete IO by inline, softirq or timer */ switch (cmd->nq->dev->irqmode) { case NULL_IRQ_SOFTIRQ: - switch (cmd->nq->dev->queue_mode) { - case NULL_Q_MQ: - blk_mq_complete_request(cmd->rq); - break; - case NULL_Q_BIO: - /* - * XXX: no proper submitting cpu information available. - */ - end_cmd(cmd); - break; - } + blk_mq_complete_request(rq); break; case NULL_IRQ_NONE: - end_cmd(cmd); + blk_mq_end_request(rq, cmd->error); break; case NULL_IRQ_TIMER: null_cmd_end_timer(cmd); @@ -1503,7 +1370,7 @@ static enum hrtimer_restart nullb_bwtimer_fn(struct hrtimer *timer) return HRTIMER_NORESTART; atomic_long_set(&nullb->cur_bytes, mb_per_tick(mbps)); - null_restart_queue_async(nullb); + blk_mq_start_stopped_hw_queues(nullb->q, true); hrtimer_forward_now(&nullb->bw_timer, timer_interval); @@ -1520,26 +1387,6 @@ static void nullb_setup_bwtimer(struct nullb *nullb) hrtimer_start(&nullb->bw_timer, timer_interval, HRTIMER_MODE_REL); } -static struct nullb_queue *nullb_to_queue(struct nullb *nullb) -{ - int index = 0; - - if (nullb->nr_queues != 1) - index = raw_smp_processor_id() / ((nr_cpu_ids + nullb->nr_queues - 1) / nullb->nr_queues); - - return &nullb->queues[index]; -} - -static void null_submit_bio(struct bio *bio) -{ - sector_t sector = bio->bi_iter.bi_sector; - sector_t nr_sectors = bio_sectors(bio); - struct nullb *nullb = bio->bi_bdev->bd_disk->private_data; - struct nullb_queue *nq = nullb_to_queue(nullb); - - null_handle_cmd(alloc_cmd(nq, bio), sector, nr_sectors, bio_op(bio)); -} - #ifdef CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION static bool should_timeout_request(struct request *rq) @@ -1659,7 +1506,7 @@ static int null_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) blk_rq_sectors(req)); if (!blk_mq_add_to_batch(req, iob, (__force int) cmd->error, blk_mq_end_request_batch)) - end_cmd(cmd); + blk_mq_end_request(req, cmd->error); nr++; } @@ -1715,7 +1562,6 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, hrtimer_init(&cmd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); cmd->timer.function = null_cmd_timer_expired; } - cmd->rq = rq; cmd->error = BLK_STS_OK; cmd->nq = nq; cmd->fake_timeout = should_timeout_request(rq) || @@ -1774,22 +1620,6 @@ static void null_queue_rqs(struct request **rqlist) *rqlist = requeue_list; } -static void cleanup_queue(struct nullb_queue *nq) -{ - bitmap_free(nq->tag_map); - kfree(nq->cmds); -} - -static void cleanup_queues(struct nullb *nullb) -{ - int i; - - for (i = 0; i < nullb->nr_queues; i++) - cleanup_queue(&nullb->queues[i]); - - kfree(nullb->queues); -} - static void null_exit_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) { struct nullb_queue *nq = hctx->driver_data; @@ -1800,8 +1630,6 @@ static void null_exit_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) static void null_init_queue(struct nullb *nullb, struct nullb_queue *nq) { - init_waitqueue_head(&nq->wait); - nq->queue_depth = nullb->queue_depth; nq->dev = nullb->dev; INIT_LIST_HEAD(&nq->poll_list); spin_lock_init(&nq->poll_lock); @@ -1853,14 +1681,13 @@ static void null_del_dev(struct nullb *nullb) if (test_bit(NULLB_DEV_FL_THROTTLED, &nullb->dev->flags)) { hrtimer_cancel(&nullb->bw_timer); atomic_long_set(&nullb->cur_bytes, LONG_MAX); - null_restart_queue_async(nullb); + blk_mq_start_stopped_hw_queues(nullb->q, true); } put_disk(nullb->disk); - if (dev->queue_mode == NULL_Q_MQ && - nullb->tag_set == &nullb->__tag_set) + if (nullb->tag_set == &nullb->__tag_set) blk_mq_free_tag_set(nullb->tag_set); - cleanup_queues(nullb); + kfree(nullb->queues); if (null_cache_active(nullb)) null_free_device_storage(nullb->dev, true); kfree(nullb); @@ -1887,40 +1714,11 @@ static void null_config_discard(struct nullb *nullb) blk_queue_max_discard_sectors(nullb->q, UINT_MAX >> 9); } -static const struct block_device_operations null_bio_ops = { +static const struct block_device_operations null_ops = { .owner = THIS_MODULE, - .submit_bio = null_submit_bio, .report_zones = null_report_zones, }; -static const struct block_device_operations null_rq_ops = { - .owner = THIS_MODULE, - .report_zones = null_report_zones, -}; - -static int setup_commands(struct nullb_queue *nq) -{ - struct nullb_cmd *cmd; - int i; - - nq->cmds = kcalloc(nq->queue_depth, sizeof(*cmd), GFP_KERNEL); - if (!nq->cmds) - return -ENOMEM; - - nq->tag_map = bitmap_zalloc(nq->queue_depth, GFP_KERNEL); - if (!nq->tag_map) { - kfree(nq->cmds); - return -ENOMEM; - } - - for (i = 0; i < nq->queue_depth; i++) { - cmd = &nq->cmds[i]; - cmd->tag = -1U; - } - - return 0; -} - static int setup_queues(struct nullb *nullb) { int nqueues = nr_cpu_ids; @@ -1937,24 +1735,6 @@ static int setup_queues(struct nullb *nullb) return 0; } -static int init_driver_queues(struct nullb *nullb) -{ - struct nullb_queue *nq; - int i, ret = 0; - - for (i = 0; i < nullb->dev->submit_queues; i++) { - nq = &nullb->queues[i]; - - null_init_queue(nullb, nq); - - ret = setup_commands(nq); - if (ret) - return ret; - nullb->nr_queues++; - } - return 0; -} - static int null_gendisk_register(struct nullb *nullb) { sector_t size = ((sector_t)nullb->dev->size * SZ_1M) >> SECTOR_SHIFT; @@ -1965,10 +1745,7 @@ static int null_gendisk_register(struct nullb *nullb) disk->major = null_major; disk->first_minor = nullb->index; disk->minors = 1; - if (queue_is_mq(nullb->q)) - disk->fops = &null_rq_ops; - else - disk->fops = &null_bio_ops; + disk->fops = &null_ops; disk->private_data = nullb; strscpy_pad(disk->disk_name, nullb->disk_name, DISK_NAME_LEN); @@ -2036,11 +1813,15 @@ static int null_validate_conf(struct nullb_device *dev) pr_err("legacy IO path is no longer available\n"); return -EINVAL; } + if (dev->queue_mode == NULL_Q_BIO) { + pr_err("BIO-based IO path is no longer available, using blk-mq instead.\n"); + dev->queue_mode = NULL_Q_MQ; + } dev->blocksize = round_down(dev->blocksize, 512); dev->blocksize = clamp_t(unsigned int, dev->blocksize, 512, 4096); - if (dev->queue_mode == NULL_Q_MQ && dev->use_per_node_hctx) { + if (dev->use_per_node_hctx) { if (dev->submit_queues != nr_online_nodes) dev->submit_queues = nr_online_nodes; } else if (dev->submit_queues > nr_cpu_ids) @@ -2052,8 +1833,6 @@ static int null_validate_conf(struct nullb_device *dev) if (dev->poll_queues > g_poll_queues) dev->poll_queues = g_poll_queues; dev->prev_poll_queues = dev->poll_queues; - - dev->queue_mode = min_t(unsigned int, dev->queue_mode, NULL_Q_MQ); dev->irqmode = min_t(unsigned int, dev->irqmode, NULL_IRQ_TIMER); /* Do memory allocation, so set blocking */ @@ -2064,9 +1843,6 @@ static int null_validate_conf(struct nullb_device *dev) dev->cache_size = min_t(unsigned long, ULONG_MAX / 1024 / 1024, dev->cache_size); dev->mbps = min_t(unsigned int, 1024 * 40, dev->mbps); - /* can not stop a queue */ - if (dev->queue_mode == NULL_Q_BIO) - dev->mbps = 0; if (dev->zoned && (!dev->zone_size || !is_power_of_2(dev->zone_size))) { @@ -2127,43 +1903,31 @@ static int null_add_dev(struct nullb_device *dev) if (rv) goto out_free_nullb; - if (dev->queue_mode == NULL_Q_MQ) { - if (dev->shared_tags) { - if (!tag_set.ops) { - rv = null_init_tag_set(NULL, &tag_set); - if (rv) { - tag_set.ops = NULL; - goto out_cleanup_queues; - } + if (dev->shared_tags) { + if (!tag_set.ops) { + rv = null_init_tag_set(NULL, &tag_set); + if (rv) { + tag_set.ops = NULL; + goto out_cleanup_queues; } - nullb->tag_set = &tag_set; - rv = 0; - } else { - nullb->tag_set = &nullb->__tag_set; - rv = null_init_tag_set(nullb, nullb->tag_set); } + nullb->tag_set = &tag_set; + rv = 0; + } else { + nullb->tag_set = &nullb->__tag_set; + rv = null_init_tag_set(nullb, nullb->tag_set); + } - if (rv) - goto out_cleanup_queues; - - nullb->tag_set->timeout = 5 * HZ; - nullb->disk = blk_mq_alloc_disk(nullb->tag_set, NULL, nullb); - if (IS_ERR(nullb->disk)) { - rv = PTR_ERR(nullb->disk); - goto out_cleanup_tags; - } - nullb->q = nullb->disk->queue; - } else if (dev->queue_mode == NULL_Q_BIO) { - rv = -ENOMEM; - nullb->disk = blk_alloc_disk(nullb->dev->home_node); - if (!nullb->disk) - goto out_cleanup_queues; + if (rv) + goto out_cleanup_queues; - nullb->q = nullb->disk->queue; - rv = init_driver_queues(nullb); - if (rv) - goto out_cleanup_disk; + nullb->tag_set->timeout = 5 * HZ; + nullb->disk = blk_mq_alloc_disk(nullb->tag_set, NULL, nullb); + if (IS_ERR(nullb->disk)) { + rv = PTR_ERR(nullb->disk); + goto out_cleanup_tags; } + nullb->q = nullb->disk->queue; if (dev->mbps) { set_bit(NULLB_DEV_FL_THROTTLED, &dev->flags); @@ -2231,10 +1995,10 @@ static int null_add_dev(struct nullb_device *dev) out_cleanup_disk: put_disk(nullb->disk); out_cleanup_tags: - if (dev->queue_mode == NULL_Q_MQ && nullb->tag_set == &nullb->__tag_set) + if (nullb->tag_set == &nullb->__tag_set) blk_mq_free_tag_set(nullb->tag_set); out_cleanup_queues: - cleanup_queues(nullb); + kfree(nullb->queues); out_free_nullb: kfree(nullb); dev->nullb = NULL; @@ -2310,7 +2074,7 @@ static int __init null_init(void) return -EINVAL; } - if (g_queue_mode == NULL_Q_MQ && g_use_per_node_hctx) { + if (g_use_per_node_hctx) { if (g_submit_queues != nr_online_nodes) { pr_warn("submit_queues param is set to %u.\n", nr_online_nodes); diff --git a/drivers/block/null_blk/null_blk.h b/drivers/block/null_blk/null_blk.h index 7bcfc0922ae821..7c618d53d8fd06 100644 --- a/drivers/block/null_blk/null_blk.h +++ b/drivers/block/null_blk/null_blk.h @@ -16,11 +16,6 @@ #include <linux/mutex.h> struct nullb_cmd { - union { - struct request *rq; - struct bio *bio; - }; - unsigned int tag; blk_status_t error; bool fake_timeout; struct nullb_queue *nq; @@ -28,16 +23,11 @@ struct nullb_cmd { }; struct nullb_queue { - unsigned long *tag_map; - wait_queue_head_t wait; - unsigned int queue_depth; struct nullb_device *dev; unsigned int requeue_selection; struct list_head poll_list; spinlock_t poll_lock; - - struct nullb_cmd *cmds; }; struct nullb_zone { @@ -60,13 +50,6 @@ struct nullb_zone { unsigned int capacity; }; -/* Queue modes */ -enum { - NULL_Q_BIO = 0, - NULL_Q_RQ = 1, - NULL_Q_MQ = 2, -}; - struct nullb_device { struct nullb *nullb; struct config_group group; diff --git a/drivers/block/null_blk/trace.h b/drivers/block/null_blk/trace.h index 6b2b370e786f5f..ef2d05d5f0df7e 100644 --- a/drivers/block/null_blk/trace.h +++ b/drivers/block/null_blk/trace.h @@ -41,10 +41,11 @@ TRACE_EVENT(nullb_zone_op, __field(unsigned int, zone_cond) ), TP_fast_assign( - __entry->op = req_op(cmd->rq); + __entry->op = req_op(blk_mq_rq_from_pdu(cmd)); __entry->zone_no = zone_no; __entry->zone_cond = zone_cond; - __assign_disk_name(__entry->disk, cmd->rq->q->disk); + __assign_disk_name(__entry->disk, + blk_mq_rq_from_pdu(cmd)->q->disk); ), TP_printk("%s req=%-15s zone_no=%u zone_cond=%-10s", __print_disk_name(__entry->disk), diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c index 6f5e0994862eae..3605afe105dac9 100644 --- a/drivers/block/null_blk/zoned.c +++ b/drivers/block/null_blk/zoned.c @@ -168,10 +168,7 @@ int null_register_zoned_dev(struct nullb *nullb) disk_set_max_open_zones(nullb->disk, dev->zone_max_open); disk_set_max_active_zones(nullb->disk, dev->zone_max_active); - if (queue_is_mq(q)) - return blk_revalidate_disk_zones(nullb->disk, NULL); - - return 0; + return blk_revalidate_disk_zones(nullb->disk, NULL); } void null_free_zoned_dev(struct nullb_device *dev) @@ -394,10 +391,7 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector, */ if (append) { sector = zone->wp; - if (dev->queue_mode == NULL_Q_MQ) - cmd->rq->__sector = sector; - else - cmd->bio->bi_iter.bi_sector = sector; + blk_mq_rq_from_pdu(cmd)->__sector = sector; } else if (sector != zone->wp) { ret = BLK_STS_IOERR; goto unlock; -- 2.39.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 1/5] null_blk: remove the bio based I/O path 2024-02-14 9:54 ` [PATCH 1/5] null_blk: remove the bio based I/O path Christoph Hellwig @ 2024-02-14 11:25 ` Damien Le Moal 2024-02-14 17:25 ` Keith Busch 1 sibling, 0 replies; 20+ messages in thread From: Damien Le Moal @ 2024-02-14 11:25 UTC (permalink / raw) To: Christoph Hellwig, Jens Axboe; +Cc: linux-block On 2/14/24 18:54, Christoph Hellwig wrote: > The bio based I/O path complicates null_blk and also make various > data structures, including the per-command one way bigger than > required for the main request based interface. As the bio-based > path is mostly used by stacking drivers and simple memory based > drivers, and brd is a good example driver for the latter there is > no need to have a bio based path in null_blk. Remove the path > to simplify the driver and make future block layer API changes > simpler by not having to deal with the complex two API setup in > null_blk. > > Signed-off-by: Christoph Hellwig <hch@lst.de> Looks OK to me. Reviewed-by: Damien Le Moal <dlemoal@kernel.org> -- Damien Le Moal Western Digital Research ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/5] null_blk: remove the bio based I/O path 2024-02-14 9:54 ` [PATCH 1/5] null_blk: remove the bio based I/O path Christoph Hellwig 2024-02-14 11:25 ` Damien Le Moal @ 2024-02-14 17:25 ` Keith Busch 2024-02-14 23:16 ` Damien Le Moal 2024-02-15 8:05 ` Christoph Hellwig 1 sibling, 2 replies; 20+ messages in thread From: Keith Busch @ 2024-02-14 17:25 UTC (permalink / raw) To: Christoph Hellwig; +Cc: Jens Axboe, linux-block On Wed, Feb 14, 2024 at 10:54:57AM +0100, Christoph Hellwig wrote: > @@ -2036,11 +1813,15 @@ static int null_validate_conf(struct nullb_device *dev) > pr_err("legacy IO path is no longer available\n"); > return -EINVAL; > } > + if (dev->queue_mode == NULL_Q_BIO) { > + pr_err("BIO-based IO path is no longer available, using blk-mq instead.\n"); > + dev->queue_mode = NULL_Q_MQ; > + } Seems pointless to keep dev->queue_mode around if only one value is valid. Instead of checking the param here once per device, could we do it just once for the module in null_set_queue_mode()? --- @@ -134,7 +134,7 @@ static int null_param_store_val(const char *str, int *val, int min, int max) static int null_set_queue_mode(const char *str, const struct kernel_param *kp) { - return null_param_store_val(str, &g_queue_mode, NULL_Q_BIO, NULL_Q_MQ); + return null_param_store_val(str, &g_queue_mode, NULL_Q_MQ, NULL_Q_MQ); } static const struct kernel_param_ops null_queue_mode_param_ops = { -- ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/5] null_blk: remove the bio based I/O path 2024-02-14 17:25 ` Keith Busch @ 2024-02-14 23:16 ` Damien Le Moal 2024-02-14 23:34 ` Keith Busch 2024-02-15 8:05 ` Christoph Hellwig 1 sibling, 1 reply; 20+ messages in thread From: Damien Le Moal @ 2024-02-14 23:16 UTC (permalink / raw) To: Keith Busch, Christoph Hellwig; +Cc: Jens Axboe, linux-block On 2/15/24 02:25, Keith Busch wrote: > On Wed, Feb 14, 2024 at 10:54:57AM +0100, Christoph Hellwig wrote: >> @@ -2036,11 +1813,15 @@ static int null_validate_conf(struct nullb_device *dev) >> pr_err("legacy IO path is no longer available\n"); >> return -EINVAL; >> } >> + if (dev->queue_mode == NULL_Q_BIO) { >> + pr_err("BIO-based IO path is no longer available, using blk-mq instead.\n"); >> + dev->queue_mode = NULL_Q_MQ; >> + } > > Seems pointless to keep dev->queue_mode around if only one value is > valid. > > Instead of checking the param here once per device, could we do it just > once for the module in null_set_queue_mode()? We need the check for the configfs path as well... > > --- > @@ -134,7 +134,7 @@ static int null_param_store_val(const char *str, int *val, int min, int max) > > static int null_set_queue_mode(const char *str, const struct kernel_param *kp) > { > - return null_param_store_val(str, &g_queue_mode, NULL_Q_BIO, NULL_Q_MQ); > + return null_param_store_val(str, &g_queue_mode, NULL_Q_MQ, NULL_Q_MQ); > } > > static const struct kernel_param_ops null_queue_mode_param_ops = { > -- > -- Damien Le Moal Western Digital Research ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/5] null_blk: remove the bio based I/O path 2024-02-14 23:16 ` Damien Le Moal @ 2024-02-14 23:34 ` Keith Busch 0 siblings, 0 replies; 20+ messages in thread From: Keith Busch @ 2024-02-14 23:34 UTC (permalink / raw) To: Damien Le Moal; +Cc: Christoph Hellwig, Jens Axboe, linux-block On Thu, Feb 15, 2024 at 08:16:19AM +0900, Damien Le Moal wrote: > On 2/15/24 02:25, Keith Busch wrote: > > On Wed, Feb 14, 2024 at 10:54:57AM +0100, Christoph Hellwig wrote: > >> @@ -2036,11 +1813,15 @@ static int null_validate_conf(struct nullb_device *dev) > >> pr_err("legacy IO path is no longer available\n"); > >> return -EINVAL; > >> } > >> + if (dev->queue_mode == NULL_Q_BIO) { > >> + pr_err("BIO-based IO path is no longer available, using blk-mq instead.\n"); > >> + dev->queue_mode = NULL_Q_MQ; > >> + } > > > > Seems pointless to keep dev->queue_mode around if only one value is > > valid. > > > > Instead of checking the param here once per device, could we do it just > > once for the module in null_set_queue_mode()? > > We need the check for the configfs path as well... Yeah, my snippet suggestion wasn't a fully flushed out idea. The configfs part would just be this: --- @@ -401,12 +401,20 @@ static int nullb_apply_poll_queues(struct nullb_device *dev, return nullb_update_nr_hw_queues(dev, dev->submit_queues, poll_queues); } +static int nullb_apply_queue_mode(struct nullb_device *dev, + unsigned int queue_mode) +{ + if (queue_mode != NULL_Q_MQ) + return -EINVAL; + return 0; +} + NULLB_DEVICE_ATTR(size, ulong, NULL); NULLB_DEVICE_ATTR(completion_nsec, ulong, NULL); NULLB_DEVICE_ATTR(submit_queues, uint, nullb_apply_submit_queues); NULLB_DEVICE_ATTR(poll_queues, uint, nullb_apply_poll_queues); NULLB_DEVICE_ATTR(home_node, uint, NULL); -NULLB_DEVICE_ATTR(queue_mode, uint, NULL); +NULLB_DEVICE_ATTR(queue_mode, uint, nullb_apply_queue_mode); NULLB_DEVICE_ATTR(blocksize, uint, NULL); NULLB_DEVICE_ATTR(max_sectors, uint, NULL); NULLB_DEVICE_ATTR(irqmode, uint, NULL); -- ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/5] null_blk: remove the bio based I/O path 2024-02-14 17:25 ` Keith Busch 2024-02-14 23:16 ` Damien Le Moal @ 2024-02-15 8:05 ` Christoph Hellwig 1 sibling, 0 replies; 20+ messages in thread From: Christoph Hellwig @ 2024-02-15 8:05 UTC (permalink / raw) To: Keith Busch; +Cc: Christoph Hellwig, Jens Axboe, linux-block On Wed, Feb 14, 2024 at 10:25:57AM -0700, Keith Busch wrote: > On Wed, Feb 14, 2024 at 10:54:57AM +0100, Christoph Hellwig wrote: > > @@ -2036,11 +1813,15 @@ static int null_validate_conf(struct nullb_device *dev) > > pr_err("legacy IO path is no longer available\n"); > > return -EINVAL; > > } > > + if (dev->queue_mode == NULL_Q_BIO) { > > + pr_err("BIO-based IO path is no longer available, using blk-mq instead.\n"); > > + dev->queue_mode = NULL_Q_MQ; > > + } > > Seems pointless to keep dev->queue_mode around if only one value is > valid. > > Instead of checking the param here once per device, could we do it just > once for the module in null_set_queue_mode()? Maybe. Note that the code would have to be quite a bit more complex than this - not only due to configfs as noted by Damien, but also because NULL_Q_BIO isn't rejected but simply ignored to not break blktests. I can look at this at parsing time, but my gut feeling is that it's not worth the effort. ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 2/5] null_blk: initialize the tag_set timeout in null_init_tag_set 2024-02-14 9:54 drop bio mode from null_blk and convert it to atomic queue limits Christoph Hellwig 2024-02-14 9:54 ` [PATCH 1/5] null_blk: remove the bio based I/O path Christoph Hellwig @ 2024-02-14 9:54 ` Christoph Hellwig 2024-02-14 11:26 ` Damien Le Moal 2024-02-14 9:54 ` [PATCH 3/5] null_blk: refactor tag_set setup Christoph Hellwig ` (3 subsequent siblings) 5 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2024-02-14 9:54 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block Otherwise it will be reset to the always same value when initializing a device using the shared tag_set. Signed-off-by: Christoph Hellwig <hch@lst.de> --- drivers/block/null_blk/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index d6836327eefb42..89e63d1c610362 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -1797,6 +1797,7 @@ static int null_init_tag_set(struct nullb *nullb, struct blk_mq_tag_set *set) set->nr_hw_queues = hw_queues; set->queue_depth = queue_depth; set->numa_node = numa_node; + set->timeout = 5 * HZ; if (poll_queues) { set->nr_hw_queues += poll_queues; set->nr_maps = 3; @@ -1921,7 +1922,6 @@ static int null_add_dev(struct nullb_device *dev) if (rv) goto out_cleanup_queues; - nullb->tag_set->timeout = 5 * HZ; nullb->disk = blk_mq_alloc_disk(nullb->tag_set, NULL, nullb); if (IS_ERR(nullb->disk)) { rv = PTR_ERR(nullb->disk); -- 2.39.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 2/5] null_blk: initialize the tag_set timeout in null_init_tag_set 2024-02-14 9:54 ` [PATCH 2/5] null_blk: initialize the tag_set timeout in null_init_tag_set Christoph Hellwig @ 2024-02-14 11:26 ` Damien Le Moal 0 siblings, 0 replies; 20+ messages in thread From: Damien Le Moal @ 2024-02-14 11:26 UTC (permalink / raw) To: Christoph Hellwig, Jens Axboe; +Cc: linux-block On 2/14/24 18:54, Christoph Hellwig wrote: > Otherwise it will be reset to the always same value when initializing a > device using the shared tag_set. > > Signed-off-by: Christoph Hellwig <hch@lst.de> Looks good to me. Reviewed-by: Damien Le Moal <dlemoal@kernel.org> -- Damien Le Moal Western Digital Research ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 3/5] null_blk: refactor tag_set setup 2024-02-14 9:54 drop bio mode from null_blk and convert it to atomic queue limits Christoph Hellwig 2024-02-14 9:54 ` [PATCH 1/5] null_blk: remove the bio based I/O path Christoph Hellwig 2024-02-14 9:54 ` [PATCH 2/5] null_blk: initialize the tag_set timeout in null_init_tag_set Christoph Hellwig @ 2024-02-14 9:54 ` Christoph Hellwig 2024-02-14 11:29 ` Damien Le Moal 2024-02-14 9:55 ` [PATCH 4/5] null_blk: remove null_gendisk_register Christoph Hellwig ` (2 subsequent siblings) 5 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2024-02-14 9:54 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block Move the tagset initialization out of null_add_dev into a new null_setup_tagset helper, and move the shared vs local differences out of null_init_tag_set into the callers. Signed-off-by: Christoph Hellwig <hch@lst.de> --- drivers/block/null_blk/main.c | 106 ++++++++++++++++------------------ 1 file changed, 51 insertions(+), 55 deletions(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 89e63d1c610362..03c3917a56fa28 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -1759,55 +1759,65 @@ static int null_gendisk_register(struct nullb *nullb) return add_disk(disk); } -static int null_init_tag_set(struct nullb *nullb, struct blk_mq_tag_set *set) +static int null_init_tag_set(struct blk_mq_tag_set *set, int poll_queues) { - unsigned int flags = BLK_MQ_F_SHOULD_MERGE; - int hw_queues, numa_node; - unsigned int queue_depth; - int poll_queues; - - if (nullb) { - hw_queues = nullb->dev->submit_queues; - poll_queues = nullb->dev->poll_queues; - queue_depth = nullb->dev->hw_queue_depth; - numa_node = nullb->dev->home_node; - if (nullb->dev->no_sched) - flags |= BLK_MQ_F_NO_SCHED; - if (nullb->dev->shared_tag_bitmap) - flags |= BLK_MQ_F_TAG_HCTX_SHARED; - if (nullb->dev->blocking) - flags |= BLK_MQ_F_BLOCKING; - } else { - hw_queues = g_submit_queues; - poll_queues = g_poll_queues; - queue_depth = g_hw_queue_depth; - numa_node = g_home_node; - if (g_no_sched) - flags |= BLK_MQ_F_NO_SCHED; - if (g_shared_tag_bitmap) - flags |= BLK_MQ_F_TAG_HCTX_SHARED; - if (g_blocking) - flags |= BLK_MQ_F_BLOCKING; - } - set->ops = &null_mq_ops; - set->cmd_size = sizeof(struct nullb_cmd); - set->flags = flags; - set->driver_data = nullb; - set->nr_hw_queues = hw_queues; - set->queue_depth = queue_depth; - set->numa_node = numa_node; + set->cmd_size = sizeof(struct nullb_cmd); set->timeout = 5 * HZ; + set->nr_maps = 1; if (poll_queues) { set->nr_hw_queues += poll_queues; - set->nr_maps = 3; - } else { - set->nr_maps = 1; + set->nr_maps += 2; } - return blk_mq_alloc_tag_set(set); } +static int null_init_global_tag_set(void) +{ + int error; + + if (tag_set.ops) + return 0; + + tag_set.nr_hw_queues = g_submit_queues; + tag_set.queue_depth = g_hw_queue_depth; + tag_set.numa_node = g_home_node; + tag_set.flags = BLK_MQ_F_SHOULD_MERGE; + if (g_no_sched) + tag_set.flags |= BLK_MQ_F_NO_SCHED; + if (g_shared_tag_bitmap) + tag_set.flags |= BLK_MQ_F_TAG_HCTX_SHARED; + if (g_blocking) + tag_set.flags |= BLK_MQ_F_BLOCKING; + + error = null_init_tag_set(&tag_set, g_poll_queues); + if (error) + tag_set.ops = NULL; + return error; +} + +static int null_setup_tagset(struct nullb *nullb) +{ + if (nullb->dev->shared_tags) { + nullb->tag_set = &tag_set; + return null_init_global_tag_set(); + } + + nullb->tag_set = &nullb->__tag_set; + nullb->tag_set->driver_data = nullb; + nullb->tag_set->nr_hw_queues = nullb->dev->submit_queues; + nullb->tag_set->queue_depth = nullb->dev->hw_queue_depth; + nullb->tag_set->numa_node = nullb->dev->home_node; + nullb->tag_set->flags = BLK_MQ_F_SHOULD_MERGE; + if (nullb->dev->no_sched) + nullb->tag_set->flags |= BLK_MQ_F_NO_SCHED; + if (nullb->dev->shared_tag_bitmap) + nullb->tag_set->flags |= BLK_MQ_F_TAG_HCTX_SHARED; + if (nullb->dev->blocking) + nullb->tag_set->flags |= BLK_MQ_F_BLOCKING; + return null_init_tag_set(nullb->tag_set, nullb->dev->poll_queues); +} + static int null_validate_conf(struct nullb_device *dev) { if (dev->queue_mode == NULL_Q_RQ) { @@ -1904,21 +1914,7 @@ static int null_add_dev(struct nullb_device *dev) if (rv) goto out_free_nullb; - if (dev->shared_tags) { - if (!tag_set.ops) { - rv = null_init_tag_set(NULL, &tag_set); - if (rv) { - tag_set.ops = NULL; - goto out_cleanup_queues; - } - } - nullb->tag_set = &tag_set; - rv = 0; - } else { - nullb->tag_set = &nullb->__tag_set; - rv = null_init_tag_set(nullb, nullb->tag_set); - } - + rv = null_setup_tagset(nullb); if (rv) goto out_cleanup_queues; -- 2.39.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 3/5] null_blk: refactor tag_set setup 2024-02-14 9:54 ` [PATCH 3/5] null_blk: refactor tag_set setup Christoph Hellwig @ 2024-02-14 11:29 ` Damien Le Moal 0 siblings, 0 replies; 20+ messages in thread From: Damien Le Moal @ 2024-02-14 11:29 UTC (permalink / raw) To: Christoph Hellwig, Jens Axboe; +Cc: linux-block On 2/14/24 18:54, Christoph Hellwig wrote: > Move the tagset initialization out of null_add_dev into a new > null_setup_tagset helper, and move the shared vs local differences > out of null_init_tag_set into the callers. > > Signed-off-by: Christoph Hellwig <hch@lst.de> Looks good to me. Reviewed-by: Damien Le Moal <dlemoal@kernel.org> -- Damien Le Moal Western Digital Research ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 4/5] null_blk: remove null_gendisk_register 2024-02-14 9:54 drop bio mode from null_blk and convert it to atomic queue limits Christoph Hellwig ` (2 preceding siblings ...) 2024-02-14 9:54 ` [PATCH 3/5] null_blk: refactor tag_set setup Christoph Hellwig @ 2024-02-14 9:55 ` Christoph Hellwig 2024-02-14 11:30 ` Damien Le Moal 2024-02-14 9:55 ` [PATCH 5/5] null_blk: pass queue_limits to blk_mq_alloc_disk Christoph Hellwig 2024-02-14 14:08 ` drop bio mode from null_blk and convert it to atomic queue limits Johannes Thumshirn 5 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2024-02-14 9:55 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block null_gendisk_register isn't a very useful abstraction given that it doesn't even allocate the gendisk. Merge it into the only caller instead. Signed-off-by: Christoph Hellwig <hch@lst.de> --- drivers/block/null_blk/main.c | 41 ++++++++++++++--------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 03c3917a56fa28..0c8d5042321302 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -1735,30 +1735,6 @@ static int setup_queues(struct nullb *nullb) return 0; } -static int null_gendisk_register(struct nullb *nullb) -{ - sector_t size = ((sector_t)nullb->dev->size * SZ_1M) >> SECTOR_SHIFT; - struct gendisk *disk = nullb->disk; - - set_capacity(disk, size); - - disk->major = null_major; - disk->first_minor = nullb->index; - disk->minors = 1; - disk->fops = &null_ops; - disk->private_data = nullb; - strscpy_pad(disk->disk_name, nullb->disk_name, DISK_NAME_LEN); - - if (nullb->dev->zoned) { - int ret = null_register_zoned_dev(nullb); - - if (ret) - return ret; - } - - return add_disk(disk); -} - static int null_init_tag_set(struct blk_mq_tag_set *set, int poll_queues) { set->ops = &null_mq_ops; @@ -1972,7 +1948,22 @@ static int null_add_dev(struct nullb_device *dev) sprintf(nullb->disk_name, "nullb%d", nullb->index); } - rv = null_gendisk_register(nullb); + set_capacity(nullb->disk, + ((sector_t)nullb->dev->size * SZ_1M) >> SECTOR_SHIFT); + nullb->disk->major = null_major; + nullb->disk->first_minor = nullb->index; + nullb->disk->minors = 1; + nullb->disk->fops = &null_ops; + nullb->disk->private_data = nullb; + strscpy_pad(nullb->disk->disk_name, nullb->disk_name, DISK_NAME_LEN); + + if (nullb->dev->zoned) { + rv = null_register_zoned_dev(nullb); + if (rv) + goto out_ida_free; + } + + rv = add_disk(nullb->disk); if (rv) goto out_ida_free; -- 2.39.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 4/5] null_blk: remove null_gendisk_register 2024-02-14 9:55 ` [PATCH 4/5] null_blk: remove null_gendisk_register Christoph Hellwig @ 2024-02-14 11:30 ` Damien Le Moal 0 siblings, 0 replies; 20+ messages in thread From: Damien Le Moal @ 2024-02-14 11:30 UTC (permalink / raw) To: Christoph Hellwig, Jens Axboe; +Cc: linux-block On 2/14/24 18:55, Christoph Hellwig wrote: > null_gendisk_register isn't a very useful abstraction given that it > doesn't even allocate the gendisk. Merge it into the only caller > instead. > > Signed-off-by: Christoph Hellwig <hch@lst.de> Looks good to me. Reviewed-by: Damien Le Moal <dlemoal@kernel.org> -- Damien Le Moal Western Digital Research ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 5/5] null_blk: pass queue_limits to blk_mq_alloc_disk 2024-02-14 9:54 drop bio mode from null_blk and convert it to atomic queue limits Christoph Hellwig ` (3 preceding siblings ...) 2024-02-14 9:55 ` [PATCH 4/5] null_blk: remove null_gendisk_register Christoph Hellwig @ 2024-02-14 9:55 ` Christoph Hellwig 2024-02-14 11:32 ` Damien Le Moal 2024-02-14 14:08 ` drop bio mode from null_blk and convert it to atomic queue limits Johannes Thumshirn 5 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2024-02-14 9:55 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block Pass the queue limits directly to blk_mq_alloc_disk instead of setting them one at a time. Signed-off-by: Christoph Hellwig <hch@lst.de> --- drivers/block/null_blk/main.c | 33 ++++++++++++++++++++------------- drivers/block/null_blk/zoned.c | 7 ------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 0c8d5042321302..6dd50332514d7c 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -1694,7 +1694,7 @@ static void null_del_dev(struct nullb *nullb) dev->nullb = NULL; } -static void null_config_discard(struct nullb *nullb) +static void null_config_discard(struct nullb *nullb, struct queue_limits *lim) { if (nullb->dev->discard == false) return; @@ -1711,7 +1711,7 @@ static void null_config_discard(struct nullb *nullb) return; } - blk_queue_max_discard_sectors(nullb->q, UINT_MAX >> 9); + lim->max_hw_discard_sectors = UINT_MAX >> 9; } static const struct block_device_operations null_ops = { @@ -1869,6 +1869,12 @@ static bool null_setup_fault(void) static int null_add_dev(struct nullb_device *dev) { + struct queue_limits lim = { + .logical_block_size = dev->blocksize, + .physical_block_size = dev->blocksize, + .max_hw_sectors = dev->max_sectors, + }; + struct nullb *nullb; int rv; @@ -1894,7 +1900,18 @@ static int null_add_dev(struct nullb_device *dev) if (rv) goto out_cleanup_queues; - nullb->disk = blk_mq_alloc_disk(nullb->tag_set, NULL, nullb); + if (dev->virt_boundary) + lim.virt_boundary_mask = PAGE_SIZE - 1; + if (dev->zoned) { + lim.zoned = true; + lim.chunk_sectors = dev->zone_size_sects; + lim.max_zone_append_sectors = dev->zone_size_sects; + lim.max_open_zones = dev->zone_max_open; + lim.max_active_zones = dev->zone_max_active; + } + null_config_discard(nullb, &lim); + + nullb->disk = blk_mq_alloc_disk(nullb->tag_set, &lim, nullb); if (IS_ERR(nullb->disk)) { rv = PTR_ERR(nullb->disk); goto out_cleanup_tags; @@ -1930,16 +1947,6 @@ static int null_add_dev(struct nullb_device *dev) dev->index = rv; mutex_unlock(&lock); - blk_queue_logical_block_size(nullb->q, dev->blocksize); - blk_queue_physical_block_size(nullb->q, dev->blocksize); - if (dev->max_sectors) - blk_queue_max_hw_sectors(nullb->q, dev->max_sectors); - - if (dev->virt_boundary) - blk_queue_virt_boundary(nullb->q, PAGE_SIZE - 1); - - null_config_discard(nullb); - if (config_item_name(&dev->group.cg_item)) { /* Use configfs dir name as the device name */ snprintf(nullb->disk_name, sizeof(nullb->disk_name), diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c index 3605afe105dac9..8ece18b0ea30c8 100644 --- a/drivers/block/null_blk/zoned.c +++ b/drivers/block/null_blk/zoned.c @@ -156,18 +156,11 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q) int null_register_zoned_dev(struct nullb *nullb) { - struct nullb_device *dev = nullb->dev; struct request_queue *q = nullb->q; - disk_set_zoned(nullb->disk); blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q); blk_queue_required_elevator_features(q, ELEVATOR_F_ZBD_SEQ_WRITE); - blk_queue_chunk_sectors(q, dev->zone_size_sects); nullb->disk->nr_zones = bdev_nr_zones(nullb->disk->part0); - blk_queue_max_zone_append_sectors(q, dev->zone_size_sects); - disk_set_max_open_zones(nullb->disk, dev->zone_max_open); - disk_set_max_active_zones(nullb->disk, dev->zone_max_active); - return blk_revalidate_disk_zones(nullb->disk, NULL); } -- 2.39.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 5/5] null_blk: pass queue_limits to blk_mq_alloc_disk 2024-02-14 9:55 ` [PATCH 5/5] null_blk: pass queue_limits to blk_mq_alloc_disk Christoph Hellwig @ 2024-02-14 11:32 ` Damien Le Moal 0 siblings, 0 replies; 20+ messages in thread From: Damien Le Moal @ 2024-02-14 11:32 UTC (permalink / raw) To: Christoph Hellwig, Jens Axboe; +Cc: linux-block On 2/14/24 18:55, Christoph Hellwig wrote: > Pass the queue limits directly to blk_mq_alloc_disk instead of > setting them one at a time. > > Signed-off-by: Christoph Hellwig <hch@lst.de> Looks good to me. Reviewed-by: Damien Le Moal <dlemoal@kernel.org> -- Damien Le Moal Western Digital Research ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: drop bio mode from null_blk and convert it to atomic queue limits 2024-02-14 9:54 drop bio mode from null_blk and convert it to atomic queue limits Christoph Hellwig ` (4 preceding siblings ...) 2024-02-14 9:55 ` [PATCH 5/5] null_blk: pass queue_limits to blk_mq_alloc_disk Christoph Hellwig @ 2024-02-14 14:08 ` Johannes Thumshirn 5 siblings, 0 replies; 20+ messages in thread From: Johannes Thumshirn @ 2024-02-14 14:08 UTC (permalink / raw) To: Christoph Hellwig, Jens Axboe; +Cc: linux-block@vger.kernel.org For the series, Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> ^ permalink raw reply [flat|nested] 20+ messages in thread
* drop bio mode from null_blk and convert it to atomic queue limits v2 @ 2024-02-19 6:29 Christoph Hellwig 2024-02-19 6:29 ` [PATCH 3/5] null_blk: refactor tag_set setup Christoph Hellwig 0 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2024-02-19 6:29 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block Hi Jens, this series drops the obsolete bio mode from the null_blk driver and then converts the driver to pass the queue limits to blk_mq_alloc_disk. Note: this series sits on top of the "pass queue_limits to blk_alloc_disk for simple drivers" series now. Changes since v1: - add an incremental from Damien to make sure the zoned tunable are properly taken into account Diffstat: main.c | 502 +++++++++++++++---------------------------------------------- null_blk.h | 19 -- trace.h | 5 zoned.c | 25 +-- 4 files changed, 139 insertions(+), 412 deletions(-) ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 3/5] null_blk: refactor tag_set setup 2024-02-19 6:29 drop bio mode from null_blk and convert it to atomic queue limits v2 Christoph Hellwig @ 2024-02-19 6:29 ` Christoph Hellwig 0 siblings, 0 replies; 20+ messages in thread From: Christoph Hellwig @ 2024-02-19 6:29 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block, Damien Le Moal, Johannes Thumshirn Move the tagset initialization out of null_add_dev into a new null_setup_tagset helper, and move the shared vs local differences out of null_init_tag_set into the callers. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> --- drivers/block/null_blk/main.c | 106 ++++++++++++++++------------------ 1 file changed, 51 insertions(+), 55 deletions(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 89e63d1c610362..03c3917a56fa28 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -1759,55 +1759,65 @@ static int null_gendisk_register(struct nullb *nullb) return add_disk(disk); } -static int null_init_tag_set(struct nullb *nullb, struct blk_mq_tag_set *set) +static int null_init_tag_set(struct blk_mq_tag_set *set, int poll_queues) { - unsigned int flags = BLK_MQ_F_SHOULD_MERGE; - int hw_queues, numa_node; - unsigned int queue_depth; - int poll_queues; - - if (nullb) { - hw_queues = nullb->dev->submit_queues; - poll_queues = nullb->dev->poll_queues; - queue_depth = nullb->dev->hw_queue_depth; - numa_node = nullb->dev->home_node; - if (nullb->dev->no_sched) - flags |= BLK_MQ_F_NO_SCHED; - if (nullb->dev->shared_tag_bitmap) - flags |= BLK_MQ_F_TAG_HCTX_SHARED; - if (nullb->dev->blocking) - flags |= BLK_MQ_F_BLOCKING; - } else { - hw_queues = g_submit_queues; - poll_queues = g_poll_queues; - queue_depth = g_hw_queue_depth; - numa_node = g_home_node; - if (g_no_sched) - flags |= BLK_MQ_F_NO_SCHED; - if (g_shared_tag_bitmap) - flags |= BLK_MQ_F_TAG_HCTX_SHARED; - if (g_blocking) - flags |= BLK_MQ_F_BLOCKING; - } - set->ops = &null_mq_ops; - set->cmd_size = sizeof(struct nullb_cmd); - set->flags = flags; - set->driver_data = nullb; - set->nr_hw_queues = hw_queues; - set->queue_depth = queue_depth; - set->numa_node = numa_node; + set->cmd_size = sizeof(struct nullb_cmd); set->timeout = 5 * HZ; + set->nr_maps = 1; if (poll_queues) { set->nr_hw_queues += poll_queues; - set->nr_maps = 3; - } else { - set->nr_maps = 1; + set->nr_maps += 2; } - return blk_mq_alloc_tag_set(set); } +static int null_init_global_tag_set(void) +{ + int error; + + if (tag_set.ops) + return 0; + + tag_set.nr_hw_queues = g_submit_queues; + tag_set.queue_depth = g_hw_queue_depth; + tag_set.numa_node = g_home_node; + tag_set.flags = BLK_MQ_F_SHOULD_MERGE; + if (g_no_sched) + tag_set.flags |= BLK_MQ_F_NO_SCHED; + if (g_shared_tag_bitmap) + tag_set.flags |= BLK_MQ_F_TAG_HCTX_SHARED; + if (g_blocking) + tag_set.flags |= BLK_MQ_F_BLOCKING; + + error = null_init_tag_set(&tag_set, g_poll_queues); + if (error) + tag_set.ops = NULL; + return error; +} + +static int null_setup_tagset(struct nullb *nullb) +{ + if (nullb->dev->shared_tags) { + nullb->tag_set = &tag_set; + return null_init_global_tag_set(); + } + + nullb->tag_set = &nullb->__tag_set; + nullb->tag_set->driver_data = nullb; + nullb->tag_set->nr_hw_queues = nullb->dev->submit_queues; + nullb->tag_set->queue_depth = nullb->dev->hw_queue_depth; + nullb->tag_set->numa_node = nullb->dev->home_node; + nullb->tag_set->flags = BLK_MQ_F_SHOULD_MERGE; + if (nullb->dev->no_sched) + nullb->tag_set->flags |= BLK_MQ_F_NO_SCHED; + if (nullb->dev->shared_tag_bitmap) + nullb->tag_set->flags |= BLK_MQ_F_TAG_HCTX_SHARED; + if (nullb->dev->blocking) + nullb->tag_set->flags |= BLK_MQ_F_BLOCKING; + return null_init_tag_set(nullb->tag_set, nullb->dev->poll_queues); +} + static int null_validate_conf(struct nullb_device *dev) { if (dev->queue_mode == NULL_Q_RQ) { @@ -1904,21 +1914,7 @@ static int null_add_dev(struct nullb_device *dev) if (rv) goto out_free_nullb; - if (dev->shared_tags) { - if (!tag_set.ops) { - rv = null_init_tag_set(NULL, &tag_set); - if (rv) { - tag_set.ops = NULL; - goto out_cleanup_queues; - } - } - nullb->tag_set = &tag_set; - rv = 0; - } else { - nullb->tag_set = &nullb->__tag_set; - rv = null_init_tag_set(nullb, nullb->tag_set); - } - + rv = null_setup_tagset(nullb); if (rv) goto out_cleanup_queues; -- 2.39.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* drop bio mode from null_blk and convert it to atomic queue limits v3 @ 2024-02-20 5:32 Christoph Hellwig 2024-02-20 5:33 ` [PATCH 3/5] null_blk: refactor tag_set setup Christoph Hellwig 0 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2024-02-20 5:32 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block Hi Jens, this series drops the obsolete bio mode from the null_blk driver and then converts the driver to pass the queue limits to blk_mq_alloc_disk. Changes since v2: - rebase on top of the blk_alloc_disk prototype change Changes since v1: - add an incremental from Damien to make sure the zoned tunable are properly taken into account Diffstat: main.c | 503 +++++++++++++++---------------------------------------------- null_blk.h | 19 -- trace.h | 5 zoned.c | 25 +-- 4 files changed, 139 insertions(+), 413 deletions(-) ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 3/5] null_blk: refactor tag_set setup 2024-02-20 5:32 drop bio mode from null_blk and convert it to atomic queue limits v3 Christoph Hellwig @ 2024-02-20 5:33 ` Christoph Hellwig 2024-02-20 7:22 ` Hannes Reinecke 0 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2024-02-20 5:33 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block, Damien Le Moal, Johannes Thumshirn Move the tagset initialization out of null_add_dev into a new null_setup_tagset helper, and move the shared vs local differences out of null_init_tag_set into the callers. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Tested-by: Damien Le Moal <dlemoal@kernel.org> --- drivers/block/null_blk/main.c | 106 ++++++++++++++++------------------ 1 file changed, 51 insertions(+), 55 deletions(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 89e63d1c610362..03c3917a56fa28 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -1759,55 +1759,65 @@ static int null_gendisk_register(struct nullb *nullb) return add_disk(disk); } -static int null_init_tag_set(struct nullb *nullb, struct blk_mq_tag_set *set) +static int null_init_tag_set(struct blk_mq_tag_set *set, int poll_queues) { - unsigned int flags = BLK_MQ_F_SHOULD_MERGE; - int hw_queues, numa_node; - unsigned int queue_depth; - int poll_queues; - - if (nullb) { - hw_queues = nullb->dev->submit_queues; - poll_queues = nullb->dev->poll_queues; - queue_depth = nullb->dev->hw_queue_depth; - numa_node = nullb->dev->home_node; - if (nullb->dev->no_sched) - flags |= BLK_MQ_F_NO_SCHED; - if (nullb->dev->shared_tag_bitmap) - flags |= BLK_MQ_F_TAG_HCTX_SHARED; - if (nullb->dev->blocking) - flags |= BLK_MQ_F_BLOCKING; - } else { - hw_queues = g_submit_queues; - poll_queues = g_poll_queues; - queue_depth = g_hw_queue_depth; - numa_node = g_home_node; - if (g_no_sched) - flags |= BLK_MQ_F_NO_SCHED; - if (g_shared_tag_bitmap) - flags |= BLK_MQ_F_TAG_HCTX_SHARED; - if (g_blocking) - flags |= BLK_MQ_F_BLOCKING; - } - set->ops = &null_mq_ops; - set->cmd_size = sizeof(struct nullb_cmd); - set->flags = flags; - set->driver_data = nullb; - set->nr_hw_queues = hw_queues; - set->queue_depth = queue_depth; - set->numa_node = numa_node; + set->cmd_size = sizeof(struct nullb_cmd); set->timeout = 5 * HZ; + set->nr_maps = 1; if (poll_queues) { set->nr_hw_queues += poll_queues; - set->nr_maps = 3; - } else { - set->nr_maps = 1; + set->nr_maps += 2; } - return blk_mq_alloc_tag_set(set); } +static int null_init_global_tag_set(void) +{ + int error; + + if (tag_set.ops) + return 0; + + tag_set.nr_hw_queues = g_submit_queues; + tag_set.queue_depth = g_hw_queue_depth; + tag_set.numa_node = g_home_node; + tag_set.flags = BLK_MQ_F_SHOULD_MERGE; + if (g_no_sched) + tag_set.flags |= BLK_MQ_F_NO_SCHED; + if (g_shared_tag_bitmap) + tag_set.flags |= BLK_MQ_F_TAG_HCTX_SHARED; + if (g_blocking) + tag_set.flags |= BLK_MQ_F_BLOCKING; + + error = null_init_tag_set(&tag_set, g_poll_queues); + if (error) + tag_set.ops = NULL; + return error; +} + +static int null_setup_tagset(struct nullb *nullb) +{ + if (nullb->dev->shared_tags) { + nullb->tag_set = &tag_set; + return null_init_global_tag_set(); + } + + nullb->tag_set = &nullb->__tag_set; + nullb->tag_set->driver_data = nullb; + nullb->tag_set->nr_hw_queues = nullb->dev->submit_queues; + nullb->tag_set->queue_depth = nullb->dev->hw_queue_depth; + nullb->tag_set->numa_node = nullb->dev->home_node; + nullb->tag_set->flags = BLK_MQ_F_SHOULD_MERGE; + if (nullb->dev->no_sched) + nullb->tag_set->flags |= BLK_MQ_F_NO_SCHED; + if (nullb->dev->shared_tag_bitmap) + nullb->tag_set->flags |= BLK_MQ_F_TAG_HCTX_SHARED; + if (nullb->dev->blocking) + nullb->tag_set->flags |= BLK_MQ_F_BLOCKING; + return null_init_tag_set(nullb->tag_set, nullb->dev->poll_queues); +} + static int null_validate_conf(struct nullb_device *dev) { if (dev->queue_mode == NULL_Q_RQ) { @@ -1904,21 +1914,7 @@ static int null_add_dev(struct nullb_device *dev) if (rv) goto out_free_nullb; - if (dev->shared_tags) { - if (!tag_set.ops) { - rv = null_init_tag_set(NULL, &tag_set); - if (rv) { - tag_set.ops = NULL; - goto out_cleanup_queues; - } - } - nullb->tag_set = &tag_set; - rv = 0; - } else { - nullb->tag_set = &nullb->__tag_set; - rv = null_init_tag_set(nullb, nullb->tag_set); - } - + rv = null_setup_tagset(nullb); if (rv) goto out_cleanup_queues; -- 2.39.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 3/5] null_blk: refactor tag_set setup 2024-02-20 5:33 ` [PATCH 3/5] null_blk: refactor tag_set setup Christoph Hellwig @ 2024-02-20 7:22 ` Hannes Reinecke 0 siblings, 0 replies; 20+ messages in thread From: Hannes Reinecke @ 2024-02-20 7:22 UTC (permalink / raw) To: Christoph Hellwig, Jens Axboe Cc: linux-block, Damien Le Moal, Johannes Thumshirn On 2/20/24 06:33, Christoph Hellwig wrote: > Move the tagset initialization out of null_add_dev into a new > null_setup_tagset helper, and move the shared vs local differences > out of null_init_tag_set into the callers. > > Signed-off-by: Christoph Hellwig <hch@lst.de> > Reviewed-by: Damien Le Moal <dlemoal@kernel.org> > Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> > Tested-by: Damien Le Moal <dlemoal@kernel.org> > --- > drivers/block/null_blk/main.c | 106 ++++++++++++++++------------------ > 1 file changed, 51 insertions(+), 55 deletions(-) > Reviewed-by: Hannes Reinecke <hare@suse.de> Cheers, Hannes -- Dr. Hannes Reinecke Kernel Storage Architect hare@suse.de +49 911 74053 688 SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich ^ permalink raw reply [flat|nested] 20+ messages in thread
* drop bio mode from null_blk and convert it to atomic queue limits v4 @ 2024-02-20 9:32 Christoph Hellwig 2024-02-20 9:32 ` [PATCH 3/5] null_blk: refactor tag_set setup Christoph Hellwig 0 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2024-02-20 9:32 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block Hi Jens, sorry for spamming you twice in a day with this series, but the buildbot decided to send me a delayed warning just after posting the previous series, so I've fixed it up and resent. this series drops the obsolete bio mode from the null_blk driver and then converts the driver to pass the queue limits to blk_mq_alloc_disk. Changes since v3: - fix the !BLK_DEV_ZONE compilation Changes since v2: - rebase on top of the blk_alloc_disk prototype change Changes since v1: - add an incremental from Damien to make sure the zoned tunable are properly taken into account Diffstat: main.c | 503 +++++++++++++++---------------------------------------------- null_blk.h | 19 -- trace.h | 5 zoned.c | 25 +-- 4 files changed, 139 insertions(+), 413 deletions(-) ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 3/5] null_blk: refactor tag_set setup 2024-02-20 9:32 drop bio mode from null_blk and convert it to atomic queue limits v4 Christoph Hellwig @ 2024-02-20 9:32 ` Christoph Hellwig 0 siblings, 0 replies; 20+ messages in thread From: Christoph Hellwig @ 2024-02-20 9:32 UTC (permalink / raw) To: Jens Axboe Cc: linux-block, Damien Le Moal, Hannes Reinecke, Johannes Thumshirn Move the tagset initialization out of null_add_dev into a new null_setup_tagset helper, and move the shared vs local differences out of null_init_tag_set into the callers. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Tested-by: Damien Le Moal <dlemoal@kernel.org> --- drivers/block/null_blk/main.c | 106 ++++++++++++++++------------------ 1 file changed, 51 insertions(+), 55 deletions(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 89e63d1c610362..03c3917a56fa28 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -1759,55 +1759,65 @@ static int null_gendisk_register(struct nullb *nullb) return add_disk(disk); } -static int null_init_tag_set(struct nullb *nullb, struct blk_mq_tag_set *set) +static int null_init_tag_set(struct blk_mq_tag_set *set, int poll_queues) { - unsigned int flags = BLK_MQ_F_SHOULD_MERGE; - int hw_queues, numa_node; - unsigned int queue_depth; - int poll_queues; - - if (nullb) { - hw_queues = nullb->dev->submit_queues; - poll_queues = nullb->dev->poll_queues; - queue_depth = nullb->dev->hw_queue_depth; - numa_node = nullb->dev->home_node; - if (nullb->dev->no_sched) - flags |= BLK_MQ_F_NO_SCHED; - if (nullb->dev->shared_tag_bitmap) - flags |= BLK_MQ_F_TAG_HCTX_SHARED; - if (nullb->dev->blocking) - flags |= BLK_MQ_F_BLOCKING; - } else { - hw_queues = g_submit_queues; - poll_queues = g_poll_queues; - queue_depth = g_hw_queue_depth; - numa_node = g_home_node; - if (g_no_sched) - flags |= BLK_MQ_F_NO_SCHED; - if (g_shared_tag_bitmap) - flags |= BLK_MQ_F_TAG_HCTX_SHARED; - if (g_blocking) - flags |= BLK_MQ_F_BLOCKING; - } - set->ops = &null_mq_ops; - set->cmd_size = sizeof(struct nullb_cmd); - set->flags = flags; - set->driver_data = nullb; - set->nr_hw_queues = hw_queues; - set->queue_depth = queue_depth; - set->numa_node = numa_node; + set->cmd_size = sizeof(struct nullb_cmd); set->timeout = 5 * HZ; + set->nr_maps = 1; if (poll_queues) { set->nr_hw_queues += poll_queues; - set->nr_maps = 3; - } else { - set->nr_maps = 1; + set->nr_maps += 2; } - return blk_mq_alloc_tag_set(set); } +static int null_init_global_tag_set(void) +{ + int error; + + if (tag_set.ops) + return 0; + + tag_set.nr_hw_queues = g_submit_queues; + tag_set.queue_depth = g_hw_queue_depth; + tag_set.numa_node = g_home_node; + tag_set.flags = BLK_MQ_F_SHOULD_MERGE; + if (g_no_sched) + tag_set.flags |= BLK_MQ_F_NO_SCHED; + if (g_shared_tag_bitmap) + tag_set.flags |= BLK_MQ_F_TAG_HCTX_SHARED; + if (g_blocking) + tag_set.flags |= BLK_MQ_F_BLOCKING; + + error = null_init_tag_set(&tag_set, g_poll_queues); + if (error) + tag_set.ops = NULL; + return error; +} + +static int null_setup_tagset(struct nullb *nullb) +{ + if (nullb->dev->shared_tags) { + nullb->tag_set = &tag_set; + return null_init_global_tag_set(); + } + + nullb->tag_set = &nullb->__tag_set; + nullb->tag_set->driver_data = nullb; + nullb->tag_set->nr_hw_queues = nullb->dev->submit_queues; + nullb->tag_set->queue_depth = nullb->dev->hw_queue_depth; + nullb->tag_set->numa_node = nullb->dev->home_node; + nullb->tag_set->flags = BLK_MQ_F_SHOULD_MERGE; + if (nullb->dev->no_sched) + nullb->tag_set->flags |= BLK_MQ_F_NO_SCHED; + if (nullb->dev->shared_tag_bitmap) + nullb->tag_set->flags |= BLK_MQ_F_TAG_HCTX_SHARED; + if (nullb->dev->blocking) + nullb->tag_set->flags |= BLK_MQ_F_BLOCKING; + return null_init_tag_set(nullb->tag_set, nullb->dev->poll_queues); +} + static int null_validate_conf(struct nullb_device *dev) { if (dev->queue_mode == NULL_Q_RQ) { @@ -1904,21 +1914,7 @@ static int null_add_dev(struct nullb_device *dev) if (rv) goto out_free_nullb; - if (dev->shared_tags) { - if (!tag_set.ops) { - rv = null_init_tag_set(NULL, &tag_set); - if (rv) { - tag_set.ops = NULL; - goto out_cleanup_queues; - } - } - nullb->tag_set = &tag_set; - rv = 0; - } else { - nullb->tag_set = &nullb->__tag_set; - rv = null_init_tag_set(nullb, nullb->tag_set); - } - + rv = null_setup_tagset(nullb); if (rv) goto out_cleanup_queues; -- 2.39.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
end of thread, other threads:[~2024-02-20 9:32 UTC | newest] Thread overview: 20+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-02-14 9:54 drop bio mode from null_blk and convert it to atomic queue limits Christoph Hellwig 2024-02-14 9:54 ` [PATCH 1/5] null_blk: remove the bio based I/O path Christoph Hellwig 2024-02-14 11:25 ` Damien Le Moal 2024-02-14 17:25 ` Keith Busch 2024-02-14 23:16 ` Damien Le Moal 2024-02-14 23:34 ` Keith Busch 2024-02-15 8:05 ` Christoph Hellwig 2024-02-14 9:54 ` [PATCH 2/5] null_blk: initialize the tag_set timeout in null_init_tag_set Christoph Hellwig 2024-02-14 11:26 ` Damien Le Moal 2024-02-14 9:54 ` [PATCH 3/5] null_blk: refactor tag_set setup Christoph Hellwig 2024-02-14 11:29 ` Damien Le Moal 2024-02-14 9:55 ` [PATCH 4/5] null_blk: remove null_gendisk_register Christoph Hellwig 2024-02-14 11:30 ` Damien Le Moal 2024-02-14 9:55 ` [PATCH 5/5] null_blk: pass queue_limits to blk_mq_alloc_disk Christoph Hellwig 2024-02-14 11:32 ` Damien Le Moal 2024-02-14 14:08 ` drop bio mode from null_blk and convert it to atomic queue limits Johannes Thumshirn -- strict thread matches above, loose matches on Subject: below -- 2024-02-19 6:29 drop bio mode from null_blk and convert it to atomic queue limits v2 Christoph Hellwig 2024-02-19 6:29 ` [PATCH 3/5] null_blk: refactor tag_set setup Christoph Hellwig 2024-02-20 5:32 drop bio mode from null_blk and convert it to atomic queue limits v3 Christoph Hellwig 2024-02-20 5:33 ` [PATCH 3/5] null_blk: refactor tag_set setup Christoph Hellwig 2024-02-20 7:22 ` Hannes Reinecke 2024-02-20 9:32 drop bio mode from null_blk and convert it to atomic queue limits v4 Christoph Hellwig 2024-02-20 9:32 ` [PATCH 3/5] null_blk: refactor tag_set setup Christoph Hellwig
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.