1 From 9dbeaeabacb26260d1621fe58f0f6fdedc8860d4 Mon Sep 17 00:00:00 2001
2 From: Mike Snitzer <snitzer@redhat.com>
3 Date: Thu, 1 Sep 2016 11:59:33 -0400
4 Subject: dm rq: take request_queue lock while clearing QUEUE_FLAG_STOPPED
6 From: Mike Snitzer <snitzer@redhat.com>
8 commit 9dbeaeabacb26260d1621fe58f0f6fdedc8860d4 upstream.
10 Every call of queue_flag_clear_unlocked() after block device
11 initialization has finished is wrong if blk_cleanup_queue() can be
12 called concurrently. Convert queue_flag_clear_unlocked() into
13 queue_flag_clear() and protect it by the block layer queue lock.
15 Also, factor out dm_mq_start_queue().
17 Reported-by: Bart Van Assche <bart.vanassche@sandisk.com>
18 Signed-off-by: Mike Snitzer <snitzer@redhat.com>
19 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
22 drivers/md/dm-rq.c | 19 ++++++++++++++-----
23 1 file changed, 14 insertions(+), 5 deletions(-)
25 --- a/drivers/md/dm-rq.c
26 +++ b/drivers/md/dm-rq.c
27 @@ -73,15 +73,24 @@ static void dm_old_start_queue(struct re
28 spin_unlock_irqrestore(q->queue_lock, flags);
31 +static void dm_mq_start_queue(struct request_queue *q)
33 + unsigned long flags;
35 + spin_lock_irqsave(q->queue_lock, flags);
36 + queue_flag_clear(QUEUE_FLAG_STOPPED, q);
37 + spin_unlock_irqrestore(q->queue_lock, flags);
39 + blk_mq_start_stopped_hw_queues(q, true);
40 + blk_mq_kick_requeue_list(q);
43 void dm_start_queue(struct request_queue *q)
46 dm_old_start_queue(q);
48 - queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, q);
49 - blk_mq_start_stopped_hw_queues(q, true);
50 - blk_mq_kick_requeue_list(q);
53 + dm_mq_start_queue(q);
56 static void dm_old_stop_queue(struct request_queue *q)