[PATCH] CFQ: request <-> request merging rr_list fixup
authorJens Axboe <jens.axboe@oracle.com>
Tue, 31 Oct 2006 13:21:55 +0000 (14:21 +0100)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 31 Oct 2006 16:12:45 +0000 (08:12 -0800)
In very rare circumstances would we be pruning a merged request and at
the same time delete the implicated cfqq from the rr_list, and not readd
it when the merged request got added. This could cause io stalls until
that process issued io again.

Fix it up by putting the rr_list add handling into cfq_add_rq_rb(),
identical to how pruning is handled in cfq_del_rq_rb(). This fixes a
hang reproducible with fsx-linux.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
block/cfq-iosched.c

index 25c4e7ed0d00f317a925bf962cd35ae906c667aa..1d9c3c70a9a05b84469a30f55dfbd369ec239e12 100644 (file)
@@ -456,6 +456,9 @@ static void cfq_add_rq_rb(struct request *rq)
         */
        while ((__alias = elv_rb_add(&cfqq->sort_list, rq)) != NULL)
                cfq_dispatch_insert(cfqd->queue, __alias);
+
+       if (!cfq_cfqq_on_rr(cfqq))
+               cfq_add_cfqq_rr(cfqd, cfqq);
 }
 
 static inline void
@@ -1652,9 +1655,6 @@ static void cfq_insert_request(request_queue_t *q, struct request *rq)
 
        cfq_add_rq_rb(rq);
 
-       if (!cfq_cfqq_on_rr(cfqq))
-               cfq_add_cfqq_rr(cfqd, cfqq);
-
        list_add_tail(&rq->queuelist, &cfqq->fifo);
 
        cfq_rq_enqueued(cfqd, cfqq, rq);