Skip to content

Commit 2fcbc56

Browse files
jsmart-ghmartinkpetersen
authored andcommitted
scsi: lpfc: Make debugfs ktime stats generic for NVME and SCSI
Currently driver ktime stats, measuring code paths, is NVME-specific. Convert the stats routines such that the code paths are generic, providing status for NVME and SCSI. Added ktime stat calls in SCSI queuecommand and cmpl routines. Link: https://lore.kernel.org/r/20200322181304.37655-11-jsmart2021@gmail.com Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 840eda9 commit 2fcbc56

File tree

7 files changed

+137
-110
lines changed

7 files changed

+137
-110
lines changed

drivers/scsi/lpfc/lpfc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ struct lpfc_vport {
480480
struct dentry *debug_nodelist;
481481
struct dentry *debug_nvmestat;
482482
struct dentry *debug_scsistat;
483-
struct dentry *debug_nvmektime;
483+
struct dentry *debug_ioktime;
484484
struct dentry *debug_hdwqstat;
485485
struct dentry *vport_debugfs_root;
486486
struct lpfc_debugfs_trc *disc_trc;

drivers/scsi/lpfc/lpfc_crtn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ struct lpfc_io_buf *lpfc_get_io_buf(struct lpfc_hba *phba,
588588
int);
589589
void lpfc_release_io_buf(struct lpfc_hba *phba, struct lpfc_io_buf *ncmd,
590590
struct lpfc_sli4_hdw_queue *qp);
591+
void lpfc_io_ktime(struct lpfc_hba *phba, struct lpfc_io_buf *ncmd);
591592
void lpfc_nvme_cmd_template(void);
592593
void lpfc_nvmet_cmd_template(void);
593594
void lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn);

drivers/scsi/lpfc/lpfc_debugfs.c

Lines changed: 107 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,8 +1300,88 @@ lpfc_debugfs_scsistat_data(struct lpfc_vport *vport, char *buf, int size)
13001300
return len;
13011301
}
13021302

