From: Jens Axboe <axboe@suse.de>

In several places cfq checks cfqd->busy_queues to see if we have pending
work, but that doesn't detect requests going directly to the dispatch list
since they don't end up in a queue and thus get ->busy_queues incremented. 
Abstract the check into cfq_pending_work() and use that throughout the
code.

Signed-off-by: Jens Axboe <axboe@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 drivers/block/cfq-iosched.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff -puN drivers/block/cfq-iosched.c~cfq-ioschedc-fix-soft-hang-with-non-fs-requests drivers/block/cfq-iosched.c
--- 25/drivers/block/cfq-iosched.c~cfq-ioschedc-fix-soft-hang-with-non-fs-requests	2005-06-18 02:48:56.000000000 -0700
+++ 25-akpm/drivers/block/cfq-iosched.c	2005-06-18 02:48:56.000000000 -0700
@@ -1725,11 +1725,16 @@ cfq_insert_request(request_queue_t *q, s
 	}
 }
 
+static inline int cfq_pending_requests(struct cfq_data *cfqd)
+{
+	return !list_empty(&cfqd->queue->queue_head) || cfqd->busy_queues;
+}
+
 static int cfq_queue_empty(request_queue_t *q)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
 
-	return list_empty(&q->queue_head) && !cfqd->busy_queues;
+	return !cfq_pending_requests(cfqd);
 }
 
 static void cfq_completed_request(request_queue_t *q, struct request *rq)
@@ -2050,7 +2055,7 @@ static void cfq_idle_slice_timer(unsigne
 		 * only expire and reinvoke request handler, if there are
 		 * other queues with pending requests
 		 */
-		if (!cfqd->busy_queues) {
+		if (!cfq_pending_requests(cfqd)) {
 			cfqd->idle_slice_timer.expires = min(now + cfqd->cfq_slice_idle, cfqq->slice_end);
 			add_timer(&cfqd->idle_slice_timer);
 			goto out_cont;
@@ -2067,7 +2072,7 @@ static void cfq_idle_slice_timer(unsigne
 expire:
 	cfq_slice_expired(cfqd, 0);
 out_kick:
-	if (cfqd->busy_queues)
+	if (cfq_pending_requests(cfqd))
 		kblockd_schedule_work(&cfqd->unplug_work);
 out_cont:
 	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
_