Skip to content

Commit

Permalink
scsi: lpfc: Clear deferred RSCN processing flag when driver is unloading
Browse files Browse the repository at this point in the history
Device recovery logic is skipped when the RSCN processing flag is set.
However during rmmod, the flag is not cleared leading to unnecessary delays
in waiting for completions on a link that is being offlined.

Move clearing of the RSCN deferred flag to a refactored routine when called
from device recovery, and set the IA flag when issuing an abort during
unload.

Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20240429221547.6842-4-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Justin Tee authored and Martin K. Petersen committed May 7, 2024
1 parent 18f7761 commit bf81e9c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 30 deletions.
61 changes: 37 additions & 24 deletions drivers/scsi/lpfc/lpfc_nportdisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@
#include "lpfc_debugfs.h"


/* Called to clear RSCN discovery flags when driver is unloading. */
static bool
lpfc_check_unload_and_clr_rscn(unsigned long *fc_flag)
{
/* If unloading, then clear the FC_RSCN_DEFERRED flag */
if (test_bit(FC_UNLOADING, fc_flag)) {
clear_bit(FC_RSCN_DEFERRED, fc_flag);
return false;
}
return test_bit(FC_RSCN_DEFERRED, fc_flag);
}

/* Called to verify a rcv'ed ADISC was intended for us. */
static int
lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
Expand Down Expand Up @@ -213,8 +225,10 @@ void
lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
{
LIST_HEAD(abort_list);
LIST_HEAD(drv_cmpl_list);
struct lpfc_sli_ring *pring;
struct lpfc_iocbq *iocb, *next_iocb;
int retval = 0;

pring = lpfc_phba_elsring(phba);

Expand Down Expand Up @@ -250,11 +264,20 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)

/* Abort the targeted IOs and remove them from the abort list. */
list_for_each_entry_safe(iocb, next_iocb, &abort_list, dlist) {
spin_lock_irq(&phba->hbalock);
list_del_init(&iocb->dlist);
lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL);
spin_unlock_irq(&phba->hbalock);
spin_lock_irq(&phba->hbalock);
list_del_init(&iocb->dlist);
retval = lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL);
spin_unlock_irq(&phba->hbalock);

if (retval && test_bit(FC_UNLOADING, &phba->pport->load_flag)) {
list_del_init(&iocb->list);
list_add_tail(&iocb->list, &drv_cmpl_list);
}
}

lpfc_sli_cancel_iocbs(phba, &drv_cmpl_list, IOSTAT_LOCAL_REJECT,
IOERR_SLI_ABORTED);

/* Make sure HBA is alive */
lpfc_issue_hb_tmo(phba);

Expand Down Expand Up @@ -1604,10 +1627,8 @@ lpfc_device_recov_plogi_issue(struct lpfc_vport *vport,
{
struct lpfc_hba *phba = vport->phba;

/* Don't do anything that will mess up processing of the
* previous RSCN.
*/
if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag))
/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */
if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))
return ndlp->nlp_state;

/* software abort outstanding PLOGI */
Expand Down Expand Up @@ -1790,10 +1811,8 @@ lpfc_device_recov_adisc_issue(struct lpfc_vport *vport,
{
struct lpfc_hba *phba = vport->phba;

/* Don't do anything that will mess up processing of the
* previous RSCN.
*/
if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag))
/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */
if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))
return ndlp->nlp_state;

/* software abort outstanding ADISC */
Expand Down Expand Up @@ -2059,10 +2078,8 @@ lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport,
void *arg,
uint32_t evt)
{
/* Don't do anything that will mess up processing of the
* previous RSCN.
*/
if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag))
/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */
if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))
return ndlp->nlp_state;

ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
Expand Down Expand Up @@ -2375,10 +2392,8 @@ lpfc_device_recov_prli_issue(struct lpfc_vport *vport,
{
struct lpfc_hba *phba = vport->phba;

/* Don't do anything that will mess up processing of the
* previous RSCN.
*/
if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag))
/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */
if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))
return ndlp->nlp_state;

/* software abort outstanding PRLI */
Expand Down Expand Up @@ -2894,10 +2909,8 @@ static uint32_t
lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
void *arg, uint32_t evt)
{
/* Don't do anything that will mess up processing of the
* previous RSCN.
*/
if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag))
/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */
if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))
return ndlp->nlp_state;

lpfc_cancel_retry_delay_tmo(vport, ndlp);
Expand Down
14 changes: 8 additions & 6 deletions drivers/scsi/lpfc/lpfc_sli.c
Original file line number Diff line number Diff line change
Expand Up @@ -12361,10 +12361,10 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,

/* ELS cmd tag <ulpIoTag> completes */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
"0139 Ignoring ELS cmd code x%x completion Data: "
"0139 Ignoring ELS cmd code x%x ref cnt x%x Data: "
"x%x x%x x%x x%px\n",
ulp_command, ulp_status, ulp_word4, iotag,
cmdiocb->ndlp);
ulp_command, kref_read(&cmdiocb->ndlp->kref),
ulp_status, ulp_word4, iotag, cmdiocb->ndlp);
/*
* Deref the ndlp after free_iocb. sli_release_iocb will access the ndlp
* if exchange is busy.
Expand Down Expand Up @@ -12460,7 +12460,9 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
}
}

if (phba->link_state < LPFC_LINK_UP ||
/* Just close the exchange under certain conditions. */
if (test_bit(FC_UNLOADING, &vport->load_flag) ||
phba->link_state < LPFC_LINK_UP ||
(phba->sli_rev == LPFC_SLI_REV4 &&
phba->sli4_hba.link_state.status == LPFC_FC_LA_TYPE_LINK_DOWN) ||
(phba->link_flag & LS_EXTERNAL_LOOPBACK))
Expand Down Expand Up @@ -12507,10 +12509,10 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI,
"0339 Abort IO XRI x%x, Original iotag x%x, "
"abort tag x%x Cmdjob : x%px Abortjob : x%px "
"retval x%x\n",
"retval x%x : IA %d\n",
ulp_context, (phba->sli_rev == LPFC_SLI_REV4) ?
cmdiocb->iotag : iotag, iotag, cmdiocb, abtsiocbp,
retval);
retval, ia);
if (retval) {
cmdiocb->cmd_flag &= ~LPFC_DRIVER_ABORTED;
__lpfc_sli_release_iocbq(phba, abtsiocbp);
Expand Down

0 comments on commit bf81e9c

Please sign in to comment.