From: Jens Axboe 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); _