]> Gentwo Git Trees - linux/.git/commitdiff
block: move elevator tags into struct elevator_resources
authorNilay Shroff <nilay@linux.ibm.com>
Thu, 13 Nov 2025 08:58:19 +0000 (14:28 +0530)
committerJens Axboe <axboe@kernel.dk>
Thu, 13 Nov 2025 16:27:49 +0000 (09:27 -0700)
This patch introduces a new structure, struct elevator_resources, to
group together all elevator-related resources that share the same
lifetime. As a first step, this change moves the elevator tag pointer
from struct elv_change_ctx into the new struct elevator_resources.

Additionally, rename blk_mq_alloc_sched_tags_batch() and
blk_mq_free_sched_tags_batch() to blk_mq_alloc_sched_res_batch() and
blk_mq_free_sched_res_batch(), respectively. Introduce two new wrapper
helpers, blk_mq_alloc_sched_res() and blk_mq_free_sched_res(), around
blk_mq_alloc_sched_tags() and blk_mq_free_sched_tags().

These changes pave the way for consolidating the allocation and freeing
of elevator-specific resources into common helper functions. This
refactoring improves encapsulation and prepares the code for future
extensions, allowing additional elevator-specific data to be added to
struct elevator_resources without cluttering struct elv_change_ctx.

Subsequent patches will extend struct elevator_resources to include
other elevator-related data.

Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Yu Kuai <yukuai@fnnas.com>
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-mq-sched.c
block/blk-mq-sched.h
block/blk-mq.c
block/elevator.c
block/elevator.h

index 7ba285a7759b3bcdd0ce2028dabad2b12525af5e..32ae57518298d455155278cb26e9509c97afeb0e 100644 (file)
@@ -427,7 +427,16 @@ void blk_mq_free_sched_tags(struct elevator_tags *et,
        kfree(et);
 }
 
-void blk_mq_free_sched_tags_batch(struct xarray *elv_tbl,
+void blk_mq_free_sched_res(struct elevator_resources *res,
+               struct blk_mq_tag_set *set)
+{
+       if (res->et) {
+               blk_mq_free_sched_tags(res->et, set);
+               res->et = NULL;
+       }
+}
+
+void blk_mq_free_sched_res_batch(struct xarray *elv_tbl,
                struct blk_mq_tag_set *set)
 {
        struct request_queue *q;
@@ -445,12 +454,11 @@ void blk_mq_free_sched_tags_batch(struct xarray *elv_tbl,
                 */
                if (q->elevator) {
                        ctx = xa_load(elv_tbl, q->id);
-                       if (!ctx || !ctx->et) {
+                       if (!ctx) {
                                WARN_ON_ONCE(1);
                                continue;
                        }
-                       blk_mq_free_sched_tags(ctx->et, set);
-                       ctx->et = NULL;
+                       blk_mq_free_sched_res(&ctx->res, set);
                }
        }
 }
@@ -531,12 +539,24 @@ struct elevator_tags *blk_mq_alloc_sched_tags(struct blk_mq_tag_set *set,
        return NULL;
 }
 
-int blk_mq_alloc_sched_tags_batch(struct xarray *elv_tbl,
+int blk_mq_alloc_sched_res(struct request_queue *q,
+               struct elevator_resources *res, unsigned int nr_hw_queues)
+{
+       struct blk_mq_tag_set *set = q->tag_set;
+
+       res->et = blk_mq_alloc_sched_tags(set, nr_hw_queues,
+                       blk_mq_default_nr_requests(set));
+       if (!res->et)
+               return -ENOMEM;
+
+       return 0;
+}
+
+int blk_mq_alloc_sched_res_batch(struct xarray *elv_tbl,
                struct blk_mq_tag_set *set, unsigned int nr_hw_queues)
 {
        struct elv_change_ctx *ctx;
        struct request_queue *q;
-       struct elevator_tags *et;
        int ret = -ENOMEM;
 
        lockdep_assert_held_write(&set->update_nr_hwq_lock);
@@ -556,11 +576,10 @@ int blk_mq_alloc_sched_tags_batch(struct xarray *elv_tbl,
                                goto out_unwind;
                        }
 
-                       ctx->et = blk_mq_alloc_sched_tags(set, nr_hw_queues,
-                                       blk_mq_default_nr_requests(set));
-                       if (!ctx->et)
+                       ret = blk_mq_alloc_sched_res(q, &ctx->res,
+                                       nr_hw_queues);
+                       if (ret)
                                goto out_unwind;
-
                }
        }
        return 0;
@@ -568,10 +587,8 @@ int blk_mq_alloc_sched_tags_batch(struct xarray *elv_tbl,
        list_for_each_entry_continue_reverse(q, &set->tag_list, tag_set_list) {
                if (q->elevator) {
                        ctx = xa_load(elv_tbl, q->id);
-                       if (ctx && ctx->et) {
-                               blk_mq_free_sched_tags(ctx->et, set);
-                               ctx->et = NULL;
-                       }
+                       if (ctx)
+                               blk_mq_free_sched_res(&ctx->res, set);
                }
        }
        return ret;
@@ -579,9 +596,10 @@ int blk_mq_alloc_sched_tags_batch(struct xarray *elv_tbl,
 
 /* caller must have a reference to @e, will grab another one if successful */
 int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e,
-               struct elevator_tags *et)
+               struct elevator_resources *res)
 {
        unsigned int flags = q->tag_set->flags;
+       struct elevator_tags *et = res->et;
        struct blk_mq_hw_ctx *hctx;
        struct elevator_queue *eq;
        unsigned long i;
index 2fddbc91a23595b0d6b9a764f8ff27a1b2c2c24c..1f8e58dd4b497a9ebbeb5bc7d1096e5106ff8497 100644 (file)
@@ -19,20 +19,24 @@ void __blk_mq_sched_restart(struct blk_mq_hw_ctx *hctx);
 void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx);
 
 int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e,
-               struct elevator_tags *et);
+               struct elevator_resources *res);
 void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e);
 void blk_mq_sched_free_rqs(struct request_queue *q);
 
 struct elevator_tags *blk_mq_alloc_sched_tags(struct blk_mq_tag_set *set,
                unsigned int nr_hw_queues, unsigned int nr_requests);
