aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-flush.c2
-rw-r--r--block/blk-mq-tag.c48
-rw-r--r--block/blk-mq-tag.h2
-rw-r--r--block/blk-mq.c83
-rw-r--r--block/blk-mq.h45
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c4
-rw-r--r--include/linux/blk-mq.h2
-rw-r--r--include/linux/blkdev.h2
8 files changed, 123 insertions, 65 deletions
diff --git a/block/blk-flush.c b/block/blk-flush.c
index ff87c664b7df..8ffee4b5f93d 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -225,7 +225,7 @@ static void flush_end_io(struct request *flush_rq, int error)
225 225
226 if (q->mq_ops) { 226 if (q->mq_ops) {
227 spin_lock_irqsave(&q->mq_flush_lock, flags); 227 spin_lock_irqsave(&q->mq_flush_lock, flags);
228 q->flush_rq->cmd_flags = 0; 228 q->flush_rq->tag = -1;
229 } 229 }
230 230
231 running = &q->flush_queue[q->flush_running_idx]; 231 running = &q->flush_queue[q->flush_running_idx];
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
index d90c4aeb7dd3..1aab39f71d95 100644
--- a/block/blk-mq-tag.c
+++ b/block/blk-mq-tag.c
@@ -221,8 +221,10 @@ static struct bt_wait_state *bt_wait_ptr(struct blk_mq_bitmap_tags *bt,
221 return bs; 221 return bs;
222} 222}
223 223
224static int bt_get(struct blk_mq_bitmap_tags *bt, struct blk_mq_hw_ctx *hctx, 224static int bt_get(struct blk_mq_alloc_data *data,
225 unsigned int *last_tag, gfp_t gfp) 225 struct blk_mq_bitmap_tags *bt,
226 struct blk_mq_hw_ctx *hctx,
227 unsigned int *last_tag)
226{ 228{
227 struct bt_wait_state *bs; 229 struct bt_wait_state *bs;
228 DEFINE_WAIT(wait); 230 DEFINE_WAIT(wait);
@@ -232,7 +234,7 @@ static int bt_get(struct blk_mq_bitmap_tags *bt, struct blk_mq_hw_ctx *hctx,
232 if (tag != -1) 234 if (tag != -1)
233 return tag; 235 return tag;
234 236
235 if (!(gfp & __GFP_WAIT)) 237 if (!(data->gfp & __GFP_WAIT))
236 return -1; 238 return -1;
237 239
238 bs = bt_wait_ptr(bt, hctx); 240 bs = bt_wait_ptr(bt, hctx);
@@ -249,50 +251,62 @@ static int bt_get(struct blk_mq_bitmap_tags *bt, struct blk_mq_hw_ctx *hctx,
249 if (was_empty) 251 if (was_empty)
250 atomic_set(&bs->wait_cnt, bt->wake_cnt); 252 atomic_set(&bs->wait_cnt, bt->wake_cnt);
251 253
254 blk_mq_put_ctx(data->ctx);
255
252 io_schedule(); 256 io_schedule();
257
258 data->ctx = blk_mq_get_ctx(data->q);
259 data->hctx = data->q->mq_ops->map_queue(data->q,
260 data->ctx->cpu);
261 if (data->reserved) {
262 bt = &data->hctx->tags->breserved_tags;
263 } else {
264 last_tag = &data->ctx->last_tag;
265 hctx = data->hctx;
266 bt = &hctx->tags->bitmap_tags;
267 }
268 finish_wait(&bs->wait, &wait);
269 bs = bt_wait_ptr(bt, hctx);
253 } while (1); 270 } while (1);
254 271
255 finish_wait(&bs->wait, &wait); 272 finish_wait(&bs->wait, &wait);
256 return tag; 273 return tag;
257} 274}
258 275
259static unsigned int __blk_mq_get_tag(struct blk_mq_tags *tags, 276static unsigned int __blk_mq_get_tag(struct blk_mq_alloc_data *data)
260 struct blk_mq_hw_ctx *hctx,
261 unsigned int *last_tag, gfp_t gfp)
262{ 277{
263 int tag; 278 int tag;
264 279
265 tag = bt_get(&tags->bitmap_tags, hctx, last_tag, gfp); 280 tag = bt_get(data, &data->hctx->tags->bitmap_tags, data->hctx,
281 &data->ctx->last_tag);
266 if (tag >= 0) 282 if (tag >= 0)
267 return tag + tags->nr_reserved_tags; 283 return tag + data->hctx->tags->nr_reserved_tags;
268 284
269 return BLK_MQ_TAG_FAIL; 285 return BLK_MQ_TAG_FAIL;
270} 286}
271 287
272static unsigned int __blk_mq_get_reserved_tag(struct blk_mq_tags *tags, 288static unsigned int __blk_mq_get_reserved_tag(struct blk_mq_alloc_data *data)
273 gfp_t gfp)
274{ 289{
275 int tag, zero = 0; 290 int tag, zero = 0;
276 291
277 if (unlikely(!tags->nr_reserved_tags)) { 292 if (unlikely(!data->hctx->tags->nr_reserved_tags)) {
278 WARN_ON_ONCE(1); 293 WARN_ON_ONCE(1);
279 return BLK_MQ_TAG_FAIL; 294 return BLK_MQ_TAG_FAIL;
280 } 295 }
281 296
282 tag = bt_get(&tags->breserved_tags, NULL, &zero, gfp); 297 tag = bt_get(data, &data->hctx->tags->breserved_tags, NULL, &zero);
283 if (tag < 0) 298 if (tag < 0)
284 return BLK_MQ_TAG_FAIL; 299 return BLK_MQ_TAG_FAIL;
285 300
286 return tag; 301 return tag;
287} 302}
288 303
289unsigned int blk_mq_get_tag(struct blk_mq_hw_ctx *hctx, unsigned int *last_tag, 304unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data)
290 gfp_t gfp, bool reserved)
291{ 305{
292 if (!reserved) 306 if (!data->reserved)
293 return __blk_mq_get_tag(hctx->tags, hctx, last_tag, gfp); 307 return __blk_mq_get_tag(data);
294 308
295 return __blk_mq_get_reserved_tag(hctx->tags, gfp); 309 return __blk_mq_get_reserved_tag(data);
296} 310}
297 311
298static struct bt_wait_state *bt_wake_ptr(struct blk_mq_bitmap_tags *bt) 312static struct bt_wait_state *bt_wake_ptr(struct blk_mq_bitmap_tags *bt)
diff --git a/block/blk-mq-tag.h b/block/blk-mq-tag.h
index c959de58d2a5..98696a65d4d4 100644
--- a/block/blk-mq-tag.h
+++ b/block/blk-mq-tag.h
@@ -48,7 +48,7 @@ struct blk_mq_tags {
48extern struct blk_mq_tags *blk_mq_init_tags(unsigned int nr_tags, unsigned int reserved_tags, int node); 48extern struct blk_mq_tags *blk_mq_init_tags(unsigned int nr_tags, unsigned int reserved_tags, int node);
49extern void blk_mq_free_tags(struct blk_mq_tags *tags); 49extern void blk_mq_free_tags(struct blk_mq_tags *tags);
50 50
51extern unsigned int blk_mq_get_tag(struct blk_mq_hw_ctx *hctx, unsigned int *last_tag, gfp_t gfp, bool reserved); 51extern unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data);
52extern void blk_mq_put_tag(struct blk_mq_hw_ctx *hctx, unsigned int tag, unsigned int *last_tag); 52extern void blk_mq_put_tag(struct blk_mq_hw_ctx *hctx, unsigned int tag, unsigned int *last_tag);
53extern bool blk_mq_has_free_tags(struct blk_mq_tags *tags); 53extern bool blk_mq_has_free_tags(struct blk_mq_tags *tags);
54extern ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page); 54extern ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page);
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 0f5879c42dcd..4e4cd6208052 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -33,28 +33,6 @@ static LIST_HEAD(all_q_list);
33 33
34static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx); 34static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx);
35 35
36static struct blk_mq_ctx *__blk_mq_get_ctx(struct request_queue *q,
37 unsigned int cpu)
38{
39 return per_cpu_ptr(q->queue_ctx, cpu);
40}
41
42/*
43 * This assumes per-cpu software queueing queues. They could be per-node
44 * as well, for instance. For now this is hardcoded as-is. Note that we don't
45 * care about preemption, since we know the ctx's are persistent. This does
46 * mean that we can't rely on ctx always matching the currently running CPU.
47 */
48static struct blk_mq_ctx *blk_mq_get_ctx(struct request_queue *q)
49{
50 return __blk_mq_get_ctx(q, get_cpu());
51}
52
53static void blk_mq_put_ctx(struct blk_mq_ctx *ctx)
54{
55 put_cpu();
56}
57
58/* 36/*
59 * Check if any of the ctx's have pending work in this hardware queue 37 * Check if any of the ctx's have pending work in this hardware queue
60 */ 38 */
@@ -232,24 +210,23 @@ static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
232} 210}
233 211
234static struct request * 212static struct request *
235__blk_mq_alloc_request(struct request_queue *q, struct blk_mq_hw_ctx *hctx, 213__blk_mq_alloc_request(struct blk_mq_alloc_data *data, int rw)
236 struct blk_mq_ctx *ctx, int rw, gfp_t gfp, bool reserved)
237{ 214{
238 struct request *rq; 215 struct request *rq;
239 unsigned int tag; 216 unsigned int tag;
240 217
241 tag = blk_mq_get_tag(hctx, &ctx->last_tag, gfp, reserved); 218 tag = blk_mq_get_tag(data);
242 if (tag != BLK_MQ_TAG_FAIL) {