diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-mq.c | 48 |
1 files changed, 16 insertions, 32 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 43f0c8ffa92a..ae14749b530c 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -264,46 +264,30 @@ __blk_mq_alloc_request(struct request_queue *q, struct blk_mq_hw_ctx *hctx, | |||
264 | return NULL; | 264 | return NULL; |
265 | } | 265 | } |
266 | 266 | ||
267 | static struct request *blk_mq_alloc_request_pinned(struct request_queue *q, | ||
268 | int rw, gfp_t gfp, | ||
269 | bool reserved) | ||
270 | { | ||
271 | bool gfp_mask = gfp & ~__GFP_WAIT; | ||
272 | struct request *rq; | ||
273 | |||
274 | do { | ||
275 | struct blk_mq_ctx *ctx = blk_mq_get_ctx(q); | ||
276 | struct blk_mq_hw_ctx *hctx = q->mq_ops->map_queue(q, ctx->cpu); | ||
277 | |||
278 | rq = __blk_mq_alloc_request(q, hctx, ctx, rw, gfp_mask, | ||
279 | reserved); | ||
280 | if (rq) | ||
281 | break; | ||
282 | |||
283 | if (!(gfp & __GFP_WAIT)) { | ||
284 | blk_mq_put_ctx(ctx); | ||
285 | break; | ||
286 | } | ||
287 | |||
288 | __blk_mq_run_hw_queue(hctx); | ||
289 | blk_mq_put_ctx(ctx); | ||
290 | gfp_mask = gfp; | ||
291 | } while (1); | ||
292 | |||
293 | return rq; | ||
294 | } | ||
295 | |||
296 | struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp, | 267 | struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp, |
297 | bool reserved) | 268 | bool reserved) |
298 | { | 269 | { |
270 | struct blk_mq_ctx *ctx; | ||
271 | struct blk_mq_hw_ctx *hctx; | ||
299 | struct request *rq; | 272 | struct request *rq; |
300 | 273 | ||
301 | if (blk_mq_queue_enter(q)) | 274 | if (blk_mq_queue_enter(q)) |
302 | return NULL; | 275 | return NULL; |
303 | 276 | ||
304 | rq = blk_mq_alloc_request_pinned(q, rw, gfp, reserved); | 277 | ctx = blk_mq_get_ctx(q); |
305 | if (rq) | 278 | hctx = q->mq_ops->map_queue(q, ctx->cpu); |
306 | blk_mq_put_ctx(rq->mq_ctx); | 279 | |
280 | rq = __blk_mq_alloc_request(q, hctx, ctx, rw, gfp & ~__GFP_WAIT, | ||
281 | reserved); | ||
282 | if (!rq && (gfp & __GFP_WAIT)) { | ||
283 | __blk_mq_run_hw_queue(hctx); | ||
284 | blk_mq_put_ctx(ctx); | ||
285 | |||
286 | ctx = blk_mq_get_ctx(q); | ||
287 | hctx = q->mq_ops->map_queue(q, ctx->cpu); | ||
288 | rq = __blk_mq_alloc_request(q, hctx, ctx, rw, gfp, reserved); | ||
289 | } | ||
290 | blk_mq_put_ctx(ctx); | ||
307 | return rq; | 291 | return rq; |
308 | } | 292 | } |
309 | EXPORT_SYMBOL(blk_mq_alloc_request); | 293 | EXPORT_SYMBOL(blk_mq_alloc_request); |