Commit e294647b authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: Move cfg_log_verbose check before calling lpfc_dmp_dbg()

In an attempt to log message 0126 with LOG_TRACE_EVENT, the following hard
lockup call trace hangs the system.

Call Trace:
 _raw_spin_lock_irqsave+0x32/0x40
 lpfc_dmp_dbg.part.32+0x28/0x220 [lpfc]
 lpfc_cmpl_els_fdisc+0x145/0x460 [lpfc]
 lpfc_sli_cancel_jobs+0x92/0xd0 [lpfc]
 lpfc_els_flush_cmd+0x43c/0x670 [lpfc]
 lpfc_els_flush_all_cmd+0x37/0x60 [lpfc]
 lpfc_sli4_async_event_proc+0x956/0x1720 [lpfc]
 lpfc_do_work+0x1485/0x1d70 [lpfc]
 kthread+0x112/0x130
 ret_from_fork+0x1f/0x40
Kernel panic - not syncing: Hard LOCKUP

The same CPU tries to claim the phba->port_list_lock twice.

Move the cfg_log_verbose checks as part of the lpfc_printf_vlog() and
lpfc_printf_log() macros before calling lpfc_dmp_dbg().  There is no need
to take the phba->port_list_lock within lpfc_dmp_dbg().

Link: https://lore.kernel.org/r/20220412222008.126521-3-jsmart2021@gmail.comCo-developed-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent b83a8c21
...@@ -15700,34 +15700,7 @@ void lpfc_dmp_dbg(struct lpfc_hba *phba) ...@@ -15700,34 +15700,7 @@ void lpfc_dmp_dbg(struct lpfc_hba *phba)
unsigned int temp_idx; unsigned int temp_idx;
int i; int i;
int j = 0; int j = 0;
unsigned long rem_nsec, iflags; unsigned long rem_nsec;
bool log_verbose = false;
struct lpfc_vport *port_iterator;
/* Don't dump messages if we explicitly set log_verbose for the
* physical port or any vport.
*/
if (phba->cfg_log_verbose)
return;
spin_lock_irqsave(&phba->port_list_lock, iflags);
list_for_each_entry(port_iterator, &phba->port_list, listentry) {
if (port_iterator->load_flag & FC_UNLOADING)
continue;
if (scsi_host_get(lpfc_shost_from_vport(port_iterator))) {
if (port_iterator->cfg_log_verbose)
log_verbose = true;
scsi_host_put(lpfc_shost_from_vport(port_iterator));
if (log_verbose) {
spin_unlock_irqrestore(&phba->port_list_lock,
iflags);
return;
}
}
}
spin_unlock_irqrestore(&phba->port_list_lock, iflags);
if (atomic_cmpxchg(&phba->dbg_log_dmping, 0, 1) != 0) if (atomic_cmpxchg(&phba->dbg_log_dmping, 0, 1) != 0)
return; return;
......
...@@ -73,7 +73,7 @@ do { \ ...@@ -73,7 +73,7 @@ do { \
#define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ #define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \
do { \ do { \
{ if (((mask) & (vport)->cfg_log_verbose) || (level[1] <= '3')) { \ { if (((mask) & (vport)->cfg_log_verbose) || (level[1] <= '3')) { \
if ((mask) & LOG_TRACE_EVENT) \ if ((mask) & LOG_TRACE_EVENT && !(vport)->cfg_log_verbose) \
lpfc_dmp_dbg((vport)->phba); \ lpfc_dmp_dbg((vport)->phba); \
dev_printk(level, &((vport)->phba->pcidev)->dev, "%d:(%d):" \ dev_printk(level, &((vport)->phba->pcidev)->dev, "%d:(%d):" \
fmt, (vport)->phba->brd_no, vport->vpi, ##arg); \ fmt, (vport)->phba->brd_no, vport->vpi, ##arg); \
...@@ -89,11 +89,11 @@ do { \ ...@@ -89,11 +89,11 @@ do { \
(phba)->pport->cfg_log_verbose : \ (phba)->pport->cfg_log_verbose : \
(phba)->cfg_log_verbose; \ (phba)->cfg_log_verbose; \
if (((mask) & log_verbose) || (level[1] <= '3')) { \ if (((mask) & log_verbose) || (level[1] <= '3')) { \
if ((mask) & LOG_TRACE_EVENT) \ if ((mask) & LOG_TRACE_EVENT && !log_verbose) \
lpfc_dmp_dbg(phba); \ lpfc_dmp_dbg(phba); \
dev_printk(level, &((phba)->pcidev)->dev, "%d:" \ dev_printk(level, &((phba)->pcidev)->dev, "%d:" \
fmt, phba->brd_no, ##arg); \ fmt, phba->brd_no, ##arg); \
} else if (!(phba)->cfg_log_verbose)\ } else if (!log_verbose)\
lpfc_dbg_print(phba, "%d:" fmt, phba->brd_no, ##arg); \ lpfc_dbg_print(phba, "%d:" fmt, phba->brd_no, ##arg); \
} \ } \
} while (0) } while (0)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment