]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.8.5/dm-rq-take-request_queue-lock-while-clearing-queue_flag_stopped.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.8.5 / dm-rq-take-request_queue-lock-while-clearing-queue_flag_stopped.patch
CommitLineData
71fe0565
GKH
1From 9dbeaeabacb26260d1621fe58f0f6fdedc8860d4 Mon Sep 17 00:00:00 2001
2From: Mike Snitzer <snitzer@redhat.com>
3Date: Thu, 1 Sep 2016 11:59:33 -0400
4Subject: dm rq: take request_queue lock while clearing QUEUE_FLAG_STOPPED
5
6From: Mike Snitzer <snitzer@redhat.com>
7
8commit 9dbeaeabacb26260d1621fe58f0f6fdedc8860d4 upstream.
9
10Every call of queue_flag_clear_unlocked() after block device
11initialization has finished is wrong if blk_cleanup_queue() can be
12called concurrently. Convert queue_flag_clear_unlocked() into
13queue_flag_clear() and protect it by the block layer queue lock.
14
15Also, factor out dm_mq_start_queue().
16
17Reported-by: Bart Van Assche <bart.vanassche@sandisk.com>
18Signed-off-by: Mike Snitzer <snitzer@redhat.com>
19Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
20
21---
22 drivers/md/dm-rq.c | 19 ++++++++++++++-----
23 1 file changed, 14 insertions(+), 5 deletions(-)
24
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);
29 }
30
31+static void dm_mq_start_queue(struct request_queue *q)
32+{
33+ unsigned long flags;
34+
35+ spin_lock_irqsave(q->queue_lock, flags);
36+ queue_flag_clear(QUEUE_FLAG_STOPPED, q);
37+ spin_unlock_irqrestore(q->queue_lock, flags);
38+
39+ blk_mq_start_stopped_hw_queues(q, true);
40+ blk_mq_kick_requeue_list(q);
41+}
42+
43 void dm_start_queue(struct request_queue *q)
44 {
45 if (!q->mq_ops)
46 dm_old_start_queue(q);
47- else {
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);
51- }
52+ else
53+ dm_mq_start_queue(q);
54 }
55
56 static void dm_old_stop_queue(struct request_queue *q)