tree 62fc13bff0a28134adbb523ed1a2c0efdd9a85cb
parent 56fece20086ebe32bce2c0d74ceadd516b56baae
author <[EMAIL PROTECTED]> Wed, 13 Apr 2005 02:22:06 -0500
committer James Bottomley <[EMAIL PROTECTED]> Sun, 17 Apr 2005 06:10:09 -0500

[PATCH] fix NMI lockup with CFQ scheduler

The current problem seen is that the queue lock is actually in the
SCSI device structure, so when that structure is freed on device
release, we go boom if the queue tries to access the lock again.

The fix here is to move the lock from the scsi_device to the queue.

Signed-off-by: James Bottomley <[EMAIL PROTECTED]>

 block/ll_rw_blk.c  |    9 +++++++++
 scsi/scsi_lib.c    |    6 +++---
 scsi/scsi_scan.c   |    1 -
 linux/blkdev.h     |    5 ++++-
 scsi/scsi_device.h |    1 -
 5 files changed, 16 insertions(+), 6 deletions(-)

Index: drivers/block/ll_rw_blk.c
===================================================================
--- 3ce88fad34483bfc393feb2ee5f3a7f4b8a17f0b/drivers/block/ll_rw_blk.c  
(mode:100644 sha1:46e54b441663d501c33944e46411117af9c4da40)
+++ 62fc13bff0a28134adbb523ed1a2c0efdd9a85cb/drivers/block/ll_rw_blk.c  
(mode:100644 sha1:11ef9d9ea139316e454cfae3d3b10f7aaab71959)
@@ -1715,6 +1715,15 @@
        if (blk_init_free_list(q))
                goto out_init;
 
+       /*
+        * if caller didn't supply a lock, they get per-queue locking with
+        * our embedded lock
+        */
+       if (!lock) {
+               spin_lock_init(&q->__queue_lock);
+               lock = &q->__queue_lock;
+       }
+
        q->request_fn           = rfn;
        q->back_merge_fn        = ll_back_merge_fn;
        q->front_merge_fn       = ll_front_merge_fn;
Index: drivers/scsi/scsi_lib.c
===================================================================
--- 3ce88fad34483bfc393feb2ee5f3a7f4b8a17f0b/drivers/scsi/scsi_lib.c  
(mode:100644 sha1:7cbc4127fb5a6375e870920dd3f7b19199d59a90)
+++ 62fc13bff0a28134adbb523ed1a2c0efdd9a85cb/drivers/scsi/scsi_lib.c  
(mode:100644 sha1:d230c699c728e3a8db456034bf5bf30c7b1c5452)
@@ -360,9 +360,9 @@
                     shost->host_failed))
                scsi_eh_wakeup(shost);
        spin_unlock(shost->host_lock);
-       spin_lock(&sdev->sdev_lock);
+       spin_lock(sdev->request_queue->queue_lock);
        sdev->device_busy--;
-       spin_unlock_irqrestore(&sdev->sdev_lock, flags);
+       spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
 }
 
 /*
@@ -1425,7 +1425,7 @@
        struct Scsi_Host *shost = sdev->host;
        struct request_queue *q;
 
-       q = blk_init_queue(scsi_request_fn, &sdev->sdev_lock);
+       q = blk_init_queue(scsi_request_fn, NULL);
        if (!q)
                return NULL;
 
Index: drivers/scsi/scsi_scan.c
===================================================================
--- 3ce88fad34483bfc393feb2ee5f3a7f4b8a17f0b/drivers/scsi/scsi_scan.c  
(mode:100644 sha1:a8a37a338c02f70ea4e04c9cbcab29559c0d3492)
+++ 62fc13bff0a28134adbb523ed1a2c0efdd9a85cb/drivers/scsi/scsi_scan.c  
(mode:100644 sha1:287d197a7c17f8527668ee162361b9552f04d948)
@@ -249,7 +249,6 @@
         */
        sdev->borken = 1;
 
-       spin_lock_init(&sdev->sdev_lock);
        sdev->request_queue = scsi_alloc_queue(sdev);
        if (!sdev->request_queue) {
                /* release fn is set up in scsi_sysfs_device_initialise, so
Index: include/linux/blkdev.h
===================================================================
--- 3ce88fad34483bfc393feb2ee5f3a7f4b8a17f0b/include/linux/blkdev.h  
(mode:100644 sha1:70ac2860a605342199b4d68c2215154eb2921645)
+++ 62fc13bff0a28134adbb523ed1a2c0efdd9a85cb/include/linux/blkdev.h  
(mode:100644 sha1:ef1afc178c0a2df9569daf3312e33911a0e89bf2)
@@ -355,8 +355,11 @@
        unsigned long           queue_flags;
 
        /*
-        * protects queue structures from reentrancy
+        * protects queue structures from reentrancy. ->__queue_lock should
+        * _never_ be used directly, it is queue private. always use
+        * ->queue_lock.
         */
+       spinlock_t              __queue_lock;
        spinlock_t              *queue_lock;
 
        /*
Index: include/scsi/scsi_device.h
===================================================================
--- 3ce88fad34483bfc393feb2ee5f3a7f4b8a17f0b/include/scsi/scsi_device.h  
(mode:100644 sha1:07d974051b0c10b1381ea4b0a675076fe5210e71)
+++ 62fc13bff0a28134adbb523ed1a2c0efdd9a85cb/include/scsi/scsi_device.h  
(mode:100644 sha1:f6d051318299c17bf10240b042bca624e96ee97e)
@@ -44,7 +44,6 @@
        struct list_head    same_target_siblings; /* just the devices sharing 
same target id */
 
        volatile unsigned short device_busy;    /* commands actually active on 
low-level */
-       spinlock_t sdev_lock;           /* also the request queue_lock */
        spinlock_t list_lock;
        struct list_head cmd_list;      /* queue of in use SCSI Command 
structures */
        struct list_head starved_entry;
-
To unsubscribe from this list: send the line "unsubscribe bk-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