If an SSP/SMP IO times out, it may be actually in reality be
simultaneously processing completion of the slot in
slot_complete_vx_hw().
Then if the slot is freed in slot_complete_vx_hw() (this IPTT is freed
and it may be re-used by other slot), and we may abort the wrong slot in
hisi_sas_abort_task().
So to solve the issue, free the slot after the check of
SAS_TASK_STATE_ABORTED in slot_complete_vx_hw().
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>
        }
 
 out:
-       hisi_sas_slot_task_free(hisi_hba, task, slot);
        sts = ts->stat;
        spin_lock_irqsave(&task->task_state_lock, flags);
        if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
        }
        task->task_state_flags |= SAS_TASK_STATE_DONE;
        spin_unlock_irqrestore(&task->task_state_lock, flags);
+       hisi_sas_slot_task_free(hisi_hba, task, slot);
 
        if (!is_internal && (task->task_proto != SAS_PROTOCOL_SMP)) {
                spin_lock_irqsave(&device->done_lock, flags);
 
        }
 
 out:
-       hisi_sas_slot_task_free(hisi_hba, task, slot);
        sts = ts->stat;
        spin_lock_irqsave(&task->task_state_lock, flags);
        if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
        }
        task->task_state_flags |= SAS_TASK_STATE_DONE;
        spin_unlock_irqrestore(&task->task_state_lock, flags);
+       hisi_sas_slot_task_free(hisi_hba, task, slot);
 
        if (!is_internal && (task->task_proto != SAS_PROTOCOL_SMP)) {
                spin_lock_irqsave(&device->done_lock, flags);