mirror of https://gitee.com/openkylin/linux.git
dm rq: take request_queue lock while clearing QUEUE_FLAG_STOPPED
Every call of queue_flag_clear_unlocked() after block device initialization has finished is wrong if blk_cleanup_queue() can be called concurrently. Convert queue_flag_clear_unlocked() into queue_flag_clear() and protect it by the block layer queue lock. Also, factor out dm_mq_start_queue(). Reported-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Cc: stable@vger.kernel.org
This commit is contained in:
parent
2397a15aff
commit
9dbeaeabac
|
@ -73,15 +73,24 @@ static void dm_old_start_queue(struct request_queue *q)
|
|||
spin_unlock_irqrestore(q->queue_lock, flags);
|
||||
}
|
||||
|
||||
static void dm_mq_start_queue(struct request_queue *q)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(q->queue_lock, flags);
|
||||
queue_flag_clear(QUEUE_FLAG_STOPPED, q);
|
||||
spin_unlock_irqrestore(q->queue_lock, flags);
|
||||
|
||||
blk_mq_start_stopped_hw_queues(q, true);
|
||||
blk_mq_kick_requeue_list(q);
|
||||
}
|
||||
|
||||
void dm_start_queue(struct request_queue *q)
|
||||
{
|
||||
if (!q->mq_ops)
|
||||
dm_old_start_queue(q);
|
||||
else {
|
||||
queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, q);
|
||||
blk_mq_start_stopped_hw_queues(q, true);
|
||||
blk_mq_kick_requeue_list(q);
|
||||
}
|
||||
else
|
||||
dm_mq_start_queue(q);
|
||||
}
|
||||
|
||||
static void dm_old_stop_queue(struct request_queue *q)
|
||||
|
|
Loading…
Reference in New Issue