Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=bc90ba093af2e5022b9d055a2148b54a6aa35bc9
Commit:     bc90ba093af2e5022b9d055a2148b54a6aa35bc9
Parent:     e126c7b6bbb0c5b5fc3ecf2fd1ae67c803b747cc
Author:     Tejun Heo <[EMAIL PROTECTED]>
AuthorDate: Fri Jun 15 13:24:28 2007 +0200
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Fri Jun 15 16:12:20 2007 -0700

    block: always requeue !fs requests at the front
    
    SCSI marks internal commands with REQ_PREEMPT and push it at the front
    of the request queue using blk_execute_rq().  When entering suspended
    or frozen state, SCSI devices are quiesced using
    scsi_device_quiesce().  In quiesced state, only REQ_PREEMPT requests
    are processed.  This is how SCSI blocks other requests out while
    suspending and resuming.  As all internal commands are pushed at the
    front of the queue, this usually works.
    
    Unfortunately, this interacts badly with ordered requeueing.  To
    preserve request order on requeueing (due to busy device, active EH or
    other failures), requests are sorted according to ordered sequence on
    requeue if IO barrier is in progress.
    
    The following sequence deadlocks.
    
    1. IO barrier sequence issues.
    
    2. Suspend requested.  Queue is quiesced with part or all of IO
       barrier sequence at the front.
    
    3. During suspending or resuming, SCSI issues internal command which
       gets deferred and requeued for some reason.  As the command is
       issued after the IO barrier in #1, ordered requeueing code puts the
       request after IO barrier sequence.
    
    4. The device is ready to process requests again but still is in
       quiesced state and the first request of the queue isn't
       REQ_PREEMPT, so command processing is deadlocked -
       suspending/resuming waits for the issued request to complete while
       the request can't be processed till device is put back into
       running state by resuming.
    
    This can be fixed by always putting !fs requests at the front when
    requeueing.
    
    The following thread reports this deadlock.
    
      http://thread.gmane.org/gmane.linux.kernel/537473
    
    Signed-off-by: Tejun Heo <[EMAIL PROTECTED]>
    Acked-by: David Greaves <[EMAIL PROTECTED]>
    Acked-by: Jeff Garzik <[EMAIL PROTECTED]>
    Signed-off-by: Jens Axboe <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 block/ll_rw_blk.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 6b5173a..c99b463 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -340,6 +340,15 @@ unsigned blk_ordered_req_seq(struct request *rq)
        if (rq == &q->post_flush_rq)
                return QUEUE_ORDSEQ_POSTFLUSH;
 
+       /*
+        * !fs requests don't need to follow barrier ordering.  Always
+        * put them at the front.  This fixes the following deadlock.
+        *
+        * http://thread.gmane.org/gmane.linux.kernel/537473
+        */
+       if (!blk_fs_request(rq))
+               return QUEUE_ORDSEQ_DRAIN;
+
        if ((rq->cmd_flags & REQ_ORDERED_COLOR) ==
            (q->orig_bar_rq->cmd_flags & REQ_ORDERED_COLOR))
                return QUEUE_ORDSEQ_DRAIN;
-
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