1303+
void
1304+
lpfc_io_ktime(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
1305+
{
1306+
uint64_t seg1, seg2, seg3, seg4;
1307+
uint64_t segsum;
1308+
1309+
if (!lpfc_cmd->ts_last_cmd ||
1310+
!lpfc_cmd->ts_cmd_start ||
1311+
!lpfc_cmd->ts_cmd_wqput ||
1312+
!lpfc_cmd->ts_isr_cmpl ||
1313+
!lpfc_cmd->ts_data_io)
1314+
return;
1315+
1316+
if (lpfc_cmd->ts_data_io < lpfc_cmd->ts_cmd_start)
1317+
return;
1318+
if (lpfc_cmd->ts_cmd_start < lpfc_cmd->ts_last_cmd)
1319+
return;
1320+
if (lpfc_cmd->ts_cmd_wqput < lpfc_cmd->ts_cmd_start)
1321+
return;
1322+
if (lpfc_cmd->ts_isr_cmpl < lpfc_cmd->ts_cmd_wqput)
1323+
return;
1324+
if (lpfc_cmd->ts_data_io < lpfc_cmd->ts_isr_cmpl)
1325+
return;
1326+
/*
1327+
* Segment 1 - Time from Last FCP command cmpl is handed
1328+
* off to NVME Layer to start of next command.
1329+
* Segment 2 - Time from Driver receives a IO cmd start
1330+
* from NVME Layer to WQ put is done on IO cmd.
1331+
* Segment 3 - Time from Driver WQ put is done on IO cmd
1332+
* to MSI-X ISR for IO cmpl.
1333+
* Segment 4 - Time from MSI-X ISR for IO cmpl to when
1334+
* cmpl is handled off to the NVME Layer.
1335+
*/
1336+
seg1 = lpfc_cmd->ts_cmd_start - lpfc_cmd->ts_last_cmd;
1337+
if (seg1 > 5000000) /* 5 ms - for sequential IOs only */
1338+
seg1 = 0;
1339+
1340+
/* Calculate times relative to start of IO */
1341+
seg2 = (lpfc_cmd->ts_cmd_wqput - lpfc_cmd->ts_cmd_start);
1342+
segsum = seg2;
1343+
seg3 = lpfc_cmd->ts_isr_cmpl - lpfc_cmd->ts_cmd_start;
1344+
if (segsum > seg3)
1345+
return;
1346+
seg3 -= segsum;
1347+
segsum += seg3;
1348+
1349+
seg4 = lpfc_cmd->ts_data_io - lpfc_cmd->ts_cmd_start;
1350+
if (segsum > seg4)
1351+
return;
1352+
seg4 -= segsum;
1353+
1354+
phba->ktime_data_samples++;
1355+
phba->ktime_seg1_total += seg1;
1356+
if (seg1 < phba->ktime_seg1_min)
1357+
phba->ktime_seg1_min = seg1;
1358+
else if (seg1 > phba->ktime_seg1_max)
1359+
phba->ktime_seg1_max = seg1;
1360+
phba->ktime_seg2_total += seg2;
1361+
if (seg2 < phba->ktime_seg2_min)
1362+
phba->ktime_seg2_min = seg2;
1363+
else if (seg2 > phba->ktime_seg2_max)
1364+
phba->ktime_seg2_max = seg2;
1365+
phba->ktime_seg3_total += seg3;
1366+
if (seg3 < phba->ktime_seg3_min)
1367+
phba->ktime_seg3_min = seg3;
1368+
else if (seg3 > phba->ktime_seg3_max)
1369+
phba->ktime_seg3_max = seg3;
1370+
phba->ktime_seg4_total += seg4;
1371+
if (seg4 < phba->ktime_seg4_min)
1372+
phba->ktime_seg4_min = seg4;
1373+
else if (seg4 > phba->ktime_seg4_max)
1374+
phba->ktime_seg4_max = seg4;
1375+
1376+
lpfc_cmd->ts_last_cmd = 0;
1377+
lpfc_cmd->ts_cmd_start = 0;
1378+
lpfc_cmd->ts_cmd_wqput = 0;
1379+
lpfc_cmd->ts_isr_cmpl = 0;
1380+
lpfc_cmd->ts_data_io = 0;
1381+
}
1382+
13031383
/**
1304-
* lpfc_debugfs_nvmektime_data - Dump target node list to a buffer
1384+
* lpfc_debugfs_ioktime_data - Dump target node list to a buffer
13051385
* @vport: The vport to gather target node info from.
13061386
* @buf: The buffer to dump log into.
13071387
* @size: The maximum amount of data to process.
@@ -1314,13 +1394,13 @@ lpfc_debugfs_scsistat_data(struct lpfc_vport *vport, char *buf, int size)
13141394
* not exceed @size.
13151395
**/
13161396
static int
1317-
lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size)
1397+
lpfc_debugfs_ioktime_data(struct lpfc_vport *vport, char *buf, int size)
13181398
{
13191399
struct lpfc_hba *phba = vport->phba;
13201400
int len = 0;
13211401

13221402
if (phba->nvmet_support == 0) {
1323-
/* NVME Initiator */
1403+
/* Initiator */
13241404
len += scnprintf(buf + len, PAGE_SIZE - len,
13251405
"ktime %s: Total Samples: %lld\n",
13261406
(phba->ktime_on ? "Enabled" : "Disabled"),
@@ -1330,8 +1410,8 @@ lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size)
13301410

13311411
len += scnprintf(
13321412
buf + len, PAGE_SIZE - len,
1333-
"Segment 1: Last NVME Cmd cmpl "
1334-
"done -to- Start of next NVME cnd (in driver)\n");
1413+
"Segment 1: Last Cmd cmpl "
1414+
"done -to- Start of next Cmd (in driver)\n");
13351415
len += scnprintf(
13361416
buf + len, PAGE_SIZE - len,
13371417
"avg:%08lld min:%08lld max %08lld\n",
@@ -1341,7 +1421,7 @@ lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size)
13411421
phba->ktime_seg1_max);
13421422
len += scnprintf(
13431423
buf + len, PAGE_SIZE - len,
1344-
"Segment 2: Driver start of NVME cmd "
1424+
"Segment 2: Driver start of Cmd "
13451425
"-to- Firmware WQ doorbell\n");
13461426
len += scnprintf(
13471427
buf + len, PAGE_SIZE - len,
@@ -1364,7 +1444,7 @@ lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size)
13641444
len += scnprintf(
13651445
buf + len, PAGE_SIZE - len,
13661446
"Segment 4: MSI-X ISR cmpl -to- "
1367-
"NVME cmpl done\n");
1447+
"Cmd cmpl done\n");
13681448
len += scnprintf(
13691449
buf + len, PAGE_SIZE - len,
13701450
"avg:%08lld min:%08lld max %08lld\n",
@@ -2727,7 +2807,7 @@ lpfc_debugfs_scsistat_write(struct file *file, const char __user *buf,
27272807
}
27282808

27292809
static int
2730-
lpfc_debugfs_nvmektime_open(struct inode *inode, struct file *file)
2810+
lpfc_debugfs_ioktime_open(struct inode *inode, struct file *file)
27312811
{
27322812
struct lpfc_vport *vport = inode->i_private;
27332813
struct lpfc_debug *debug;
@@ -2738,14 +2818,14 @@ lpfc_debugfs_nvmektime_open(struct inode *inode, struct file *file)
27382818
goto out;
27392819

27402820
/* Round to page boundary */
2741-
debug->buffer = kmalloc(LPFC_NVMEKTIME_SIZE, GFP_KERNEL);
2821+
debug->buffer = kmalloc(LPFC_IOKTIME_SIZE, GFP_KERNEL);
27422822
if (!debug->buffer) {
27432823
kfree(debug);
27442824
goto out;
27452825
}
27462826

2747-
debug->len = lpfc_debugfs_nvmektime_data(vport, debug->buffer,
2748-
LPFC_NVMEKTIME_SIZE);
2827+
debug->len = lpfc_debugfs_ioktime_data(vport, debug->buffer,
2828+
LPFC_IOKTIME_SIZE);
27492829

27502830
debug->i_private = inode->i_private;
27512831
file->private_data = debug;
@@ -2756,8 +2836,8 @@ lpfc_debugfs_nvmektime_open(struct inode *inode, struct file *file)
27562836
}
27572837

27582838
static ssize_t
2759-
lpfc_debugfs_nvmektime_write(struct file *file, const char __user *buf,
2760-
size_t nbytes, loff_t *ppos)
2839+
lpfc_debugfs_ioktime_write(struct file *file, const char __user *buf,
2840+
size_t nbytes, loff_t *ppos)
27612841
{
27622842
struct lpfc_debug *debug = file->private_data;
27632843
struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
@@ -5467,13 +5547,13 @@ static const struct file_operations lpfc_debugfs_op_scsistat = {
54675547
.release = lpfc_debugfs_release,
54685548
};
54695549

5470-
#undef lpfc_debugfs_op_nvmektime
5471-
static const struct file_operations lpfc_debugfs_op_nvmektime = {
5550+
#undef lpfc_debugfs_op_ioktime
5551+
static const struct file_operations lpfc_debugfs_op_ioktime = {
54725552
.owner = THIS_MODULE,
5473-
.open = lpfc_debugfs_nvmektime_open,
5553+
.open = lpfc_debugfs_ioktime_open,
54745554
.llseek = lpfc_debugfs_lseek,
54755555
.read = lpfc_debugfs_read,
5476-
.write = lpfc_debugfs_nvmektime_write,
5556+
.write = lpfc_debugfs_ioktime_write,
54775557
.release = lpfc_debugfs_release,
54785558
};
54795559

@@ -6111,11 +6191,16 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
61116191
goto debug_failed;
61126192
}
61136193

6114-
snprintf(name, sizeof(name), "nvmektime");
6115-
vport->debug_nvmektime =
6194+
snprintf(name, sizeof(name), "ioktime");
6195+
vport->debug_ioktime =
61166196
debugfs_create_file(name, 0644,
61176197
vport->vport_debugfs_root,
6118-
vport, &lpfc_debugfs_op_nvmektime);
6198+
vport, &lpfc_debugfs_op_ioktime);
6199+
if (!vport->debug_ioktime) {
6200+
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6201+
"0815 Cannot create debugfs ioktime\n");
6202+
goto debug_failed;
6203+
}
61196204

