From: Jens Axboe <axboe@suse.de>

Can you try this as an incremental patch? It cleans a few things up.



 25-akpm/drivers/block/cfq-iosched.c |   43 +++++++++++++++++-------------------
 1 files changed, 21 insertions(+), 22 deletions(-)

diff -puN drivers/block/cfq-iosched.c~cfq-3-fixes drivers/block/cfq-iosched.c
--- 25/drivers/block/cfq-iosched.c~cfq-3-fixes	Tue Sep  2 13:06:18 2003
+++ 25-akpm/drivers/block/cfq-iosched.c	Tue Sep  2 13:06:18 2003
@@ -149,15 +149,17 @@ static struct request *cfq_find_rq_hash(
 /*
  * rb tree support functions
  */
-#define RB_EMPTY(root)	((root)->rb_node == NULL)
-#define RB_CLEAR(root)	((root)->rb_node = NULL)
-#define ON_RB(crq)	((crq)->cfq_queue != NULL)
+#define RB_NONE		(2)
+#define RB_EMPTY(node)	((node)->rb_node == NULL)
+#define RB_CLEAR(node)	((node)->rb_color = RB_NONE)
+#define RB_CLEAR_ROOT(root)	((root)->rb_node = NULL)
+#define ON_RB(node)	((node)->rb_color != RB_NONE)
 #define rb_entry_crq(node)	rb_entry((node), struct cfq_rq, rb_node)
 #define rq_rb_key(rq)		(rq)->sector
 
 static inline void cfq_del_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
 {
-	if (ON_RB(crq)) {
+	if (ON_RB(&crq->rb_node)) {
 		cfqq->queued[rq_data_dir(crq->request)]--;
 		rb_erase(&crq->rb_node, &cfqq->sort_list);
 		crq->cfq_queue = NULL;
@@ -194,13 +196,12 @@ cfq_add_crq_rb(struct cfq_data *cfqd, st
 	struct cfq_rq *__alias;
 
 	crq->rb_key = rq_rb_key(rq);
-
+	cfqq->queued[rq_data_dir(rq)]++;
 retry:
 	__alias = __cfq_add_crq_rb(cfqq, crq);
 	if (!__alias) {
 		rb_insert_color(&crq->rb_node, &cfqq->sort_list);
 		crq->cfq_queue = cfqq;
-		cfqq->queued[rq_data_dir(rq)]++;
 		return;
 	}
 
@@ -301,7 +302,7 @@ static void cfq_merged_request(request_q
 	cfq_del_crq_hash(crq);
 	cfq_add_crq_hash(cfqd, crq);
 
-	if (ON_RB(crq) && rq_rb_key(req) != crq->rb_key) {
+	if (ON_RB(&crq->rb_node) && (rq_rb_key(req) != crq->rb_key)) {
 		struct cfq_queue *cfqq = crq->cfq_queue;
 
 		cfq_del_crq_rb(cfqq, crq);
@@ -345,17 +346,17 @@ link:
 }
 
 static inline void
-__cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+__cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd,
+			struct cfq_queue *cfqq)
 {
-	struct cfq_rq *crq;
-
-	crq = rb_entry_crq(rb_first(&cfqq->sort_list));
+	struct cfq_rq *crq = rb_entry_crq(rb_first(&cfqq->sort_list));
 
 	cfq_del_crq_rb(cfqq, crq);
+	cfq_remove_merge_hints(q, crq);
 	cfq_dispatch_sort(cfqd->dispatch, crq);
 }
 
-static int cfq_dispatch_requests(struct cfq_data *cfqd)
+static int cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd)
 {
 	struct cfq_queue *cfqq;
 	struct list_head *entry, *tmp;
@@ -372,7 +373,7 @@ restart:
 
 		BUG_ON(RB_EMPTY(&cfqq->sort_list));
 
-		__cfq_dispatch_requests(cfqd, cfqq);
+		__cfq_dispatch_requests(q, cfqd, cfqq);
 
 		if (RB_EMPTY(&cfqq->sort_list))
 			cfq_put_queue(cfqd, cfqq);
@@ -399,17 +400,15 @@ static struct request *cfq_next_request(
 dispatch:
 		rq = list_entry_rq(cfqd->dispatch->next);
 
-		if (q->last_merge == &rq->queuelist)
-			q->last_merge = NULL;
-
+		BUG_ON(q->last_merge == &rq->queuelist);
 		crq = RQ_DATA(rq);
 		if (crq)
-			cfq_del_crq_hash(crq);
+			BUG_ON(ON_MHASH(crq));
 
 		return rq;
 	}
 
-	if (cfq_dispatch_requests(cfqd))
+	if (cfq_dispatch_requests(q, cfqd))
 		goto dispatch;
 
 	return NULL;
@@ -456,7 +455,7 @@ static struct cfq_queue *cfq_get_queue(s
 
 		INIT_LIST_HEAD(&cfqq->cfq_hash);
 		INIT_LIST_HEAD(&cfqq->cfq_list);
-		RB_CLEAR(&cfqq->sort_list);
+		RB_CLEAR_ROOT(&cfqq->sort_list);
 
 		cfqq->pid = pid;
 		cfqq->queued[0] = cfqq->queued[1] = 0;
@@ -552,10 +551,9 @@ static int cfq_may_queue(request_queue_t
 	if (!cfqq)
 		goto out;
 
-	if (cfqq->queued[rw] < cfq_queued)
-		goto out;
-
 	limit = (q->nr_requests - cfq_queued) / cfqd->busy_queues;
+	if (limit < 3)
+		limit = 3;
 	if (cfqq->queued[rw] > limit)
 		ret = 0;
 
@@ -583,6 +581,7 @@ static int cfq_set_request(request_queue
 	struct cfq_rq *crq = mempool_alloc(cfqd->crq_pool, gfp_mask);
 
 	if (crq) {
+		RB_CLEAR(&crq->rb_node);
 		crq->request = rq;
 		crq->cfq_queue = NULL;
 		INIT_LIST_HEAD(&crq->hash);

_