mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-08 15:04:45 +00:00
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
Block a user