Driver team has highlighted this patch is required to address this issue:
author James Smart <email address hidden> 2022-04-12 15:19:44 -0700
committer Martin K. Petersen <email address hidden> 2022-04-18 22:48:43 -0400
commit e294647b1aed4247fe52851f3a3b2b19ae906228 (patch)
tree fd7e11a3c6f680d5aabd468d523d08ffcd66b59f /drivers/scsi/lpfc
parent b83a8c21f3fe874e12eb2b6e6c5cfb220d35c446 (diff)
download scsi-e294647b1aed4247fe52851f3a3b2b19ae906228.tar.gz
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.
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://<email address hidden>
Co-developed-by: Justin Tee <email address hidden>
Signed-off-by: Justin Tee <email address hidden>
Signed-off-by: James Smart <email address hidden>
Signed-off-by: Martin K. Petersen <email address hidden>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- drivers/scsi/lpfc/lpfc_init.c 29
-rw-r--r-- drivers/scsi/lpfc/lpfc_logmsg.h 6
2 files changed, 4 insertions, 31 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 461d333b1b3a8..f9cd4b72d949a 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -15700,34 +15700,7 @@ void lpfc_dmp_dbg(struct lpfc_hba *phba)
unsigned int temp_idx;
int i;
int j = 0;
- unsigned long rem_nsec, iflags;
- 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);
+ unsigned long rem_nsec;
if (atomic_cmpxchg(&phba->dbg_log_dmping, 0, 1) != 0)
return;
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h
index 7d480c7987942..a5aafe230c74f 100644
--- a/drivers/scsi/lpfc/lpfc_logmsg.h
+++ b/drivers/scsi/lpfc/lpfc_logmsg.h
@@ -73,7 +73,7 @@ do { \
#define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \
do { \
{ 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); \
dev_printk(level, &((vport)->phba->pcidev)->dev, "%d:(%d):" \
fmt, (vport)->phba->brd_no, vport->vpi, ##arg); \
@@ -89,11 +89,11 @@ do { \
(phba)->pport->cfg_log_verbose : \
(phba)->cfg_log_verbose; \
if (((mask) & log_verbose) || (level[1] <= '3')) { \
- if ((mask) & LOG_TRACE_EVENT) \
+ if ((mask) & LOG_TRACE_EVENT && !log_verbose) \
lpfc_dmp_dbg(phba); \
dev_printk(level, &((phba)->pcidev)->dev, "%d:" \
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); \
} \
} while (0)
Driver team has highlighted this patch is required to address this issue:
author James Smart <email address hidden> 2022-04-12 15:19:44 -0700 7fe52851f3a3b2b 19ae906228 (patch) 5aabd468d523d08 ffcd66b59f /drivers/scsi/lpfc e12eb2b6e6c5cfb 220d35c446 (diff) ed4247fe52851f3 a3b2b19ae906228 .tar.gz
committer Martin K. Petersen <email address hidden> 2022-04-18 22:48:43 -0400
commit e294647b1aed424
tree fd7e11a3c6f680d
parent b83a8c21f3fe874
download scsi-e294647b1a
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: lock_irqsave+ 0x32/0x40 dbg.part. 32+0x28/ 0x220 [lpfc] els_fdisc+ 0x145/0x460 [lpfc] cancel_ jobs+0x92/ 0xd0 [lpfc] flush_cmd+ 0x43c/0x670 [lpfc] flush_all_ cmd+0x37/ 0x60 [lpfc] async_event_ proc+0x956/ 0x1720 [lpfc] work+0x1485/ 0x1d70 [lpfc] 0x112/0x130 fork+0x1f/ 0x40
_raw_spin_
lpfc_dmp_
lpfc_cmpl_
lpfc_sli_
lpfc_els_
lpfc_els_
lpfc_sli4_
lpfc_do_
kthread+
ret_from_
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 list_lock within lpfc_dmp_dbg().
lpfc_printf_log() macros before calling lpfc_dmp_dbg(). There is no need
to take the phba->port_
Link: https://<email address hidden> scsi/lpfc' ) scsi/lpfc/ lpfc_init. c 29 scsi/lpfc/ lpfc_logmsg. h 6 scsi/lpfc/ lpfc_init. c b/drivers/ scsi/lpfc/ lpfc_init. c .f9cd4b72d949a 100644 scsi/lpfc/ lpfc_init. c scsi/lpfc/ lpfc_init. c cfg_log_ verbose) irqsave( &phba-> port_list_ lock, iflags); each_entry( port_iterator, &phba->port_list, listentry) { >load_flag & FC_UNLOADING) get(lpfc_ shost_from_ vport(port_ iterator) )) { >cfg_log_ verbose) put(lpfc_ shost_from_ vport(port_ iterator) ); irqrestore( &phba-> port_list_ lock, irqrestore( &phba-> port_list_ lock, iflags);
Co-developed-by: Justin Tee <email address hidden>
Signed-off-by: Justin Tee <email address hidden>
Signed-off-by: James Smart <email address hidden>
Signed-off-by: Martin K. Petersen <email address hidden>
Diffstat (limited to 'drivers/
-rw-r--r-- drivers/
-rw-r--r-- drivers/
2 files changed, 4 insertions, 31 deletions
diff --git a/drivers/
index 461d333b1b3a8.
--- a/drivers/
+++ b/drivers/
@@ -15700,34 +15700,7 @@ void lpfc_dmp_dbg(struct lpfc_hba *phba)
unsigned int temp_idx;
int i;
int j = 0;
- unsigned long rem_nsec, iflags;
- 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->
- return;
-
- spin_lock_
- list_for_
- if (port_iterator-
- continue;
- if (scsi_host_
- if (port_iterator-
- log_verbose = true;
-
- scsi_host_
-
- if (log_verbose) {
- spin_unlock_
- iflags);
- return;
- }
- }
- }
- spin_unlock_
+ unsigned long rem_nsec;
if (atomic_ cmpxchg( &phba-> dbg_log_ dmping, 0, 1) != 0) scsi/lpfc/ lpfc_logmsg. h b/drivers/ scsi/lpfc/ lpfc_logmsg. h .a5aafe230c74f 100644 scsi/lpfc/ lpfc_logmsg. h scsi/lpfc/ lpfc_logmsg. h vlog(vport, level, mask, fmt, arg...) \ ->cfg_log_ verbose) || (level[1] <= '3')) { \ ->cfg_log_ verbose) \ dmp_dbg( (vport) ->phba) ; \ printk( level, &((vport) ->phba- >pcidev) ->dev, "%d:(%d):" \ ->phba- >brd_no, vport->vpi, ##arg); \ phba)-> pport-> cfg_log_ verbose : \ phba)-> cfg_log_ verbose; \ dmp_dbg( phba); \ printk( level, &((phba) ->pcidev) ->dev, "%d:" \ ->cfg_log_ verbose) \ dbg_print( phba, "%d:" fmt, phba->brd_no, ##arg); \
return;
diff --git a/drivers/
index 7d480c7987942.
--- a/drivers/
+++ b/drivers/
@@ -73,7 +73,7 @@ do { \
#define lpfc_printf_
do { \
{ if (((mask) & (vport)
- if ((mask) & LOG_TRACE_EVENT) \
+ if ((mask) & LOG_TRACE_EVENT && !(vport)
lpfc_
dev_
fmt, (vport)
@@ -89,11 +89,11 @@ do { \
(
(
if (((mask) & log_verbose) || (level[1] <= '3')) { \
- if ((mask) & LOG_TRACE_EVENT) \
+ if ((mask) & LOG_TRACE_EVENT && !log_verbose) \
lpfc_
dev_
fmt, phba->brd_no, ##arg); \
- } else if (!(phba)
+ } else if (!log_verbose)\
lpfc_
} \
} while (0)