aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <jsmart2021@gmail.com>2019-03-12 16:30:14 -0700
committerMartin K. Petersen <martin.petersen@oracle.com>2019-03-19 12:57:02 -0400
commit4645f7b56a9fc3fb16605a1bfa10d884fcd5226c (patch)
treefbb1db9184cea3a16f597c7357da022b5d7a353b /drivers/scsi/lpfc/lpfc_sli.c
parent32a9310076e4f00ac6d8a5a2d39b953d199bef0d (diff)
scsi: lpfc: Coordinate adapter error handling with offline handling
The driver periodically checks for adapter error in a background thread. If the thread detects an error, the adapter will be reset including the deletion and reallocation of workqueues on the adapter. Simultaneously, there may be a user-space request to offline the adapter which may try to do many of the same steps, in parallel, on a different thread. As memory was deallocated while unexpected, the parallel offline request hit a bad pointer. Add coordination between the two threads. The error recovery thread has precedence. So, when an error is detected, a flag is set on the adapter to indicate the error thread is terminating the adapter. But, before doing that work, it will look for a flag that is set by the offline flow, and if set, will wait for it to complete before then processing the error handling path. Similarly, in the offline thread, it first checks for whether the error thread is resetting the adapter, and if so, will then wait for the error thread to finish. Only after it has finished, will it set its flag and offline the adapter. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 32ded3e9b32e..4b084a408e71 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -14417,6 +14417,9 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue)
if (!queue)
return;
+ if (!list_empty(&queue->wq_list))
+ list_del(&queue->wq_list);
+
while (!list_empty(&queue->page_list)) {
list_remove_head(&queue->page_list, dmabuf, struct lpfc_dmabuf,
list);
@@ -14432,9 +14435,6 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue)
if (!list_empty(&queue->cpu_list))
list_del(&queue->cpu_list);
- if (!list_empty(&queue->wq_list))
- list_del(&queue->wq_list);
-
kfree(queue);
return;
}