mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
block: move elevator tags into struct elevator_resources
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>
This commit is contained in:
@@ -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 @@ out:
|
||||
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 @@ out_unwind:
|
||||
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 @@ out_unwind:
|
||||
|
||||
/* 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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 @@ out_unfreeze:
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user