@@ -5429,6 +5429,180 @@ lpfc_idiag_extacc_read(struct file *file, char __user *buf, size_t nbytes,
54295429 return simple_read_from_buffer (buf , nbytes , ppos , pbuffer , len );
54305430}
54315431
5432+ static int
5433+ lpfc_cgn_buffer_open (struct inode * inode , struct file * file )
5434+ {
5435+ struct lpfc_debug * debug ;
5436+ int rc = - ENOMEM ;
5437+
5438+ debug = kmalloc (sizeof (* debug ), GFP_KERNEL );
5439+ if (!debug )
5440+ goto out ;
5441+
5442+ debug -> buffer = vmalloc (LPFC_CGN_BUF_SIZE );
5443+ if (!debug -> buffer ) {
5444+ kfree (debug );
5445+ goto out ;
5446+ }
5447+
5448+ debug -> i_private = inode -> i_private ;
5449+ file -> private_data = debug ;
5450+
5451+ rc = 0 ;
5452+ out :
5453+ return rc ;
5454+ }
5455+
5456+ static ssize_t
5457+ lpfc_cgn_buffer_read (struct file * file , char __user * buf , size_t nbytes ,
5458+ loff_t * ppos )
5459+ {
5460+ struct lpfc_debug * debug = file -> private_data ;
5461+ struct lpfc_hba * phba = (struct lpfc_hba * )debug -> i_private ;
5462+ char * buffer = debug -> buffer ;
5463+ uint32_t * ptr ;
5464+ int cnt , len = 0 ;
5465+
5466+ if (!phba -> sli4_hba .pc_sli4_params .mi_ver || !phba -> cgn_i ) {
5467+ len += scnprintf (buffer + len , LPFC_CGN_BUF_SIZE - len ,
5468+ "Congestion Mgmt is not supported\n" );
5469+ goto out ;
5470+ }
5471+ ptr = (uint32_t * )phba -> cgn_i -> virt ;
5472+ len += scnprintf (buffer + len , LPFC_CGN_BUF_SIZE - len ,
5473+ "Congestion Buffer Header\n" );
5474+ /* Dump the first 32 bytes */
5475+ cnt = 32 ;
5476+ len += scnprintf (buffer + len , LPFC_CGN_BUF_SIZE - len ,
5477+ "000: %08x %08x %08x %08x %08x %08x %08x %08x\n" ,
5478+ * ptr , * (ptr + 1 ), * (ptr + 2 ), * (ptr + 3 ),
5479+ * (ptr + 4 ), * (ptr + 5 ), * (ptr + 6 ), * (ptr + 7 ));
5480+ ptr += 8 ;
5481+ len += scnprintf (buffer + len , LPFC_CGN_BUF_SIZE - len ,
5482+ "Congestion Buffer Data\n" );
5483+ while (cnt < sizeof (struct lpfc_cgn_info )) {
5484+ if (len > (LPFC_CGN_BUF_SIZE - LPFC_DEBUG_OUT_LINE_SZ )) {
5485+ len += scnprintf (buffer + len , LPFC_CGN_BUF_SIZE - len ,
5486+ "Truncated . . .\n" );
5487+ break ;
5488+ }
5489+ len += scnprintf (buffer + len , LPFC_CGN_BUF_SIZE - len ,
5490+ "%03x: %08x %08x %08x %08x "
5491+ "%08x %08x %08x %08x\n" ,
5492+ cnt , * ptr , * (ptr + 1 ), * (ptr + 2 ),
5493+ * (ptr + 3 ), * (ptr + 4 ), * (ptr + 5 ),
5494+ * (ptr + 6 ), * (ptr + 7 ));
5495+ cnt += 32 ;
5496+ ptr += 8 ;
5497+ }
5498+ out :
5499+ return simple_read_from_buffer (buf , nbytes , ppos , buffer , len );
5500+ }
5501+
5502+ static int
5503+ lpfc_cgn_buffer_release (struct inode * inode , struct file * file )
5504+ {
5505+ struct lpfc_debug * debug = file -> private_data ;
5506+
5507+ vfree (debug -> buffer );
5508+ kfree (debug );
5509+
5510+ return 0 ;
5511+ }
5512+
5513+ static int
5514+ lpfc_rx_monitor_open (struct inode * inode , struct file * file )
5515+ {
5516+ struct lpfc_rx_monitor_debug * debug ;
5517+ int rc = - ENOMEM ;
5518+
5519+ debug = kmalloc (sizeof (* debug ), GFP_KERNEL );
5520+ if (!debug )
5521+ goto out ;
5522+
5523+ debug -> buffer = vmalloc (MAX_DEBUGFS_RX_TABLE_SIZE );
5524+ if (!debug -> buffer ) {
5525+ kfree (debug );
5526+ goto out ;
5527+ }
5528+
5529+ debug -> i_private = inode -> i_private ;
5530+ file -> private_data = debug ;
5531+
5532+ rc = 0 ;
5533+ out :
5534+ return rc ;
5535+ }
5536+
5537+ static ssize_t
5538+ lpfc_rx_monitor_read (struct file * file , char __user * buf , size_t nbytes ,
5539+ loff_t * ppos )
5540+ {
5541+ struct lpfc_rx_monitor_debug * debug = file -> private_data ;
5542+ struct lpfc_hba * phba = (struct lpfc_hba * )debug -> i_private ;
5543+ char * buffer = debug -> buffer ;
5544+ struct rxtable_entry * entry ;
5545+ int i , len = 0 , head , tail , last , start ;
5546+
5547+ head = atomic_read (& phba -> rxtable_idx_head );
5548+ while (head == LPFC_RXMONITOR_TABLE_IN_USE ) {
5549+ /* Table is getting updated */
5550+ msleep (20 );
5551+ head = atomic_read (& phba -> rxtable_idx_head );
5552+ }
5553+
5554+ tail = atomic_xchg (& phba -> rxtable_idx_tail , head );
5555+ if (!phba -> rxtable || head == tail ) {
5556+ len += scnprintf (buffer + len , MAX_DEBUGFS_RX_TABLE_SIZE - len ,
5557+ "Rxtable is empty\n" );
5558+ goto out ;
5559+ }
5560+ last = (head > tail ) ? head : LPFC_MAX_RXMONITOR_ENTRY ;
5561+ start = tail ;
5562+
5563+ len += scnprintf (buffer + len , MAX_DEBUGFS_RX_TABLE_SIZE - len ,
5564+ " MaxBPI\t Total Data Cmd Total Data Cmpl "
5565+ " Latency(us) Avg IO Size\tMax IO Size IO cnt "
5566+ "Info BWutil(ms)\n" );
5567+ get_table :
5568+ for (i = start ; i < last ; i ++ ) {
5569+ entry = & phba -> rxtable [i ];
5570+ len += scnprintf (buffer + len , MAX_DEBUGFS_RX_TABLE_SIZE - len ,
5571+ "%3d:%12lld %12lld\t%12lld\t"
5572+ "%8lldus\t%8lld\t%10lld "
5573+ "%8d %2d %2d(%2d)\n" ,
5574+ i , entry -> max_bytes_per_interval ,
5575+ entry -> total_bytes ,
5576+ entry -> rcv_bytes ,
5577+ entry -> avg_io_latency ,
5578+ entry -> avg_io_size ,
5579+ entry -> max_read_cnt ,
5580+ entry -> io_cnt ,
5581+ entry -> cmf_info ,
5582+ entry -> timer_utilization ,
5583+ entry -> timer_interval );
5584+ }
5585+
5586+ if (head != last ) {
5587+ start = 0 ;
5588+ last = head ;
5589+ goto get_table ;
5590+ }
5591+ out :
5592+ return simple_read_from_buffer (buf , nbytes , ppos , buffer , len );
5593+ }
5594+
5595+ static int
5596+ lpfc_rx_monitor_release (struct inode * inode , struct file * file )
5597+ {
5598+ struct lpfc_rx_monitor_debug * debug = file -> private_data ;
5599+
5600+ vfree (debug -> buffer );
5601+ kfree (debug );
5602+
5603+ return 0 ;
5604+ }
5605+
54325606#undef lpfc_debugfs_op_disc_trc
54335607static const struct file_operations lpfc_debugfs_op_disc_trc = {
54345608 .owner = THIS_MODULE ,
@@ -5657,6 +5831,23 @@ static const struct file_operations lpfc_idiag_op_extAcc = {
56575831 .write = lpfc_idiag_extacc_write ,
56585832 .release = lpfc_idiag_cmd_release ,
56595833};
5834+ #undef lpfc_cgn_buffer_op
5835+ static const struct file_operations lpfc_cgn_buffer_op = {
5836+ .owner = THIS_MODULE ,
5837+ .open = lpfc_cgn_buffer_open ,
5838+ .llseek = lpfc_debugfs_lseek ,
5839+ .read = lpfc_cgn_buffer_read ,
5840+ .release = lpfc_cgn_buffer_release ,
5841+ };
5842+
5843+ #undef lpfc_rx_monitor_op
5844+ static const struct file_operations lpfc_rx_monitor_op = {
5845+ .owner = THIS_MODULE ,
5846+ .open = lpfc_rx_monitor_open ,
5847+ .llseek = lpfc_debugfs_lseek ,
5848+ .read = lpfc_rx_monitor_read ,
5849+ .release = lpfc_rx_monitor_release ,
5850+ };
56605851#endif
56615852
56625853/* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command
@@ -5907,6 +6098,32 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
59076098 goto debug_failed ;
59086099 }
59096100
6101+ /* Congestion Info Buffer */
6102+ scnprintf (name , sizeof (name ), "cgn_buffer" );
6103+ phba -> debug_cgn_buffer =
6104+ debugfs_create_file (name , S_IFREG | 0644 ,
6105+ phba -> hba_debugfs_root ,
6106+ phba , & lpfc_cgn_buffer_op );
6107+ if (!phba -> debug_cgn_buffer ) {
6108+ lpfc_printf_vlog (vport , KERN_ERR , LOG_INIT ,
6109+ "6527 Cannot create debugfs "
6110+ "cgn_buffer\n" );
6111+ goto debug_failed ;
6112+ }
6113+
6114+ /* RX Monitor */
6115+ scnprintf (name , sizeof (name ), "rx_monitor" );
6116+ phba -> debug_rx_monitor =
6117+ debugfs_create_file (name , S_IFREG | 0644 ,
6118+ phba -> hba_debugfs_root ,
6119+ phba , & lpfc_rx_monitor_op );
6120+ if (!phba -> debug_rx_monitor ) {
6121+ lpfc_printf_vlog (vport , KERN_ERR , LOG_INIT ,
6122+ "6528 Cannot create debugfs "
6123+ "rx_monitor\n" );
6124+ goto debug_failed ;
6125+ }
6126+
59106127 /* RAS log */
59116128 snprintf (name , sizeof (name ), "ras_log" );
59126129 phba -> debug_ras_log =
@@ -6335,6 +6552,12 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
63356552 debugfs_remove (phba -> debug_hbqinfo ); /* hbqinfo */
63366553 phba -> debug_hbqinfo = NULL ;
63376554
6555+ debugfs_remove (phba -> debug_cgn_buffer );
6556+ phba -> debug_cgn_buffer = NULL ;
6557+
6558+ debugfs_remove (phba -> debug_rx_monitor );
6559+ phba -> debug_rx_monitor = NULL ;
6560+
63386561 debugfs_remove (phba -> debug_ras_log );
63396562 phba -> debug_ras_log = NULL ;
63406563
0 commit comments