diff options
Diffstat (limited to 'block/ll_rw_blk.c')
-rw-r--r-- | block/ll_rw_blk.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index e5041a02e21f..eac48bec1479 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c | |||
@@ -1732,8 +1732,21 @@ void blk_run_queue(struct request_queue *q) | |||
1732 | 1732 | ||
1733 | spin_lock_irqsave(q->queue_lock, flags); | 1733 | spin_lock_irqsave(q->queue_lock, flags); |
1734 | blk_remove_plug(q); | 1734 | blk_remove_plug(q); |
1735 | if (!elv_queue_empty(q)) | 1735 | |
1736 | q->request_fn(q); | 1736 | /* |
1737 | * Only recurse once to avoid overrunning the stack, let the unplug | ||
1738 | * handling reinvoke the handler shortly if we already got there. | ||
1739 | */ | ||
1740 | if (!elv_queue_empty(q)) { | ||
1741 | if (!test_and_set_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) { | ||
1742 | q->request_fn(q); | ||
1743 | clear_bit(QUEUE_FLAG_REENTER, &q->queue_flags); | ||
1744 | } else { | ||
1745 | blk_plug_device(q); | ||
1746 | kblockd_schedule_work(&q->unplug_work); | ||
1747 | } | ||
1748 | } | ||
1749 | |||
1737 | spin_unlock_irqrestore(q->queue_lock, flags); | 1750 | spin_unlock_irqrestore(q->queue_lock, flags); |
1738 | } | 1751 | } |
1739 | EXPORT_SYMBOL(blk_run_queue); | 1752 | EXPORT_SYMBOL(blk_run_queue); |