]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Add dpt_i2o deadlock fix, fwd from akpm
authorChris Wright <chrisw@redhat.com>
Wed, 21 Dec 2005 19:09:24 +0000 (11:09 -0800)
committerChris Wright <chrisw@redhat.com>
Wed, 21 Dec 2005 19:09:24 +0000 (11:09 -0800)
queue/dpt_i2o-fix-for-deadlock-condition.patch [new file with mode: 0644]
queue/series

diff --git a/queue/dpt_i2o-fix-for-deadlock-condition.patch b/queue/dpt_i2o-fix-for-deadlock-condition.patch
new file mode 100644 (file)
index 0000000..18552e4
--- /dev/null
@@ -0,0 +1,93 @@
+From chrisw@osdl.org  Wed Dec 21 09:28:06 2005
+Message-Id: <200512180326.jBI3QTj1029647@shell0.pdx.osdl.net>
+To: torvalds@osdl.org
+From: akpm@osdl.org
+Date: Sat, 17 Dec 2005 19:26:30 -0800
+Cc: James.Bottomley@steeleye.com, miquels@cistron.nl, aacraid@adaptec.com,
+        stable@kernel.org, mark_salyzyn@adaptec.com
+Subject: [PATCH] dpt_i2o fix for deadlock condition
+
+From: "Salyzyn, Mark" <mark_salyzyn@adaptec.com>
+
+Miquel van Smoorenburg <miquels@cistron.nl> forwarded me this fix to
+resolve a deadlock condition that occurs due to the API change in 2.6.13+
+kernels dropping the host locking when entering the error handling.  They
+all end up calling adpt_i2o_post_wait(), which if you call it unlocked,
+might return with host_lock locked anyway and that causes a deadlock.
+
+Signed-off-by: Mark Salyzyn <aacraid@adaptec.com>
+Cc: James Bottomley <James.Bottomley@steeleye.com>
+Cc: <stable@kernel.org>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Chris Wright <chrisw@redhat.com>
+---
+
+ drivers/scsi/dpt_i2o.c |   25 ++++++++++++++++++++-----
+ 1 files changed, 20 insertions(+), 5 deletions(-)
+
+Index: linux-2.6.14.y/drivers/scsi/dpt_i2o.c
+===================================================================
+--- linux-2.6.14.y.orig/drivers/scsi/dpt_i2o.c
++++ linux-2.6.14.y/drivers/scsi/dpt_i2o.c
+@@ -660,7 +660,12 @@ static int adpt_abort(struct scsi_cmnd *
+       msg[2] = 0;
+       msg[3]= 0; 
+       msg[4] = (u32)cmd;
+-      if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){
++      if (pHba->host)
++              spin_lock_irq(pHba->host->host_lock);
++      rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER);
++      if (pHba->host)
++              spin_unlock_irq(pHba->host->host_lock);
++      if (rcode != 0) {
+               if(rcode == -EOPNOTSUPP ){
+                       printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
+                       return FAILED;
+@@ -697,10 +702,15 @@ static int adpt_device_reset(struct scsi
+       msg[2] = 0;
+       msg[3] = 0;
++      if (pHba->host)
++              spin_lock_irq(pHba->host->host_lock);
+       old_state = d->state;
+       d->state |= DPTI_DEV_RESET;
+-      if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){
+-              d->state = old_state;
++      rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
++      d->state = old_state;
++      if (pHba->host)
++              spin_unlock_irq(pHba->host->host_lock);
++      if (rcode != 0) {
+               if(rcode == -EOPNOTSUPP ){
+                       printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
+                       return FAILED;
+@@ -708,7 +718,6 @@ static int adpt_device_reset(struct scsi
+               printk(KERN_INFO"%s: Device reset failed\n",pHba->name);
+               return FAILED;
+       } else {
+-              d->state = old_state;
+               printk(KERN_INFO"%s: Device reset successful\n",pHba->name);
+               return SUCCESS;
+       }
+@@ -721,6 +730,7 @@ static int adpt_bus_reset(struct scsi_cm
+ {
+       adpt_hba* pHba;
+       u32 msg[4];
++      u32 rcode;
+       pHba = (adpt_hba*)cmd->device->host->hostdata[0];
+       memset(msg, 0, sizeof(msg));
+@@ -729,7 +739,12 @@ static int adpt_bus_reset(struct scsi_cm
+       msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
+       msg[2] = 0;
+       msg[3] = 0;
+-      if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){
++      if (pHba->host)
++              spin_lock_irq(pHba->host->host_lock);
++      rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
++      if (pHba->host)
++              spin_unlock_irq(pHba->host->host_lock);
++      if (rcode != 0) {
+               printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
+               return FAILED;
+       } else {
index cc7fb702e62e9331ba23543c78e1c5b877d563ab..f98e4d8b776f5e4af7452b54f3231cb9d7920f91 100644 (file)
@@ -3,3 +3,4 @@ acpi-prefer-_cst-over-fadt-for-c-state-capabilities.patch
 fix-cta_proto_num-attribute-size-in-ctnetlink.patch
 fix-unbalanced-read_unlock_bh-in-ctnetlink.patch
 acpi-fix-null-deref-in-video-lcd-brightness.patch
+dpt_i2o-fix-for-deadlock-condition.patch