61206205
snprintf(name, sizeof(name), "hdwqstat");
61216206
vport->debug_hdwqstat =
@@ -6252,8 +6337,8 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
62526337
debugfs_remove(vport->debug_scsistat); /* scsistat */
62536338
vport->debug_scsistat = NULL;
62546339

6255-
debugfs_remove(vport->debug_nvmektime); /* nvmektime */
6256-
vport->debug_nvmektime = NULL;
6340+
debugfs_remove(vport->debug_ioktime); /* ioktime */
6341+
vport->debug_ioktime = NULL;
62576342

62586343
debugfs_remove(vport->debug_hdwqstat); /* hdwqstat */
62596344
vport->debug_hdwqstat = NULL;

drivers/scsi/lpfc/lpfc_debugfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646

4747
/* nvmestat output buffer size */
4848
#define LPFC_NVMESTAT_SIZE 8192
49-
#define LPFC_NVMEKTIME_SIZE 8192
49+
#define LPFC_IOKTIME_SIZE 8192
5050
#define LPFC_NVMEIO_TRC_SIZE 8192
5151

5252
/* scsistat output buffer size */

drivers/scsi/lpfc/lpfc_nvme.c

Lines changed: 3 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -899,88 +899,6 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
899899
sgl->sge_len = cpu_to_le32(nCmd->rsplen);
900900
}
901901

