diff options
author | Shaohua Li <shli@kernel.org> | 2013-12-30 22:38:50 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2014-01-30 14:57:25 -0500 |
commit | f0276924fa35a3607920a58cf5d878212824b951 (patch) | |
tree | 5759cef09f3ba6b2f206ace779fef298a8b9d7be /block/blk-flush.c | |
parent | d835502f3dacad1638d516ab156d66f0ba377cf5 (diff) |
blk-mq: Don't reserve a tag for flush request
Reserving a tag (request) for flush to avoid dead lock is a overkill. A
tag is valuable resource. We can track the number of flush requests and
disallow having too many pending flush requests allocated. With this
patch, blk_mq_alloc_request_pinned() could do a busy nop (but not a dead
loop) if too many pending requests are allocated and new flush request
is allocated. But this should not be a problem, too many pending flush
requests are very rare case.
I verified this can fix the deadlock caused by too many pending flush
requests.
Signed-off-by: Shaohua Li <shli@fusionio.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/blk-flush.c')
-rw-r--r-- | block/blk-flush.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/block/blk-flush.c b/block/blk-flush.c index 9288aaf35c21..9143e85226c7 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c | |||
@@ -284,9 +284,8 @@ static void mq_flush_work(struct work_struct *work) | |||
284 | 284 | ||
285 | q = container_of(work, struct request_queue, mq_flush_work); | 285 | q = container_of(work, struct request_queue, mq_flush_work); |
286 | 286 | ||
287 | /* We don't need set REQ_FLUSH_SEQ, it's for consistency */ | ||
288 | rq = blk_mq_alloc_request(q, WRITE_FLUSH|REQ_FLUSH_SEQ, | 287 | rq = blk_mq_alloc_request(q, WRITE_FLUSH|REQ_FLUSH_SEQ, |
289 | __GFP_WAIT|GFP_ATOMIC, true); | 288 | __GFP_WAIT|GFP_ATOMIC, false); |
290 | rq->cmd_type = REQ_TYPE_FS; | 289 | rq->cmd_type = REQ_TYPE_FS; |
291 | rq->end_io = flush_end_io; | 290 | rq->end_io = flush_end_io; |
292 | 291 | ||
@@ -408,8 +407,11 @@ void blk_insert_flush(struct request *rq) | |||
408 | /* | 407 | /* |
409 | * @policy now records what operations need to be done. Adjust | 408 | * @policy now records what operations need to be done. Adjust |
410 | * REQ_FLUSH and FUA for the driver. | 409 | * REQ_FLUSH and FUA for the driver. |
410 | * We keep REQ_FLUSH for mq to track flush requests. For !FUA, | ||
411 | * we never dispatch the request directly. | ||
411 | */ | 412 | */ |
412 | rq->cmd_flags &= ~REQ_FLUSH; | 413 | if (rq->cmd_flags & REQ_FUA) |
414 | rq->cmd_flags &= ~REQ_FLUSH; | ||
413 | if (!(fflags & REQ_FUA)) | 415 | if (!(fflags & REQ_FUA)) |
414 | rq->cmd_flags &= ~REQ_FUA; | 416 | rq->cmd_flags &= ~REQ_FUA; |
415 | 417 | ||