Skip to content

Commit ded2019

Browse files
Justin Teemartinkpetersen
authored andcommitted
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent d11272b commit ded2019

File tree

3 files changed

+19
-20
lines changed

3 files changed

+19
-20
lines changed

drivers/scsi/lpfc/lpfc_els.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4437,23 +4437,23 @@ lpfc_els_retry_delay(struct timer_list *t)
44374437
unsigned long flags;
44384438
struct lpfc_work_evt *evtp = &ndlp->els_retry_evt;
44394439

4440+
/* Hold a node reference for outstanding queued work */
4441+
if (!lpfc_nlp_get(ndlp))
4442+
return;
4443+
44404444
spin_lock_irqsave(&phba->hbalock, flags);
44414445
if (!list_empty(&evtp->evt_listp)) {
44424446
spin_unlock_irqrestore(&phba->hbalock, flags);
4447+
lpfc_nlp_put(ndlp);
44434448
return;
44444449
}
44454450

4446-
/* We need to hold the node by incrementing the reference
4447-
* count until the queued work is done
4448-
*/
4449-
evtp->evt_arg1 = lpfc_nlp_get(ndlp);
4450-
if (evtp->evt_arg1) {
4451-
evtp->evt = LPFC_EVT_ELS_RETRY;
4452-
list_add_tail(&evtp->evt_listp, &phba->work_list);
4453-
lpfc_worker_wake_up(phba);
4454-
}
4451+
evtp->evt_arg1 = ndlp;
4452+
evtp->evt = LPFC_EVT_ELS_RETRY;
4453+
list_add_tail(&evtp->evt_listp, &phba->work_list);
44554454
spin_unlock_irqrestore(&phba->hbalock, flags);
4456-
return;
4455+
4456+
lpfc_worker_wake_up(phba);
44574457
}
44584458

44594459
/**

drivers/scsi/lpfc/lpfc_hbadisc.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,9 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
257257
if (evtp->evt_arg1) {
258258
evtp->evt = LPFC_EVT_DEV_LOSS;
259259
list_add_tail(&evtp->evt_listp, &phba->work_list);
260+
spin_unlock_irqrestore(&phba->hbalock, iflags);
260261
lpfc_worker_wake_up(phba);
262+
return;
261263
}
262264
spin_unlock_irqrestore(&phba->hbalock, iflags);
263265
} else {
@@ -275,10 +277,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
275277
lpfc_disc_state_machine(vport, ndlp, NULL,
276278
NLP_EVT_DEVICE_RM);
277279
}
278-
279280
}
280-
281-
return;
282281
}
283282

284283
/**

drivers/scsi/lpfc/lpfc_sli.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,9 +1217,9 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
12171217
empty = list_empty(&phba->active_rrq_list);
12181218
list_add_tail(&rrq->list, &phba->active_rrq_list);
12191219
phba->hba_flag |= HBA_RRQ_ACTIVE;
1220+
spin_unlock_irqrestore(&phba->hbalock, iflags);
12201221
if (empty)
12211222
lpfc_worker_wake_up(phba);
1222-
spin_unlock_irqrestore(&phba->hbalock, iflags);
12231223
return 0;
12241224
out:
12251225
spin_unlock_irqrestore(&phba->hbalock, iflags);
@@ -11373,18 +11373,18 @@ lpfc_sli_post_recovery_event(struct lpfc_hba *phba,
1137311373
unsigned long iflags;
1137411374
struct lpfc_work_evt *evtp = &ndlp->recovery_evt;
1137511375

11376+
/* Hold a node reference for outstanding queued work */
11377+
if (!lpfc_nlp_get(ndlp))
11378+
return;
11379+
1137611380
spin_lock_irqsave(&phba->hbalock, iflags);
1137711381
if (!list_empty(&evtp->evt_listp)) {
1137811382
spin_unlock_irqrestore(&phba->hbalock, iflags);
11383+
lpfc_nlp_put(ndlp);
1137911384
return;
1138011385
}
1138111386

11382-
/* Incrementing the reference count until the queued work is done. */
11383-
evtp->evt_arg1 = lpfc_nlp_get(ndlp);
11384-
if (!evtp->evt_arg1) {
11385-
spin_unlock_irqrestore(&phba->hbalock, iflags);
11386-
return;
11387-
}
11387+
evtp->evt_arg1 = ndlp;
1138811388
evtp->evt = LPFC_EVT_RECOVER_PORT;
1138911389
list_add_tail(&evtp->evt_listp, &phba->work_list);
1139011390
spin_unlock_irqrestore(&phba->hbalock, iflags);

0 commit comments

Comments
 (0)