902-
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
903-
static void
904-
lpfc_nvme_ktime(struct lpfc_hba *phba,
905-
struct lpfc_io_buf *lpfc_ncmd)
906-
{
907-
uint64_t seg1, seg2, seg3, seg4;
908-
uint64_t segsum;
909-
910-
if (!lpfc_ncmd->ts_last_cmd ||
911-
!lpfc_ncmd->ts_cmd_start ||
912-
!lpfc_ncmd->ts_cmd_wqput ||
913-
!lpfc_ncmd->ts_isr_cmpl ||
914-
!lpfc_ncmd->ts_data_nvme)
915-
return;
916-
917-
if (lpfc_ncmd->ts_data_nvme < lpfc_ncmd->ts_cmd_start)
918-
return;
919-
if (lpfc_ncmd->ts_cmd_start < lpfc_ncmd->ts_last_cmd)
920-
return;
921-
if (lpfc_ncmd->ts_cmd_wqput < lpfc_ncmd->ts_cmd_start)
922-
return;
923-
if (lpfc_ncmd->ts_isr_cmpl < lpfc_ncmd->ts_cmd_wqput)
924-
return;
925-
if (lpfc_ncmd->ts_data_nvme < lpfc_ncmd->ts_isr_cmpl)
926-
return;
927-
/*
928-
* Segment 1 - Time from Last FCP command cmpl is handed
929-
* off to NVME Layer to start of next command.
930-
* Segment 2 - Time from Driver receives a IO cmd start
931-
* from NVME Layer to WQ put is done on IO cmd.
932-
* Segment 3 - Time from Driver WQ put is done on IO cmd
933-
* to MSI-X ISR for IO cmpl.
934-
* Segment 4 - Time from MSI-X ISR for IO cmpl to when
935-
* cmpl is handled off to the NVME Layer.
936-
*/
937-
seg1 = lpfc_ncmd->ts_cmd_start - lpfc_ncmd->ts_last_cmd;
938-
if (seg1 > 5000000) /* 5 ms - for sequential IOs only */
939-
seg1 = 0;
940-
941-
/* Calculate times relative to start of IO */
942-
seg2 = (lpfc_ncmd->ts_cmd_wqput - lpfc_ncmd->ts_cmd_start);
943-
segsum = seg2;
944-
seg3 = lpfc_ncmd->ts_isr_cmpl - lpfc_ncmd->ts_cmd_start;
945-
if (segsum > seg3)
946-
return;
947-
seg3 -= segsum;
948-
segsum += seg3;
949-
950-
seg4 = lpfc_ncmd->ts_data_nvme - lpfc_ncmd->ts_cmd_start;
951-
if (segsum > seg4)
952-
return;
953-
seg4 -= segsum;
954-
955-
phba->ktime_data_samples++;
956-
phba->ktime_seg1_total += seg1;
957-
if (seg1 < phba->ktime_seg1_min)
958-
phba->ktime_seg1_min = seg1;
959-
else if (seg1 > phba->ktime_seg1_max)
960-
phba->ktime_seg1_max = seg1;
961-
phba->ktime_seg2_total += seg2;
962-
if (seg2 < phba->ktime_seg2_min)
963-
phba->ktime_seg2_min = seg2;
964-
else if (seg2 > phba->ktime_seg2_max)
965-
phba->ktime_seg2_max = seg2;
966-
phba->ktime_seg3_total += seg3;
967-
if (seg3 < phba->ktime_seg3_min)
968-
phba->ktime_seg3_min = seg3;
969-
else if (seg3 > phba->ktime_seg3_max)
970-
phba->ktime_seg3_max = seg3;
971-
phba->ktime_seg4_total += seg4;
972-
if (seg4 < phba->ktime_seg4_min)
973-
phba->ktime_seg4_min = seg4;
974-
else if (seg4 > phba->ktime_seg4_max)
975-
phba->ktime_seg4_max = seg4;
976-
977-
lpfc_ncmd->ts_last_cmd = 0;
978-
lpfc_ncmd->ts_cmd_start = 0;
979-
lpfc_ncmd->ts_cmd_wqput = 0;
980-
lpfc_ncmd->ts_isr_cmpl = 0;
981-
lpfc_ncmd->ts_data_nvme = 0;
982-
}
983-
#endif
984902

