Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=5044eed48886b105a123333fe7ca97c6bd496120
Commit:     5044eed48886b105a123333fe7ca97c6bd496120
Parent:     a23cf14b161b8deeb0f701d577a0e8be6365e247
Author:     Jens Axboe <[EMAIL PROTECTED]>
AuthorDate: Wed Apr 25 11:53:48 2007 +0200
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Wed Apr 25 08:41:48 2007 -0700

    cfq-iosched: fix alias + front merge bug
    
    There's a really rare and obscure bug in CFQ, that causes a crash in
    cfq_dispatch_insert() due to rq == NULL.  One example of the resulting
    oops is seen here:
    
        http://lkml.org/lkml/2007/4/15/41
    
    Neil correctly diagnosed the situation for how this can happen: if two
    concurrent requests with the exact same sector number (due to direct IO
    or aliasing between MD and the raw device access), the alias handling
    will add the request to the sortlist, but next_rq remains NULL.
    
    Read the more complete analysis at:
    
        http://lkml.org/lkml/2007/4/25/57
    
    This looks like it requires md to trigger, even though it should
    potentially be possible to due with O_DIRECT (at least if you edit the
    kernel and doctor some of the unplug calls).
    
    The fix is to move the ->next_rq update to when we add a request to the
    rbtree. Then we remove the possibility for a request to exist in the
    rbtree code, but not have ->next_rq correctly updated.
    
    Signed-off-by: Jens Axboe <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 block/cfq-iosched.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 9e37971..f92ba2a 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -532,6 +532,12 @@ static void cfq_add_rq_rb(struct request *rq)
 
        if (!cfq_cfqq_on_rr(cfqq))
                cfq_add_cfqq_rr(cfqd, cfqq);
+
+       /*
+        * check if this request is a better next-serve candidate
+        */
+       cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq);
+       BUG_ON(!cfqq->next_rq);
 }
 
 static inline void
@@ -1639,12 +1645,6 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue 
*cfqq,
                cfqq->meta_pending++;
 
        /*
-        * check if this request is a better next-serve candidate)) {
-        */
-       cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq);
-       BUG_ON(!cfqq->next_rq);
-
-       /*
         * we never wait for an async request and we don't allow preemption
         * of an async request. so just return early
         */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to