Skip to content

Commit bf81e9c

Browse files
Justin Teemartinkpetersen
authored andcommitted
scsi: lpfc: Clear deferred RSCN processing flag when driver is unloading
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 18f7761 commit bf81e9c

File tree

2 files changed

+45
-30
lines changed

2 files changed

+45
-30
lines changed

drivers/scsi/lpfc/lpfc_nportdisc.c

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@
4747
#include "lpfc_debugfs.h"
4848

4949

50+
/* Called to clear RSCN discovery flags when driver is unloading. */
51+
static bool
52+
lpfc_check_unload_and_clr_rscn(unsigned long *fc_flag)
53+
{
54+
/* If unloading, then clear the FC_RSCN_DEFERRED flag */
55+
if (test_bit(FC_UNLOADING, fc_flag)) {
56+
clear_bit(FC_RSCN_DEFERRED, fc_flag);
57+
return false;
58+
}
59+
return test_bit(FC_RSCN_DEFERRED, fc_flag);
60+
}
61+
5062
/* Called to verify a rcv'ed ADISC was intended for us. */
5163
static int
5264
lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
@@ -213,8 +225,10 @@ void
213225
lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
214226
{
215227
LIST_HEAD(abort_list);
228+
LIST_HEAD(drv_cmpl_list);
216229
struct lpfc_sli_ring *pring;
217230
struct lpfc_iocbq *iocb, *next_iocb;
231+
int retval = 0;
218232

219233
pring = lpfc_phba_elsring(phba);
220234

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

251265
/* Abort the targeted IOs and remove them from the abort list. */
252266
list_for_each_entry_safe(iocb, next_iocb, &abort_list, dlist) {
253-
spin_lock_irq(&phba->hbalock);
254-
list_del_init(&iocb->dlist);
255-
lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL);
256-
spin_unlock_irq(&phba->hbalock);
267+
spin_lock_irq(&phba->hbalock);
268+
list_del_init(&iocb->dlist);
269+
retval = lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL);
270+
spin_unlock_irq(&phba->hbalock);
271+
272+
if (retval && test_bit(FC_UNLOADING, &phba->pport->load_flag)) {
273+
list_del_init(&iocb->list);
274+
list_add_tail(&iocb->list, &drv_cmpl_list);
275+
}
257276
}
277+
278+
lpfc_sli_cancel_iocbs(phba, &drv_cmpl_list, IOSTAT_LOCAL_REJECT,
279+
IOERR_SLI_ABORTED);
280+
258281
/* Make sure HBA is alive */
259282
lpfc_issue_hb_tmo(phba);
260283

@@ -1604,10 +1627,8 @@ lpfc_device_recov_plogi_issue(struct lpfc_vport *vport,
16041627
{
16051628
struct lpfc_hba *phba = vport->phba;
16061629

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

16131634
/* software abort outstanding PLOGI */
@@ -1790,10 +1811,8 @@ lpfc_device_recov_adisc_issue(struct lpfc_vport *vport,
17901811
{
17911812
struct lpfc_hba *phba = vport->phba;
17921813

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

17991818
/* software abort outstanding ADISC */
@@ -2059,10 +2078,8 @@ lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport,
20592078
void *arg,
20602079
uint32_t evt)
20612080
{
2062-
/* Don't do anything that will mess up processing of the
2063-
* previous RSCN.
2064-
*/
2065-
if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag))
2081+
/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */
2082+
if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))
20662083
return ndlp->nlp_state;
20672084

20682085
ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
@@ -2375,10 +2392,8 @@ lpfc_device_recov_prli_issue(struct lpfc_vport *vport,
23752392
{
23762393
struct lpfc_hba *phba = vport->phba;
23772394

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

23842399
/* software abort outstanding PRLI */
@@ -2894,10 +2909,8 @@ static uint32_t
28942909
lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
28952910
void *arg, uint32_t evt)
28962911
{
2897-
/* Don't do anything that will mess up processing of the
2898-
* previous RSCN.
2899-
*/
2900-
if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag))
2912+
/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */
2913+
if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))
29012914
return ndlp->nlp_state;
29022915

29032916
lpfc_cancel_retry_delay_tmo(vport, ndlp);

drivers/scsi/lpfc/lpfc_sli.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12361,10 +12361,10 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1236112361

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

12463-
if (phba->link_state < LPFC_LINK_UP ||
12463+
/* Just close the exchange under certain conditions. */
12464+
if (test_bit(FC_UNLOADING, &vport->load_flag) ||
12465+
phba->link_state < LPFC_LINK_UP ||
1246412466
(phba->sli_rev == LPFC_SLI_REV4 &&
1246512467
phba->sli4_hba.link_state.status == LPFC_FC_LA_TYPE_LINK_DOWN) ||
1246612468
(phba->link_flag & LS_EXTERNAL_LOOPBACK))
@@ -12507,10 +12509,10 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1250712509
lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI,
1250812510
"0339 Abort IO XRI x%x, Original iotag x%x, "
1250912511
"abort tag x%x Cmdjob : x%px Abortjob : x%px "
12510-
"retval x%x\n",
12512+
"retval x%x : IA %d\n",
1251112513
ulp_context, (phba->sli_rev == LPFC_SLI_REV4) ?
1251212514
cmdiocb->iotag : iotag, iotag, cmdiocb, abtsiocbp,
12513-
retval);
12515+
retval, ia);
1251412516
if (retval) {
1251512517
cmdiocb->cmd_flag &= ~LPFC_DRIVER_ABORTED;
1251612518
__lpfc_sli_release_iocbq(phba, abtsiocbp);

0 commit comments

Comments
 (0)