Skip to content

Commit

Permalink
dm rq: fix a race condition in rq_completed()
Browse files Browse the repository at this point in the history
It is required to hold the queue lock when calling blk_run_queue_async()
to avoid that a race between blk_run_queue_async() and
blk_cleanup_queue() is triggered.

Cc: [email protected]
Signed-off-by: Bart Van Assche <[email protected]>
Signed-off-by: Mike Snitzer <[email protected]>
  • Loading branch information
Bart Van Assche authored and snitm committed Nov 14, 2016
1 parent 2e8ed71 commit d15bb3a
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions drivers/md/dm-rq.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ static void rq_end_stats(struct mapped_device *md, struct request *orig)
*/
static void rq_completed(struct mapped_device *md, int rw, bool run_queue)
{
struct request_queue *q = md->queue;
unsigned long flags;

atomic_dec(&md->pending[rw]);

/* nudge anyone waiting on suspend queue */
Expand All @@ -238,8 +241,11 @@ static void rq_completed(struct mapped_device *md, int rw, bool run_queue)
* back into ->request_fn() could deadlock attempting to grab the
* queue lock again.
*/
if (!md->queue->mq_ops && run_queue)
blk_run_queue_async(md->queue);
if (!q->mq_ops && run_queue) {
spin_lock_irqsave(q->queue_lock, flags);
blk_run_queue_async(q);
spin_unlock_irqrestore(q->queue_lock, flags);
}

/*
* dm_put() must be at the end of this function. See the comment above
Expand Down

0 comments on commit d15bb3a

Please sign in to comment.