]>
Commit | Line | Data |
---|---|---|
71fe0565 GKH |
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 | |
5 | ||
6 | From: Mike Snitzer <snitzer@redhat.com> | |
7 | ||
8 | commit 9dbeaeabacb26260d1621fe58f0f6fdedc8860d4 upstream. | |
9 | ||
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. | |
14 | ||
15 | Also, factor out dm_mq_start_queue(). | |
16 | ||
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> | |
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) |