Skip to content

Commit

Permalink
block: don't defer flushes on blk-mq + scheduling
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Omar Sandoval <[email protected]>
  • Loading branch information
axboe committed Feb 17, 2017
1 parent 64765a7 commit 7520872
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion block/blk-flush.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 7520872

Please sign in to comment.