This is a note to let you know that I've just added the patch titled blk-rq-qos: make rq_qos_add and rq_qos_del more useful to the 6.1-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: blk-rq-qos-make-rq_qos_add-and-rq_qos_del-more-usefu.patch and it can be found in the queue-6.1 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit 581958da857b8e9faf3303ba6ebc2f7e0b7a15fe Author: Christoph Hellwig <hch@xxxxxx> Date: Fri Feb 3 16:03:54 2023 +0100 blk-rq-qos: make rq_qos_add and rq_qos_del more useful [ Upstream commit ce57b558604e68277d31ca5ce49ec4579a8618c5 ] Switch to passing a gendisk, and make rq_qos_add initialize all required fields and drop the not required q argument from rq_qos_del. Signed-off-by: Christoph Hellwig <hch@xxxxxx> Reviewed-by: Andreas Herrmann <aherrmann@xxxxxxx> Acked-by: Tejun Heo <tj@xxxxxxxxxx> Link: https://lore.kernel.org/r/20230203150400.3199230-14-hch@xxxxxx Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> Stable-dep-of: f814bdda774c ("blk-wbt: Fix detection of dirty-throttled tasks") Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 72ca07f24b3c0..a8a7d2ce927b9 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -2847,9 +2847,7 @@ static struct rq_qos_ops ioc_rqos_ops = { static int blk_iocost_init(struct gendisk *disk) { - struct request_queue *q = disk->queue; struct ioc *ioc; - struct rq_qos *rqos; int i, cpu, ret; ioc = kzalloc(sizeof(*ioc), GFP_KERNEL); @@ -2872,11 +2870,6 @@ static int blk_iocost_init(struct gendisk *disk) local64_set(&ccs->rq_wait_ns, 0); } - rqos = &ioc->rqos; - rqos->id = RQ_QOS_COST; - rqos->ops = &ioc_rqos_ops; - rqos->q = q; - spin_lock_init(&ioc->lock); timer_setup(&ioc->timer, ioc_timer_fn, 0); INIT_LIST_HEAD(&ioc->active_iocgs); @@ -2900,17 +2893,17 @@ static int blk_iocost_init(struct gendisk *disk) * called before policy activation completion, can't assume that the * target bio has an iocg associated and need to test for NULL iocg. */ - ret = rq_qos_add(q, rqos); + ret = rq_qos_add(&ioc->rqos, disk, RQ_QOS_COST, &ioc_rqos_ops); if (ret) goto err_free_ioc; - ret = blkcg_activate_policy(q, &blkcg_policy_iocost); + ret = blkcg_activate_policy(disk->queue, &blkcg_policy_iocost); if (ret) goto err_del_qos; return 0; err_del_qos: - rq_qos_del(q, rqos); + rq_qos_del(&ioc->rqos); err_free_ioc: free_percpu(ioc->pcpu_stat); kfree(ioc); diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c index 571fa95aafe96..c64cfec34ac37 100644 --- a/block/blk-iolatency.c +++ b/block/blk-iolatency.c @@ -758,24 +758,18 @@ static void blkiolatency_enable_work_fn(struct work_struct *work) int blk_iolatency_init(struct gendisk *disk) { - struct request_queue *q = disk->queue; struct blk_iolatency *blkiolat; - struct rq_qos *rqos; int ret; blkiolat = kzalloc(sizeof(*blkiolat), GFP_KERNEL); if (!blkiolat) return -ENOMEM; - rqos = &blkiolat->rqos; - rqos->id = RQ_QOS_LATENCY; - rqos->ops = &blkcg_iolatency_ops; - rqos->q = q; - - ret = rq_qos_add(q, rqos); + ret = rq_qos_add(&blkiolat->rqos, disk, RQ_QOS_LATENCY, + &blkcg_iolatency_ops); if (ret) goto err_free; - ret = blkcg_activate_policy(q, &blkcg_policy_iolatency); + ret = blkcg_activate_policy(disk->queue, &blkcg_policy_iolatency); if (ret) goto err_qos_del; @@ -785,7 +779,7 @@ int blk_iolatency_init(struct gendisk *disk) return 0; err_qos_del: - rq_qos_del(q, rqos); + rq_qos_del(&blkiolat->rqos); err_free: kfree(blkiolat); return ret; diff --git a/block/blk-rq-qos.c b/block/blk-rq-qos.c index aae98dcb01ebe..14bee1bd76136 100644 --- a/block/blk-rq-qos.c +++ b/block/blk-rq-qos.c @@ -295,8 +295,15 @@ void rq_qos_exit(struct request_queue *q) } } -int rq_qos_add(struct request_queue *q, struct rq_qos *rqos) +int rq_qos_add(struct rq_qos *rqos, struct gendisk *disk, enum rq_qos_id id, + struct rq_qos_ops *ops) { + struct request_queue *q = disk->queue; + + rqos->q = q; + rqos->id = id; + rqos->ops = ops; + /* * No IO can be in-flight when adding rqos, so freeze queue, which * is fine since we only support rq_qos for blk-mq queue. @@ -326,11 +333,11 @@ int rq_qos_add(struct request_queue *q, struct rq_qos *rqos) spin_unlock_irq(&q->queue_lock); blk_mq_unfreeze_queue(q); return -EBUSY; - } -void rq_qos_del(struct request_queue *q, struct rq_qos *rqos) +void rq_qos_del(struct rq_qos *rqos) { + struct request_queue *q = rqos->q; struct rq_qos **cur; /* diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h index 805eee8b031d0..22552785aa31e 100644 --- a/block/blk-rq-qos.h +++ b/block/blk-rq-qos.h @@ -85,8 +85,9 @@ static inline void rq_wait_init(struct rq_wait *rq_wait) init_waitqueue_head(&rq_wait->wait); } -int rq_qos_add(struct request_queue *q, struct rq_qos *rqos); -void rq_qos_del(struct request_queue *q, struct rq_qos *rqos); +int rq_qos_add(struct rq_qos *rqos, struct gendisk *disk, enum rq_qos_id id, + struct rq_qos_ops *ops); +void rq_qos_del(struct rq_qos *rqos); typedef bool (acquire_inflight_cb_t)(struct rq_wait *rqw, void *private_data); typedef void (cleanup_cb_t)(struct rq_wait *rqw, void *private_data); diff --git a/block/blk-wbt.c b/block/blk-wbt.c index 95bec9244e9f3..aec4e37c89c4a 100644 --- a/block/blk-wbt.c +++ b/block/blk-wbt.c @@ -842,9 +842,6 @@ int wbt_init(struct gendisk *disk) for (i = 0; i < WBT_NUM_RWQ; i++) rq_wait_init(&rwb->rq_wait[i]); - rwb->rqos.id = RQ_QOS_WBT; - rwb->rqos.ops = &wbt_rqos_ops; - rwb->rqos.q = q; rwb->last_comp = rwb->last_issue = jiffies; rwb->win_nsec = RWB_WINDOW_NSEC; rwb->enable_state = WBT_STATE_ON_DEFAULT; @@ -857,7 +854,7 @@ int wbt_init(struct gendisk *disk) /* * Assign rwb and add the stats callback. */ - ret = rq_qos_add(q, &rwb->rqos); + ret = rq_qos_add(&rwb->rqos, disk, RQ_QOS_WBT, &wbt_rqos_ops); if (ret) goto err_free;