scsi: hisi_sas: release SMP slot in lldd_abort_task
authorXiang Chen <chenxiang66@hisilicon.com>
Wed, 22 Mar 2017 17:25:36 +0000 (01:25 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 23 Mar 2017 15:12:02 +0000 (11:12 -0400)
When an SMP task timeouts, it will call lldd_abort_task to release the
associated slot, and then will release the sas_task.

Currently in lldd_abort_task, if we fail to internally abort IO, then
the slot of SMP IO is not released, but sas_task will still be later
released, so the slot's sas_task is NULL, which will cause NULL pointer
when hisi_sas_slot_task_free happens later.

To resolve, check the return value of internal abort, and release the
slot if it failed.

Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hisi_sas/hisi_sas_main.c

index f86263b3bf1cadef8fa17830849372b038a635a5..1391f2dd8102e7ff172f5f67ad3d1d2b320e54c4 100644 (file)
@@ -962,8 +962,13 @@ static int hisi_sas_abort_task(struct sas_task *task)
                struct hisi_sas_slot *slot = task->lldd_task;
                u32 tag = slot->idx;
 
-               hisi_sas_internal_task_abort(hisi_hba, device,
-                                            HISI_SAS_INT_ABT_CMD, tag);
+               rc = hisi_sas_internal_task_abort(hisi_hba, device,
+                            HISI_SAS_INT_ABT_CMD, tag);
+               if (rc == TMF_RESP_FUNC_FAILED) {
+                       spin_lock_irqsave(&hisi_hba->lock, flags);
+                       hisi_sas_do_release_task(hisi_hba, task, slot);
+                       spin_unlock_irqrestore(&hisi_hba->lock, flags);
+               }
        }
 
 out: