summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2017-02-17 11:40:44 -0700
committerJens Axboe <axboe@fb.com>2017-02-17 11:40:44 -0700
commitd07891dfdf318dab9a98a0c3a286962ea13e5d0a (patch)
tree45dda86a66ba0f24af1a7a1778cb70fc65ff4666
parente3aa75370104e105c6db6fa748b0f581ef03a083 (diff)
block: don't defer flushes on blk-mq + schedulingfor-4.11/review
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>
-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)
if (fq->flush_pending_idx != fq->flush_running_idx || list_empty(pending))
return false;
- /* C2 and C3 */
+ /* C2 and C3
+ *
+ * For blk-mq + scheduling, we can risk having all driver tags
+ * assigned to empty flushes, and we deadlock if we are expecting
+ * other requests to make progress. Don't defer for that case.
+ */
if (!list_empty(&fq->flush_data_in_flight) &&
+ !(q->mq_ops && q->elevator) &&
time_before(jiffies,
fq->flush_pending_since + FLUSH_PENDING_TIMEOUT))
return false;