summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2017-02-17 13:40:44 -0500
committerJens Axboe <axboe@fb.com>2017-02-17 14:35:47 -0500
commit7520872c0cf4d3df6d74242c6edfb9e70a47df4d (patch)
treee33287e1a152ee6d2f2b47f1eb3df0a6c66ae955
parent64765a75ef258c802f795558d00a5a1864c531fc (diff)
block: don't defer flushes on blk-mq + scheduling
For blk-mq with scheduling, we can potentially end up with ALL driver tags assigned and sitting on the flush queues. If we defer because of an inlfight data request, then we can deadlock if that data request doesn't already have a tag assigned. This fixes a deadlock with running the xfs/297 xfstest, where thousands of syncs can cause the drive queue to stall. Signed-off-by: Jens Axboe <axboe@fb.com> Reviewed-by: Omar Sandoval <osandov@fb.com>
-rw-r--r--block/blk-flush.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/block/blk-flush.c b/block/blk-flush.c
index 968162579234..0d5a9c1da1fc 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -297,8 +297,14 @@ static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq)
297 if (fq->flush_pending_idx != fq->flush_running_idx || list_empty(pending)) 297 if (fq->flush_pending_idx != fq->flush_running_idx || list_empty(pending))
298 return false; 298 return false;
299 299
300 /* C2 and C3 */ 300 /* C2 and C3
301 *
302 * For blk-mq + scheduling, we can risk having all driver tags
303 * assigned to empty flushes, and we deadlock if we are expecting
304 * other requests to make progress. Don't defer for that case.
305 */
301 if (!list_empty(&fq->flush_data_in_flight) && 306 if (!list_empty(&fq->flush_data_in_flight) &&
307 !(q->mq_ops && q->elevator) &&
302 time_before(jiffies, 308 time_before(jiffies,
303 fq->flush_pending_since + FLUSH_PENDING_TIMEOUT)) 309 fq->flush_pending_since + FLUSH_PENDING_TIMEOUT))
304 return false; 310 return false;