aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornagalakshmi.nandigama@lsi.com <nagalakshmi.nandigama@lsi.com>2011-10-19 06:07:14 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-30 04:53:45 -0400
commitf3db032f1af6dd3280037ea526fee7cddcc36c41 (patch)
tree3e81bec7fcc23e0f4bb8b795f3f003d0b5f530aa
parentf881ceadd4d6afafb227bcf8165c1b63ba90065b (diff)
[SCSI] mpt2sas: Fix for dead lock occurring between host_lock and sas_device_lock
Fix for dead lock occurring between host_lock and sas_device_lock. The deadlock is between two spin locks, between the shost->host_lock and driver ioc->sas_device_lock. The fix is to rearrange the code in the FW/Driver device removal handshake so the ioc->sas_device_lock is not occurring when the shost->host_lock is taken. [jejb: zero initialise sas_address to fix spurious compiler warning] Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index cd89f42440fe..f9ce31950314 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -3016,7 +3016,8 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3016 Mpi2SCSITaskManagementRequest_t *mpi_request; 3016 Mpi2SCSITaskManagementRequest_t *mpi_request;
3017 u16 smid; 3017 u16 smid;
3018 struct _sas_device *sas_device; 3018 struct _sas_device *sas_device;
3019 struct MPT2SAS_TARGET *sas_target_priv_data; 3019 struct MPT2SAS_TARGET *sas_target_priv_data = NULL;
3020 u64 sas_address = 0;
3020 unsigned long flags; 3021 unsigned long flags;
3021 struct _tr_list *delayed_tr; 3022 struct _tr_list *delayed_tr;
3022 u32 ioc_state; 3023 u32 ioc_state;
@@ -3049,13 +3050,17 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3049 sas_device->starget->hostdata) { 3050 sas_device->starget->hostdata) {
3050 sas_target_priv_data = sas_device->starget->hostdata; 3051 sas_target_priv_data = sas_device->starget->hostdata;
3051 sas_target_priv_data->deleted = 1; 3052 sas_target_priv_data->deleted = 1;
3052 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT 3053 sas_address = sas_device->sas_address;
3053 "setting delete flag: handle(0x%04x), "
3054 "sas_addr(0x%016llx)\n", ioc->name, handle,
3055 (unsigned long long) sas_device->sas_address));
3056 } 3054 }
3057 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 3055 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3058 3056
3057 if (sas_target_priv_data) {
3058 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "setting delete flag: "
3059 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, handle,
3060 (unsigned long long)sas_address));
3061 _scsih_ublock_io_device(ioc, handle);
3062 }
3063
3059 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); 3064 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
3060 if (!smid) { 3065 if (!smid) {
3061 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); 3066 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);