-int blk_mq_alloc_sched_tags_batch(struct xarray *et_table,
+int blk_mq_alloc_sched_res(struct request_queue *q,
+               struct elevator_resources *res, unsigned int nr_hw_queues);
+int blk_mq_alloc_sched_res_batch(struct xarray *elv_tbl,
                struct blk_mq_tag_set *set, unsigned int nr_hw_queues);
 int blk_mq_alloc_sched_ctx_batch(struct xarray *elv_tbl,
                struct blk_mq_tag_set *set);
 void blk_mq_free_sched_ctx_batch(struct xarray *elv_tbl);
 void blk_mq_free_sched_tags(struct elevator_tags *et,
                struct blk_mq_tag_set *set);
-void blk_mq_free_sched_tags_batch(struct xarray *et_table,
+void blk_mq_free_sched_res(struct elevator_resources *res,
+               struct blk_mq_tag_set *set);
+void blk_mq_free_sched_res_batch(struct xarray *et_table,
                struct blk_mq_tag_set *set);
 
 static inline void blk_mq_sched_restart(struct blk_mq_hw_ctx *hctx)
index 04c6356f0eb2428316e24439cfb1bfa1e3146bd8..0d38daaa4705c943744ba236fd93393220f856ac 100644 (file)
@@ -5072,7 +5072,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
        if (blk_mq_alloc_sched_ctx_batch(&elv_tbl, set) < 0)
                goto out_free_ctx;
 
-       if (blk_mq_alloc_sched_tags_batch(&elv_tbl, set, nr_hw_queues) < 0)
+       if (blk_mq_alloc_sched_res_batch(&elv_tbl, set, nr_hw_queues) < 0)
                goto out_free_ctx;
 
        list_for_each_entry(q, &set->tag_list, tag_set_list) {
index cd7bdff205c8c21c9aa48f017ab1532648de4de4..cbec292a4af5b123c8f274bb54754737c14f913a 100644 (file)
@@ -580,7 +580,7 @@ static int elevator_switch(struct request_queue *q, struct elv_change_ctx *ctx)
        }
 
        if (new_e) {
-               ret = blk_mq_init_sched(q, new_e, ctx->et);
+               ret = blk_mq_init_sched(q, new_e, &ctx->res);
                if (ret)
                        goto out_unfreeze;
                ctx->new = q->elevator;
@@ -604,7 +604,8 @@ static int elevator_switch(struct request_queue *q, struct elv_change_ctx *ctx)
        return ret;
 }
 
-static void elv_exit_and_release(struct request_queue *q)
+static void elv_exit_and_release(struct elv_change_ctx *ctx,
+               struct request_queue *q)
 {
        struct elevator_queue *e;
        unsigned memflags;
@@ -616,7 +617,7 @@ static void elv_exit_and_release(struct request_queue *q)
        mutex_unlock(&q->elevator_lock);
        blk_mq_unfreeze_queue(q, memflags);
        if (e) {
-               blk_mq_free_sched_tags(e->et, q->tag_set);
+               blk_mq_free_sched_res(&ctx->res, q->tag_set);
                kobject_put(&e->kobj);
        }
 }
@@ -627,11 +628,12 @@ static int elevator_change_done(struct request_queue *q,
        int ret = 0;
 
        if (ctx->old) {
+               struct elevator_resources res = {.et = ctx->old->et};
                bool enable_wbt = test_bit(ELEVATOR_FLAG_ENABLE_WBT_ON_EXIT,
                                &ctx->old->flags);
 
                elv_unregister_queue(q, ctx->old);
-               blk_mq_free_sched_tags(ctx->old->et, q->tag_set);
+               blk_mq_free_sched_res(&res, q->tag_set);
                kobject_put(&ctx->old->kobj);
                if (enable_wbt)
                        wbt_enable_default(q->disk);
@@ -639,7 +641,7 @@ static int elevator_change_done(struct request_queue *q,
        if (ctx->new) {
                ret = elv_register_queue(q, ctx->new, !ctx->no_uevent);
                if (ret)
-                       elv_exit_and_release(q);
+                       elv_exit_and_release(ctx, q);
        }
        return ret;
 }
@@ -656,10 +658,9 @@ static int elevator_change(struct request_queue *q, struct elv_change_ctx *ctx)
        lockdep_assert_held(&set->update_nr_hwq_lock);
 
        if (strncmp(ctx->name, "none", 4)) {
-               ctx->et = blk_mq_alloc_sched_tags(set, set->nr_hw_queues,
-                               blk_mq_default_nr_requests(set));
-               if (!ctx->et)
-                       return -ENOMEM;
+               ret = blk_mq_alloc_sched_res(q, &ctx->res, set->nr_hw_queues);
+               if (ret)
+                       return ret;
        }
 
        memflags = blk_mq_freeze_queue(q);
@@ -681,10 +682,10 @@ static int elevator_change(struct request_queue *q, struct elv_change_ctx *ctx)
        if (!ret)
                ret = elevator_change_done(q, ctx);
        /*
-        * Free sched tags if it's allocated but we couldn't switch elevator.
+        * Free sched resource if it's allocated but we couldn't switch elevator.
         */
-       if (ctx->et && !ctx->new)
-               blk_mq_free_sched_tags(ctx->et, set);
+       if (!ctx->new)
+               blk_mq_free_sched_res(&ctx->res, set);
 
        return ret;
 }
@@ -711,10 +712,10 @@ void elv_update_nr_hw_queues(struct request_queue *q,
        if (!ret)
                WARN_ON_ONCE(elevator_change_done(q, ctx));
        /*
-        * Free sched tags if it's allocated but we couldn't switch elevator.
+        * Free sched resource if it's allocated but we couldn't switch elevator.
         */
-       if (ctx->et && !ctx->new)
-               blk_mq_free_sched_tags(ctx->et, set);
+       if (!ctx->new)
+               blk_mq_free_sched_res(&ctx->res, set);
 }
 
 /*
index bad43182361e5c6a86bf057a2da2aab6dc9ab33a..621a63597249e75b96a606368b6d4dbad0e9e377 100644 (file)
@@ -32,6 +32,11 @@ struct elevator_tags {
        struct blk_mq_tags *tags[];
 };
 
+struct elevator_resources {
+       /* holds elevator tags */
+       struct elevator_tags *et;
+};
+
 /* Holding context data for changing elevator */
 struct elv_change_ctx {
        const char *name;
@@ -43,8 +48,8 @@ struct elv_change_ctx {
        struct elevator_queue *new;
        /* store elevator type */
        struct elevator_type *type;
-       /* holds sched tags data */
-       struct elevator_tags *et;
+       /* store elevator resources */
+       struct elevator_resources res;
 };
 
 struct elevator_mq_ops {