aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hisi_sas/hisi_sas_main.c
diff options
context:
space:
mode:
authorJohn Garry <john.garry@huawei.com>2017-03-23 01:25:29 +0800
committerMartin K. Petersen <martin.petersen@oracle.com>2017-03-23 11:12:02 -0400
commit54c9dd2d26d0951891516a956893428feb9aea17 (patch)
tree014a525f797ac38118bd9a1b737d0e73e7c42fbe /drivers/scsi/hisi_sas/hisi_sas_main.c
parentscsi: hisi_sas: free slots after hardreset (diff)
downloadlinux-dev-54c9dd2d26d0951891516a956893428feb9aea17.tar.xz
linux-dev-54c9dd2d26d0951891516a956893428feb9aea17.zip
scsi: hisi_sas: fix some sas_task.task_state_lock locking
Some more locking needs to be added/modified for when read-modify-writing sas_task.task_state_flags. Note: since we can attempt to grab this lock in interrupt context we should use irq variant of spin_lock. Signed-off-by: John Garry <john.garry@huawei.com> Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/hisi_sas/hisi_sas_main.c')
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_main.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 49cac22a83bd..f9ea5ccd1e84 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -188,6 +188,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba,
struct asd_sas_port *sas_port = device->port;
struct device *dev = &hisi_hba->pdev->dev;
int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx;
+ unsigned long flags;
if (!sas_port) {
struct task_status_struct *ts = &task->task_status;
@@ -308,9 +309,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba,
}
list_add_tail(&slot->entry, &sas_dev->list);
- spin_lock(&task->task_state_lock);
+ spin_lock_irqsave(&task->task_state_lock, flags);
task->task_state_flags |= SAS_TASK_AT_INITIATOR;
- spin_unlock(&task->task_state_lock);
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
hisi_hba->slot_prep = slot;
@@ -922,14 +923,11 @@ static int hisi_sas_abort_task(struct sas_task *task)
return TMF_RESP_FUNC_FAILED;
}
- spin_lock_irqsave(&task->task_state_lock, flags);
if (task->task_state_flags & SAS_TASK_STATE_DONE) {
- spin_unlock_irqrestore(&task->task_state_lock, flags);
rc = TMF_RESP_FUNC_COMPLETE;
goto out;
}
- spin_unlock_irqrestore(&task->task_state_lock, flags);
sas_dev->dev_status = HISI_SAS_DEV_EH;
if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) {
struct scsi_cmnd *cmnd = task->uldd_task;
@@ -1127,6 +1125,7 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, u64 device_id,
struct asd_sas_port *sas_port = device->port;
struct hisi_sas_cmd_hdr *cmd_hdr_base;
int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx;
+ unsigned long flags;
if (unlikely(test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)))
return -EINVAL;
@@ -1167,9 +1166,9 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, u64 device_id,
list_add_tail(&slot->entry, &sas_dev->list);
- spin_lock(&task->task_state_lock);
+ spin_lock_irqsave(&task->task_state_lock, flags);
task->task_state_flags |= SAS_TASK_AT_INITIATOR;
- spin_unlock(&task->task_state_lock);
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
hisi_hba->slot_prep = slot;