scsi: lpfc: Release hbalock before calling lpfc_worker_wake_up()
lpfc_worker_wake_up() calls the lpfc_work_done() routine, which takes the hbalock. Thus, lpfc_worker_wake_up() should not be called while holding the hbalock to avoid potential deadlock. Signed-off-by: Justin Tee <justin.tee@broadcom.com> Link: https://lore.kernel.org/r/20240305200503.57317-7-justintee8345@gmail.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
d11272be49
commit
ded20192df
@ -4437,23 +4437,23 @@ lpfc_els_retry_delay(struct timer_list *t)
|
||||
unsigned long flags;
|
||||
struct lpfc_work_evt *evtp = &ndlp->els_retry_evt;
|
||||
|
||||
/* Hold a node reference for outstanding queued work */
|
||||
if (!lpfc_nlp_get(ndlp))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&phba->hbalock, flags);
|
||||
if (!list_empty(&evtp->evt_listp)) {
|
||||
spin_unlock_irqrestore(&phba->hbalock, flags);
|
||||
lpfc_nlp_put(ndlp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We need to hold the node by incrementing the reference
|
||||
* count until the queued work is done
|
||||
*/
|
||||
evtp->evt_arg1 = lpfc_nlp_get(ndlp);
|
||||
if (evtp->evt_arg1) {
|
||||
evtp->evt = LPFC_EVT_ELS_RETRY;
|
||||
list_add_tail(&evtp->evt_listp, &phba->work_list);
|
||||
lpfc_worker_wake_up(phba);
|
||||
}
|
||||
evtp->evt_arg1 = ndlp;
|
||||
evtp->evt = LPFC_EVT_ELS_RETRY;
|
||||
list_add_tail(&evtp->evt_listp, &phba->work_list);
|
||||
spin_unlock_irqrestore(&phba->hbalock, flags);
|
||||
return;
|
||||
|
||||
lpfc_worker_wake_up(phba);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,7 +257,9 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
|
||||
if (evtp->evt_arg1) {
|
||||
evtp->evt = LPFC_EVT_DEV_LOSS;
|
||||
list_add_tail(&evtp->evt_listp, &phba->work_list);
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
lpfc_worker_wake_up(phba);
|
||||
return;
|
||||
}
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
} else {
|
||||
@ -275,10 +277,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
|
||||
lpfc_disc_state_machine(vport, ndlp, NULL,
|
||||
NLP_EVT_DEVICE_RM);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1217,9 +1217,9 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
|
||||
empty = list_empty(&phba->active_rrq_list);
|
||||
list_add_tail(&rrq->list, &phba->active_rrq_list);
|
||||
phba->hba_flag |= HBA_RRQ_ACTIVE;
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
if (empty)
|
||||
lpfc_worker_wake_up(phba);
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
return 0;
|
||||
out:
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
@ -11373,18 +11373,18 @@ lpfc_sli_post_recovery_event(struct lpfc_hba *phba,
|
||||
unsigned long iflags;
|
||||
struct lpfc_work_evt *evtp = &ndlp->recovery_evt;
|
||||
|
||||
/* Hold a node reference for outstanding queued work */
|
||||
if (!lpfc_nlp_get(ndlp))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&phba->hbalock, iflags);
|
||||
if (!list_empty(&evtp->evt_listp)) {
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
lpfc_nlp_put(ndlp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Incrementing the reference count until the queued work is done. */
|
||||
evtp->evt_arg1 = lpfc_nlp_get(ndlp);
|
||||
if (!evtp->evt_arg1) {
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
return;
|
||||
}
|
||||
evtp->evt_arg1 = ndlp;
|
||||
evtp->evt = LPFC_EVT_RECOVER_PORT;
|
||||
list_add_tail(&evtp->evt_listp, &phba->work_list);
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
|
Loading…
x
Reference in New Issue
Block a user