985903
/**
986904
* lpfc_nvme_io_cmd_wqe_cmpl - Complete an NVME-over-FCP IO
@@ -1183,9 +1101,9 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,
11831101
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
11841102
if (lpfc_ncmd->ts_cmd_start) {
11851103
lpfc_ncmd->ts_isr_cmpl = pwqeIn->isr_timestamp;
1186-
lpfc_ncmd->ts_data_nvme = ktime_get_ns();
1187-
phba->ktime_last_cmd = lpfc_ncmd->ts_data_nvme;
1188-
lpfc_nvme_ktime(phba, lpfc_ncmd);
1104+
lpfc_ncmd->ts_data_io = ktime_get_ns();
1105+
phba->ktime_last_cmd = lpfc_ncmd->ts_data_io;
1106+
lpfc_io_ktime(phba, lpfc_ncmd);
11891107
}
11901108
if (unlikely(phba->hdwqstat_on & LPFC_CHECK_NVME_IO)) {
11911109
cpu = raw_smp_processor_id();

drivers/scsi/lpfc/lpfc_scsi.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4025,6 +4025,14 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
40254025
lpfc_cmd->pCmd = NULL;
40264026
spin_unlock(&lpfc_cmd->buf_lock);
40274027

4028+
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
4029+
if (lpfc_cmd->ts_cmd_start) {
4030+
lpfc_cmd->ts_isr_cmpl = pIocbIn->isr_timestamp;
4031+
lpfc_cmd->ts_data_io = ktime_get_ns();
4032+
phba->ktime_last_cmd = lpfc_cmd->ts_data_io;
4033+
lpfc_io_ktime(phba, lpfc_cmd);
4034+
}
4035+
#endif
40284036
/* The sdev is not guaranteed to be valid post scsi_done upcall. */
40294037
cmd->scsi_done(cmd);
40304038

@@ -4497,6 +4505,12 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
44974505
struct lpfc_io_buf *lpfc_cmd;
44984506
struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
44994507
int err, idx;
4508+
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
4509+
uint64_t start = 0L;
4510+
4511+
if (phba->ktime_on)
4512+
start = ktime_get_ns();
4513+
#endif
45004514

45014515
rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
45024516

@@ -4622,6 +4636,15 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
46224636
#endif
46234637
err = lpfc_sli_issue_iocb(phba, LPFC_FCP_RING,
46244638
&lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB);
4639+
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
4640+
if (start) {
4641+
lpfc_cmd->ts_cmd_start = start;
4642+
lpfc_cmd->ts_last_cmd = phba->ktime_last_cmd;
4643+
lpfc_cmd->ts_cmd_wqput = ktime_get_ns();
4644+
} else {
4645+
lpfc_cmd->ts_cmd_start = 0;
4646+
}
4647+
#endif
46254648
if (err) {
46264649
lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
46274650
"3376 FCP could not issue IOCB err %x"

0 commit comments

Comments
 (0)