Skip to content

Commit 9f77870

Browse files
jsmart-ghmartinkpetersen
authored andcommitted
scsi: lpfc: Add debugfs support for cm framework buffers
Add support via debugfs to report the cm statistics, cm enablement, and rx monitor information. Link: https://lore.kernel.org/r/[email protected] Co-developed-by: Justin Tee <[email protected]> Signed-off-by: Justin Tee <[email protected]> Signed-off-by: James Smart <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 7481811 commit 9f77870

File tree

3 files changed

+234
-0
lines changed

3 files changed

+234
-0
lines changed

drivers/scsi/lpfc/lpfc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,8 @@ struct lpfc_hba {
13571357
#ifdef LPFC_HDWQ_LOCK_STAT
13581358
struct dentry *debug_lockstat;
13591359
#endif
1360+
struct dentry *debug_cgn_buffer;
1361+
struct dentry *debug_rx_monitor;
13601362
struct dentry *debug_ras_log;
13611363
atomic_t nvmeio_trc_cnt;
13621364
uint32_t nvmeio_trc_size;

drivers/scsi/lpfc/lpfc_debugfs.c

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
54335607
static 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

drivers/scsi/lpfc/lpfc_debugfs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@
5252
/* scsistat output buffer size */
5353
#define LPFC_SCSISTAT_SIZE 8192
5454

55+
/* Congestion Info Buffer size */
56+
#define LPFC_CGN_BUF_SIZE 8192
57+
5558
#define LPFC_DEBUG_OUT_LINE_SZ 80
5659

5760
/*
@@ -279,6 +282,12 @@ struct lpfc_idiag {
279282
void *ptr_private;
280283
};
281284

285+
#define MAX_DEBUGFS_RX_TABLE_SIZE (100 * LPFC_MAX_RXMONITOR_ENTRY)
286+
struct lpfc_rx_monitor_debug {
287+
char *i_private;
288+
char *buffer;
289+
};
290+
282291
#else
283292

284293
#define lpfc_nvmeio_data(phba, fmt, arg...) \

0 commit comments

Comments
 (0)