Commit c1b1d258 authored by Jens Axboe's avatar Jens Axboe

[PATCH] fix blk_start_queue()

Here's the second attempt at fixing blk_start_queue().  The only change
since last version is using proper atomic bitops.  If we moved the
read/write full to a different variable, we could rely on the queue lock
for plugging and stop/start of queue (by far the most used bit
operations there) and skip the atomic bitops.
parent 524225b7
...@@ -1188,13 +1188,23 @@ static void blk_unplug_timeout(unsigned long data) ...@@ -1188,13 +1188,23 @@ static void blk_unplug_timeout(unsigned long data)
* Description: * Description:
* blk_start_queue() will clear the stop flag on the queue, and call * blk_start_queue() will clear the stop flag on the queue, and call
* the request_fn for the queue if it was in a stopped state when * the request_fn for the queue if it was in a stopped state when
* entered. Also see blk_stop_queue(). Must not be called from driver * entered. Also see blk_stop_queue(). Queue lock must be held.
* request function due to recursion issues. Queue lock must be held.
**/ **/
void blk_start_queue(request_queue_t *q) void blk_start_queue(request_queue_t *q)
{ {
clear_bit(QUEUE_FLAG_STOPPED, &q->queue_flags); clear_bit(QUEUE_FLAG_STOPPED, &q->queue_flags);
schedule_work(&q->unplug_work);
/*
* one level of recursion is ok and is much faster than kicking
* the unplug handling
*/
if (!test_and_set_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) {
q->request_fn(q);
clear_bit(QUEUE_FLAG_REENTER, &q->queue_flags);
} else {
blk_plug_device(q);
schedule_work(&q->unplug_work);
}
} }
EXPORT_SYMBOL(blk_start_queue); EXPORT_SYMBOL(blk_start_queue);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment