|
@@ -1036,10 +1036,11 @@ void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs)
|
|
|
EXPORT_SYMBOL(blk_mq_delay_queue);
|
|
|
|
|
|
static inline void __blk_mq_insert_req_list(struct blk_mq_hw_ctx *hctx,
|
|
|
- struct blk_mq_ctx *ctx,
|
|
|
struct request *rq,
|
|
|
bool at_head)
|
|
|
{
|
|
|
+ struct blk_mq_ctx *ctx = rq->mq_ctx;
|
|
|
+
|
|
|
trace_block_rq_insert(hctx->queue, rq);
|
|
|
|
|
|
if (at_head)
|
|
@@ -1053,20 +1054,16 @@ static void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx,
|
|
|
{
|
|
|
struct blk_mq_ctx *ctx = rq->mq_ctx;
|
|
|
|
|
|
- __blk_mq_insert_req_list(hctx, ctx, rq, at_head);
|
|
|
+ __blk_mq_insert_req_list(hctx, rq, at_head);
|
|
|
blk_mq_hctx_mark_pending(hctx, ctx);
|
|
|
}
|
|
|
|
|
|
void blk_mq_insert_request(struct request *rq, bool at_head, bool run_queue,
|
|
|
- bool async)
|
|
|
+ bool async)
|
|
|
{
|
|
|
+ struct blk_mq_ctx *ctx = rq->mq_ctx;
|
|
|
struct request_queue *q = rq->q;
|
|
|
struct blk_mq_hw_ctx *hctx;
|
|
|
- struct blk_mq_ctx *ctx = rq->mq_ctx, *current_ctx;
|
|
|
-
|
|
|
- current_ctx = blk_mq_get_ctx(q);
|
|
|
- if (!cpu_online(ctx->cpu))
|
|
|
- rq->mq_ctx = ctx = current_ctx;
|
|
|
|
|
|
hctx = q->mq_ops->map_queue(q, ctx->cpu);
|
|
|
|
|
@@ -1076,8 +1073,6 @@ void blk_mq_insert_request(struct request *rq, bool at_head, bool run_queue,
|
|
|
|
|
|
if (run_queue)
|
|
|
blk_mq_run_hw_queue(hctx, async);
|
|
|
-
|
|
|
- blk_mq_put_ctx(current_ctx);
|
|
|
}
|
|
|
|
|
|
static void blk_mq_insert_requests(struct request_queue *q,
|
|
@@ -1088,14 +1083,9 @@ static void blk_mq_insert_requests(struct request_queue *q,
|
|
|
|
|
|
{
|
|
|
struct blk_mq_hw_ctx *hctx;
|
|
|
- struct blk_mq_ctx *current_ctx;
|
|
|
|
|
|
trace_block_unplug(q, depth, !from_schedule);
|
|
|
|
|
|
- current_ctx = blk_mq_get_ctx(q);
|
|
|
-
|
|
|
- if (!cpu_online(ctx->cpu))
|
|
|
- ctx = current_ctx;
|
|
|
hctx = q->mq_ops->map_queue(q, ctx->cpu);
|
|
|
|
|
|
/*
|
|
@@ -1107,15 +1097,14 @@ static void blk_mq_insert_requests(struct request_queue *q,
|
|
|
struct request *rq;
|
|
|
|
|
|
rq = list_first_entry(list, struct request, queuelist);
|
|
|
+ BUG_ON(rq->mq_ctx != ctx);
|
|
|
list_del_init(&rq->queuelist);
|
|
|
- rq->mq_ctx = ctx;
|
|
|
- __blk_mq_insert_req_list(hctx, ctx, rq, false);
|
|
|
+ __blk_mq_insert_req_list(hctx, rq, false);
|
|
|
}
|
|
|
blk_mq_hctx_mark_pending(hctx, ctx);
|
|
|
spin_unlock(&ctx->lock);
|
|
|
|
|
|
blk_mq_run_hw_queue(hctx, from_schedule);
|
|
|
- blk_mq_put_ctx(current_ctx);
|
|
|
}
|
|
|
|
|
|
static int plug_ctx_cmp(void *priv, struct list_head *a, struct list_head *b)
|
|
@@ -1630,16 +1619,17 @@ static int blk_mq_alloc_bitmap(struct blk_mq_ctxmap *bitmap, int node)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * 'cpu' is going away. splice any existing rq_list entries from this
|
|
|
+ * software queue to the hw queue dispatch list, and ensure that it
|
|
|
+ * gets run.
|
|
|
+ */
|
|
|
static int blk_mq_hctx_cpu_offline(struct blk_mq_hw_ctx *hctx, int cpu)
|
|
|
{
|
|
|
- struct request_queue *q = hctx->queue;
|
|
|
struct blk_mq_ctx *ctx;
|
|
|
LIST_HEAD(tmp);
|
|
|
|
|
|
- /*
|
|
|
- * Move ctx entries to new CPU, if this one is going away.
|
|
|
- */
|
|
|
- ctx = __blk_mq_get_ctx(q, cpu);
|
|
|
+ ctx = __blk_mq_get_ctx(hctx->queue, cpu);
|
|
|
|
|
|
spin_lock(&ctx->lock);
|
|
|
if (!list_empty(&ctx->rq_list)) {
|
|
@@ -1651,24 +1641,11 @@ static int blk_mq_hctx_cpu_offline(struct blk_mq_hw_ctx *hctx, int cpu)
|
|
|
if (list_empty(&tmp))
|
|
|
return NOTIFY_OK;
|
|
|
|
|
|
- ctx = blk_mq_get_ctx(q);
|
|
|
- spin_lock(&ctx->lock);
|
|
|
-
|
|
|
- while (!list_empty(&tmp)) {
|
|
|
- struct request *rq;
|
|
|
-
|
|
|
- rq = list_first_entry(&tmp, struct request, queuelist);
|
|
|
- rq->mq_ctx = ctx;
|
|
|
- list_move_tail(&rq->queuelist, &ctx->rq_list);
|
|
|
- }
|
|
|
-
|
|
|
- hctx = q->mq_ops->map_queue(q, ctx->cpu);
|
|
|
- blk_mq_hctx_mark_pending(hctx, ctx);
|
|
|
-
|
|
|
- spin_unlock(&ctx->lock);
|
|
|
+ spin_lock(&hctx->lock);
|
|
|
+ list_splice_tail_init(&tmp, &hctx->dispatch);
|
|
|
+ spin_unlock(&hctx->lock);
|
|
|
|
|
|
blk_mq_run_hw_queue(hctx, true);
|
|
|
- blk_mq_put_ctx(ctx);
|
|
|
return NOTIFY_OK;
|
|
|
}
|
|
|
|