diff options
| author | Ming Lei <ming.lei@canonical.com> | 2014-12-03 06:38:04 -0500 |
|---|---|---|
| committer | Jens Axboe <axboe@fb.com> | 2014-12-08 23:37:08 -0500 |
| commit | 19c66e59ce57e7b181625cbb408d48eb10837763 (patch) | |
| tree | 4eb5617cb983d279305e7b9f7e65cf61f0175d2a | |
| parent | 080ff3511450fd73948697fef34a3cc382675b59 (diff) | |
blk-mq: prevent unmapped hw queue from being scheduled
When one hardware queue has no mapped software queues, it
shouldn't have been scheduled. Otherwise WARNING or OOPS
can triggered.
blk_mq_hw_queue_mapped() helper is introduce for fixing
the problem.
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
| -rw-r--r-- | block/blk-mq.c | 8 | ||||
| -rw-r--r-- | block/blk-mq.h | 5 |
2 files changed, 11 insertions, 2 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 4854e709aa34..b21a3b6f7b65 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
| @@ -589,7 +589,7 @@ static void blk_mq_rq_timer(unsigned long priv) | |||
| 589 | * If not software queues are currently mapped to this | 589 | * If not software queues are currently mapped to this |
| 590 | * hardware queue, there's nothing to check | 590 | * hardware queue, there's nothing to check |
| 591 | */ | 591 | */ |
| 592 | if (!hctx->nr_ctx || !hctx->tags) | 592 | if (!blk_mq_hw_queue_mapped(hctx)) |
| 593 | continue; | 593 | continue; |
| 594 | 594 | ||
| 595 | blk_mq_tag_busy_iter(hctx, blk_mq_check_expired, &data); | 595 | blk_mq_tag_busy_iter(hctx, blk_mq_check_expired, &data); |
| @@ -809,7 +809,8 @@ static int blk_mq_hctx_next_cpu(struct blk_mq_hw_ctx *hctx) | |||
| 809 | 809 | ||
| 810 | void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async) | 810 | void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async) |
| 811 | { | 811 | { |
| 812 | if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state))) | 812 | if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state) || |
| 813 | !blk_mq_hw_queue_mapped(hctx))) | ||
| 813 | return; | 814 | return; |
| 814 | 815 | ||
| 815 | if (!async) { | 816 | if (!async) { |
| @@ -916,6 +917,9 @@ static void blk_mq_delay_work_fn(struct work_struct *work) | |||
| 916 | 917 | ||
| 917 | void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs) | 918 | void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs) |
| 918 | { | 919 | { |
| 920 | if (unlikely(!blk_mq_hw_queue_mapped(hctx))) | ||
| 921 | return; | ||
| 922 | |||
| 919 | kblockd_schedule_delayed_work_on(blk_mq_hctx_next_cpu(hctx), | 923 | kblockd_schedule_delayed_work_on(blk_mq_hctx_next_cpu(hctx), |
| 920 | &hctx->delay_work, msecs_to_jiffies(msecs)); | 924 | &hctx->delay_work, msecs_to_jiffies(msecs)); |
| 921 | } | 925 | } |
diff --git a/block/blk-mq.h b/block/blk-mq.h index d567d5283ffa..206230e64f79 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h | |||
| @@ -115,4 +115,9 @@ static inline void blk_mq_set_alloc_data(struct blk_mq_alloc_data *data, | |||
| 115 | data->hctx = hctx; | 115 | data->hctx = hctx; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | static inline bool blk_mq_hw_queue_mapped(struct blk_mq_hw_ctx *hctx) | ||
| 119 | { | ||
| 120 | return hctx->nr_ctx && hctx->tags; | ||
| 121 | } | ||
| 122 | |||
| 118 | #endif | 123 | #endif |
