* Description:
* 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
- * entered. Also see blk_stop_queue(). Must not be called from driver
- * request function due to recursion issues. Queue lock must be held.
+ * entered. Also see blk_stop_queue(). Queue lock must be held.
**/
void blk_start_queue(request_queue_t *q)
{
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);