mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
blk-mq-sched: provide hooks for initializing hardware queue data
Schedulers need to be informed when a hardware queue is added or removed at runtime so they can allocate/free per-hardware queue data. So, replace the blk_mq_sched_init_hctx_data() helper, which only makes sense at init time, with .init_hctx() and .exit_hctx() hooks. Signed-off-by: Omar Sandoval <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
This commit is contained in:
parent
65f619d253
commit
ee056f9812
3 changed files with 45 additions and 42 deletions
|
|
@ -30,43 +30,6 @@ void blk_mq_sched_free_hctx_data(struct request_queue *q,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(blk_mq_sched_free_hctx_data);
|
||||
|
||||
int blk_mq_sched_init_hctx_data(struct request_queue *q, size_t size,
|
||||
int (*init)(struct blk_mq_hw_ctx *),
|
||||
void (*exit)(struct blk_mq_hw_ctx *))
|
||||
{
|
||||
struct blk_mq_hw_ctx *hctx;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
queue_for_each_hw_ctx(q, hctx, i) {
|
||||
hctx->sched_data = kmalloc_node(size, GFP_KERNEL, hctx->numa_node);
|
||||
if (!hctx->sched_data) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (init) {
|
||||
ret = init(hctx);
|
||||
if (ret) {
|
||||
/*
|
||||
* We don't want to give exit() a partially
|
||||
* initialized sched_data. init() must clean up
|
||||
* if it fails.
|
||||
*/
|
||||
kfree(hctx->sched_data);
|
||||
hctx->sched_data = NULL;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
blk_mq_sched_free_hctx_data(q, exit);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_mq_sched_init_hctx_data);
|
||||
|
||||
static void __blk_mq_sched_assign_ioc(struct request_queue *q,
|
||||
struct request *rq,
|
||||
struct bio *bio,
|
||||
|
|
@ -508,11 +471,24 @@ int blk_mq_sched_init_hctx(struct request_queue *q, struct blk_mq_hw_ctx *hctx,
|
|||
unsigned int hctx_idx)
|
||||
{
|
||||
struct elevator_queue *e = q->elevator;
|
||||
int ret;
|
||||
|
||||
if (!e)
|
||||
return 0;
|
||||
|
||||
return blk_mq_sched_alloc_tags(q, hctx, hctx_idx);
|
||||
ret = blk_mq_sched_alloc_tags(q, hctx, hctx_idx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (e->type->ops.mq.init_hctx) {
|
||||
ret = e->type->ops.mq.init_hctx(hctx, hctx_idx);
|
||||
if (ret) {
|
||||
blk_mq_sched_free_tags(q->tag_set, hctx, hctx_idx);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void blk_mq_sched_exit_hctx(struct request_queue *q, struct blk_mq_hw_ctx *hctx,
|
||||
|
|
@ -523,12 +499,18 @@ void blk_mq_sched_exit_hctx(struct request_queue *q, struct blk_mq_hw_ctx *hctx,
|
|||
if (!e)
|
||||
return;
|
||||
|
||||
if (e->type->ops.mq.exit_hctx && hctx->sched_data) {
|
||||
e->type->ops.mq.exit_hctx(hctx, hctx_idx);
|
||||
hctx->sched_data = NULL;
|
||||
}
|
||||
|
||||
blk_mq_sched_free_tags(q->tag_set, hctx, hctx_idx);
|
||||
}
|
||||
|
||||
int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e)
|
||||
{
|
||||
struct blk_mq_hw_ctx *hctx;
|
||||
struct elevator_queue *eq;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
|
|
@ -553,6 +535,18 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e)
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (e->ops.mq.init_hctx) {
|
||||
queue_for_each_hw_ctx(q, hctx, i) {
|
||||
ret = e->ops.mq.init_hctx(hctx, i);
|
||||
if (ret) {
|
||||
eq = q->elevator;
|
||||
blk_mq_exit_sched(q, eq);
|
||||
kobject_put(&eq->kobj);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
|
@ -563,6 +557,17 @@ err:
|
|||
|
||||
void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e)
|
||||
{
|
||||
struct blk_mq_hw_ctx *hctx;
|
||||
unsigned int i;
|
||||
|
||||
if (e->type->ops.mq.exit_hctx) {
|
||||
queue_for_each_hw_ctx(q, hctx, i) {
|
||||
if (hctx->sched_data) {
|
||||
e->type->ops.mq.exit_hctx(hctx, i);
|
||||
hctx->sched_data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e->type->ops.mq.exit_sched)
|
||||
e->type->ops.mq.exit_sched(e);
|
||||
blk_mq_sched_tags_teardown(q);
|
||||
|
|
|
|||
|
|
@ -4,10 +4,6 @@
|
|||
#include "blk-mq.h"
|
||||
#include "blk-mq-tag.h"
|
||||
|
||||
int blk_mq_sched_init_hctx_data(struct request_queue *q, size_t size,
|
||||
int (*init)(struct blk_mq_hw_ctx *),
|
||||
void (*exit)(struct blk_mq_hw_ctx *));
|
||||
|
||||
void blk_mq_sched_free_hctx_data(struct request_queue *q,
|
||||
void (*exit)(struct blk_mq_hw_ctx *));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue