scsi: lpfc: Fix soft lockup in lpfc worker thread during LIP testing
authorJames Smart <jsmart2021@gmail.com>
Tue, 30 Jan 2018 23:58:54 +0000 (15:58 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 12 Feb 2018 16:43:23 +0000 (11:43 -0500)
During link bounce testing in a point-to-point topology, the host may
enter a soft lockup on the lpfc_worker thread:

    Call Trace:
     lpfc_work_done+0x1f3/0x1390 [lpfc]
     lpfc_do_work+0x16f/0x180 [lpfc]
     kthread+0xc7/0xe0
     ret_from_fork+0x3f/0x70

The driver was simultaneously setting a combination of flags that caused
lpfc_do_work()to effectively spin between slow path work and new event
data, causing the lockup.

Ensure in the typical wq completions, that new event data flags are set
if the slow path flag is running. The slow path will eventually
reschedule the wq handling.

Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <james.smart@broadcom.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc_hbadisc.c

index b159a5c4e388e0ff3fa8a9a9177298ce5c5115ca..9265906d956e5ff6d1872bcc925cbc8043d10a23 100644 (file)
@@ -696,8 +696,9 @@ lpfc_work_done(struct lpfc_hba *phba)
                      phba->hba_flag & HBA_SP_QUEUE_EVT)) {
                if (pring->flag & LPFC_STOP_IOCB_EVENT) {
                        pring->flag |= LPFC_DEFERRED_RING_EVENT;
-                       /* Set the lpfc data pending flag */
-                       set_bit(LPFC_DATA_READY, &phba->data_flags);
+                       /* Preserve legacy behavior. */
+                       if (!(phba->hba_flag & HBA_SP_QUEUE_EVT))
+                               set_bit(LPFC_DATA_READY, &phba->data_flags);
                } else {
                        if (phba->link_state >= LPFC_LINK_UP ||
                            phba->link_flag & LS_MDS_LOOPBACK) {