aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <jsmart2021@gmail.com>2017-02-12 16:52:33 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2017-02-22 18:41:43 -0500
commitbd2cdd5e400f5914bc30d5cfb0a0185cf51e4424 (patch)
tree11914a16eaf683403cef6ee03db5f16e20753340
parent01649561a8b4b77247bd234f240d737367bb8a52 (diff)
scsi: lpfc: NVME Initiator: Add debugfs support
NVME Initiator: Add debugfs support Adds debugfs snippets to cover the new NVME initiator functionality Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/lpfc/lpfc.h55
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h6
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c27
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c1160
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.h21
-rw-r--r--drivers/scsi/lpfc/lpfc_nvme.c143
-rw-r--r--drivers/scsi/lpfc/lpfc_nvme.h7
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c5
8 files changed, 1300 insertions, 124 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 9ad63a47425b..fdb314b3282d 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -458,6 +458,9 @@ struct lpfc_vport {
458#ifdef CONFIG_SCSI_LPFC_DEBUG_FS 458#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
459 struct dentry *debug_disc_trc; 459 struct dentry *debug_disc_trc;
460 struct dentry *debug_nodelist; 460 struct dentry *debug_nodelist;
461 struct dentry *debug_nvmestat;
462 struct dentry *debug_nvmektime;
463 struct dentry *debug_cpucheck;
461 struct dentry *vport_debugfs_root; 464 struct dentry *vport_debugfs_root;
462 struct lpfc_debugfs_trc *disc_trc; 465 struct lpfc_debugfs_trc *disc_trc;
463 atomic_t disc_trc_cnt; 466 atomic_t disc_trc_cnt;
@@ -984,6 +987,12 @@ struct lpfc_hba {
984 struct dentry *debug_readApp; /* inject read app_tag errors */ 987 struct dentry *debug_readApp; /* inject read app_tag errors */
985 struct dentry *debug_readRef; /* inject read ref_tag errors */ 988 struct dentry *debug_readRef; /* inject read ref_tag errors */
986 989
990 struct dentry *debug_nvmeio_trc;
991 struct lpfc_debugfs_nvmeio_trc *nvmeio_trc;
992 atomic_t nvmeio_trc_cnt;
993 uint32_t nvmeio_trc_size;
994 uint32_t nvmeio_trc_output_idx;
995
987 /* T10 DIF error injection */ 996 /* T10 DIF error injection */
988 uint32_t lpfc_injerr_wgrd_cnt; 997 uint32_t lpfc_injerr_wgrd_cnt;
989 uint32_t lpfc_injerr_wapp_cnt; 998 uint32_t lpfc_injerr_wapp_cnt;
@@ -1011,6 +1020,7 @@ struct lpfc_hba {
1011 struct dentry *idiag_ext_acc; 1020 struct dentry *idiag_ext_acc;
1012 uint8_t lpfc_idiag_last_eq; 1021 uint8_t lpfc_idiag_last_eq;
1013#endif 1022#endif
1023 uint16_t nvmeio_trc_on;
1014 1024
1015 /* Used for deferred freeing of ELS data buffers */ 1025 /* Used for deferred freeing of ELS data buffers */
1016 struct list_head elsbuf; 1026 struct list_head elsbuf;
@@ -1083,6 +1093,51 @@ struct lpfc_hba {
1083#define LPFC_TRANSGRESSION_LOW_RXPOWER 0x4000 1093#define LPFC_TRANSGRESSION_LOW_RXPOWER 0x4000
1084 uint16_t sfp_alarm; 1094 uint16_t sfp_alarm;
1085 uint16_t sfp_warning; 1095 uint16_t sfp_warning;
1096
1097#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1098#define LPFC_CHECK_CPU_CNT 32
1099 uint32_t cpucheck_rcv_io[LPFC_CHECK_CPU_CNT];
1100 uint32_t cpucheck_xmt_io[LPFC_CHECK_CPU_CNT];
1101 uint32_t cpucheck_cmpl_io[LPFC_CHECK_CPU_CNT];
1102 uint32_t cpucheck_ccmpl_io[LPFC_CHECK_CPU_CNT];
1103 uint16_t cpucheck_on;
1104#define LPFC_CHECK_OFF 0
1105#define LPFC_CHECK_NVME_IO 1
1106 uint16_t ktime_on;
1107 uint64_t ktime_data_samples;
1108 uint64_t ktime_status_samples;
1109 uint64_t ktime_last_cmd;
1110 uint64_t ktime_seg1_total;
1111 uint64_t ktime_seg1_min;
1112 uint64_t ktime_seg1_max;
1113 uint64_t ktime_seg2_total;
1114 uint64_t ktime_seg2_min;
1115 uint64_t ktime_seg2_max;
1116 uint64_t ktime_seg3_total;
1117 uint64_t ktime_seg3_min;
1118 uint64_t ktime_seg3_max;
1119 uint64_t ktime_seg4_total;
1120 uint64_t ktime_seg4_min;
1121 uint64_t ktime_seg4_max;
1122 uint64_t ktime_seg5_total;
1123 uint64_t ktime_seg5_min;
1124 uint64_t ktime_seg5_max;
1125 uint64_t ktime_seg6_total;
1126 uint64_t ktime_seg6_min;
1127 uint64_t ktime_seg6_max;
1128 uint64_t ktime_seg7_total;
1129 uint64_t ktime_seg7_min;
1130 uint64_t ktime_seg7_max;
1131 uint64_t ktime_seg8_total;
1132 uint64_t ktime_seg8_min;
1133 uint64_t ktime_seg8_max;
1134 uint64_t ktime_seg9_total;
1135 uint64_t ktime_seg9_min;
1136 uint64_t ktime_seg9_max;
1137 uint64_t ktime_seg10_total;
1138 uint64_t ktime_seg10_min;
1139 uint64_t ktime_seg10_max;
1140#endif
1086}; 1141};
1087 1142
1088static inline struct Scsi_Host * 1143static inline struct Scsi_Host *
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index a9c8a0a41b16..4a0db3895993 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -393,9 +393,11 @@ void lpfc_host_attrib_init(struct Scsi_Host *);
393extern void lpfc_debugfs_initialize(struct lpfc_vport *); 393extern void lpfc_debugfs_initialize(struct lpfc_vport *);
394extern void lpfc_debugfs_terminate(struct lpfc_vport *); 394extern void lpfc_debugfs_terminate(struct lpfc_vport *);
395extern void lpfc_debugfs_disc_trc(struct lpfc_vport *, int, char *, uint32_t, 395extern void lpfc_debugfs_disc_trc(struct lpfc_vport *, int, char *, uint32_t,
396 uint32_t, uint32_t); 396 uint32_t, uint32_t);
397extern void lpfc_debugfs_slow_ring_trc(struct lpfc_hba *, char *, uint32_t, 397extern void lpfc_debugfs_slow_ring_trc(struct lpfc_hba *, char *, uint32_t,
398 uint32_t, uint32_t); 398 uint32_t, uint32_t);
399extern void lpfc_debugfs_nvme_trc(struct lpfc_hba *phba, char *fmt,
400 uint16_t data1, uint16_t data2, uint32_t data3);
399extern struct lpfc_hbq_init *lpfc_hbq_defs[]; 401extern struct lpfc_hbq_init *lpfc_hbq_defs[];
400 402
401/* SLI4 if_type 2 externs. */ 403/* SLI4 if_type 2 externs. */
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 8cfeffe312e0..2c051369857a 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -465,6 +465,10 @@ lpfc_prep_node_fc4type(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type)
465 ndlp = lpfc_setup_disc_node(vport, Did); 465 ndlp = lpfc_setup_disc_node(vport, Did);
466 466
467 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { 467 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
468 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
469 "Parse GID_FTrsp: did:x%x flg:x%x x%x",
470 Did, ndlp->nlp_flag, vport->fc_flag);
471
468 /* By default, the driver expects to support FCP FC4 */ 472 /* By default, the driver expects to support FCP FC4 */
469 if (fc4_type == FC_TYPE_FCP) 473 if (fc4_type == FC_TYPE_FCP)
470 ndlp->nlp_fc4_type |= NLP_FC4_FCP; 474 ndlp->nlp_fc4_type |= NLP_FC4_FCP;
@@ -478,16 +482,24 @@ lpfc_prep_node_fc4type(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type)
478 ndlp->nlp_flag, ndlp->nlp_fc4_type, 482 ndlp->nlp_flag, ndlp->nlp_fc4_type,
479 vport->fc_flag, 483 vport->fc_flag,
480 vport->fc_rscn_id_cnt); 484 vport->fc_rscn_id_cnt);
481 } else 485 } else {
486 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
487 "Skip1 GID_FTrsp: did:x%x flg:x%x cnt:%d",
488 Did, vport->fc_flag, vport->fc_rscn_id_cnt);
489
482 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 490 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
483 "0239 Skip x%06x NameServer Rsp " 491 "0239 Skip x%06x NameServer Rsp "
484 "Data: x%x x%x\n", Did, 492 "Data: x%x x%x\n", Did,
485 vport->fc_flag, 493 vport->fc_flag,
486 vport->fc_rscn_id_cnt); 494 vport->fc_rscn_id_cnt);
487 495 }
488 } else { 496 } else {
489 if (!(vport->fc_flag & FC_RSCN_MODE) || 497 if (!(vport->fc_flag & FC_RSCN_MODE) ||
490 lpfc_rscn_payload_check(vport, Did)) { 498 lpfc_rscn_payload_check(vport, Did)) {
499 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
500 "Query GID_FTrsp: did:x%x flg:x%x cnt:%d",
501 Did, vport->fc_flag, vport->fc_rscn_id_cnt);
502
491 /* 503 /*
492 * This NPortID was previously a FCP target, 504 * This NPortID was previously a FCP target,
493 * Don't even bother to send GFF_ID. 505 * Don't even bother to send GFF_ID.
@@ -509,12 +521,17 @@ lpfc_prep_node_fc4type(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type)
509 else 521 else
510 lpfc_setup_disc_node(vport, Did); 522 lpfc_setup_disc_node(vport, Did);
511 } 523 }
512 } else 524 } else {
525 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
526 "Skip2 GID_FTrsp: did:x%x flg:x%x cnt:%d",
527 Did, vport->fc_flag, vport->fc_rscn_id_cnt);
528
513 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 529 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
514 "0245 Skip x%06x NameServer Rsp " 530 "0245 Skip x%06x NameServer Rsp "
515 "Data: x%x x%x\n", Did, 531 "Data: x%x x%x\n", Did,
516 vport->fc_flag, 532 vport->fc_flag,
517 vport->fc_rscn_id_cnt); 533 vport->fc_rscn_id_cnt);
534 }
518 } 535 }
519} 536}
520 537
@@ -892,6 +909,10 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
892 did = ((struct lpfc_sli_ct_request *)inp->virt)->un.gft.PortId; 909 did = ((struct lpfc_sli_ct_request *)inp->virt)->un.gft.PortId;
893 did = be32_to_cpu(did); 910 did = be32_to_cpu(did);
894 911
912 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
913 "GFT_ID cmpl: status:x%x/x%x did:x%x",
914 irsp->ulpStatus, irsp->un.ulpWord[4], did);
915
895 if (irsp->ulpStatus == IOSTAT_SUCCESS) { 916 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
896 /* Good status, continue checking */ 917 /* Good status, continue checking */
897 CTrsp = (struct lpfc_sli_ct_request *)outp->virt; 918 CTrsp = (struct lpfc_sli_ct_request *)outp->virt;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index d9bbebe8eb37..3fcba26623eb 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -34,6 +34,9 @@
34#include <scsi/scsi_device.h> 34#include <scsi/scsi_device.h>
35#include <scsi/scsi_host.h> 35#include <scsi/scsi_host.h>
36#include <scsi/scsi_transport_fc.h> 36#include <scsi/scsi_transport_fc.h>
37#include <scsi/fc/fc_fs.h>
38
39#include <linux/nvme-fc-driver.h>
37 40
38#include "lpfc_hw4.h" 41#include "lpfc_hw4.h"
39#include "lpfc_hw.h" 42#include "lpfc_hw.h"
@@ -41,8 +44,9 @@
41#include "lpfc_sli4.h" 44#include "lpfc_sli4.h"
42#include "lpfc_nl.h" 45#include "lpfc_nl.h"
43#include "lpfc_disc.h" 46#include "lpfc_disc.h"
44#include "lpfc_scsi.h"
45#include "lpfc.h" 47#include "lpfc.h"
48#include "lpfc_scsi.h"
49#include "lpfc_nvme.h"
46#include "lpfc_logmsg.h" 50#include "lpfc_logmsg.h"
47#include "lpfc_crtn.h" 51#include "lpfc_crtn.h"
48#include "lpfc_vport.h" 52#include "lpfc_vport.h"
@@ -99,6 +103,12 @@ module_param(lpfc_debugfs_max_slow_ring_trc, int, S_IRUGO);
99MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc, 103MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
100 "Set debugfs slow ring trace depth"); 104 "Set debugfs slow ring trace depth");
101 105
106/* This MUST be a power of 2 */
107static int lpfc_debugfs_max_nvmeio_trc;
108module_param(lpfc_debugfs_max_nvmeio_trc, int, 0444);
109MODULE_PARM_DESC(lpfc_debugfs_max_nvmeio_trc,
110 "Set debugfs NVME IO trace depth");
111
102static int lpfc_debugfs_mask_disc_trc; 112static int lpfc_debugfs_mask_disc_trc;
103module_param(lpfc_debugfs_mask_disc_trc, int, S_IRUGO); 113module_param(lpfc_debugfs_mask_disc_trc, int, S_IRUGO);
104MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc, 114MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
@@ -535,6 +545,10 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
535 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 545 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
536 struct lpfc_nodelist *ndlp; 546 struct lpfc_nodelist *ndlp;
537 unsigned char *statep; 547 unsigned char *statep;
548 struct nvme_fc_local_port *localport;
549 struct lpfc_nvme_lport *lport;
550 struct lpfc_nvme_rport *rport;
551 struct nvme_fc_remote_port *nrport;
538 552
539 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE); 553 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
540 554
@@ -612,6 +626,358 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
612 } 626 }
613 spin_unlock_irq(shost->host_lock); 627 spin_unlock_irq(shost->host_lock);
614 628
629 len += snprintf(buf + len, size - len,
630 "\nNVME Lport/Rport Entries ...\n");
631
632 localport = vport->localport;
633 if (!localport)
634 goto out_exit;
635
636 spin_lock_irq(shost->host_lock);
637 lport = (struct lpfc_nvme_lport *)localport->private;
638
639 /* Port state is only one of two values for now. */
640 if (localport->port_id)
641 statep = "ONLINE";
642 else
643 statep = "UNKNOWN ";
644
645 len += snprintf(buf + len, size - len,
646 "Lport DID x%06x PortState %s\n",
647 localport->port_id, statep);
648
649 len += snprintf(buf + len, size - len, "\tRport List:\n");
650 list_for_each_entry(rport, &lport->rport_list, list) {
651 /* local short-hand pointer. */
652 nrport = rport->remoteport;
653
654 /* Port state is only one of two values for now. */
655 switch (nrport->port_state) {
656 case FC_OBJSTATE_ONLINE:
657 statep = "ONLINE";
658 break;
659 case FC_OBJSTATE_UNKNOWN:
660 statep = "UNKNOWN ";
661 break;
662 default:
663 statep = "UNSUPPORTED";
664 break;
665 }
666
667 /* Tab in to show lport ownership. */
668 len += snprintf(buf + len, size - len,
669 "\t%s Port ID:x%06x ",
670 statep, nrport->port_id);
671 len += snprintf(buf + len, size - len, "WWPN x%llx ",
672 nrport->port_name);
673 len += snprintf(buf + len, size - len, "WWNN x%llx ",
674 nrport->node_name);
675 switch (nrport->port_role) {
676 case FC_PORT_ROLE_NVME_INITIATOR:
677 len += snprintf(buf + len, size - len,
678 "NVME INITIATOR ");
679 break;
680 case FC_PORT_ROLE_NVME_TARGET:
681 len += snprintf(buf + len, size - len,
682 "NVME TARGET ");
683 break;
684 case FC_PORT_ROLE_NVME_DISCOVERY:
685 len += snprintf(buf + len, size - len,
686 "NVME DISCOVERY ");
687 break;
688 default:
689 len += snprintf(buf + len, size - len,
690 "UNKNOWN ROLE x%x",
691 nrport->port_role);
692 break;
693 }
694
695 /* Terminate the string. */
696 len += snprintf(buf + len, size - len, "\n");
697 }
698
699 spin_unlock_irq(shost->host_lock);
700 out_exit:
701 return len;
702}
703
704/**
705 * lpfc_debugfs_nvmestat_data - Dump target node list to a buffer
706 * @vport: The vport to gather target node info from.
707 * @buf: The buffer to dump log into.
708 * @size: The maximum amount of data to process.
709 *
710 * Description:
711 * This routine dumps the NVME statistics associated with @vport
712 *
713 * Return Value:
714 * This routine returns the amount of bytes that were dumped into @buf and will
715 * not exceed @size.
716 **/
717static int
718lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size)
719{
720 struct lpfc_hba *phba = vport->phba;
721 int len = 0;
722
723 if (phba->nvmet_support == 0) {
724 if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME))
725 return len;
726
727 len += snprintf(buf + len, size - len,
728 "\nNVME Lport Statistics\n");
729
730 len += snprintf(buf + len, size - len,
731 "LS: Xmt %016llx Cmpl %016llx\n",
732 phba->fc4NvmeLsRequests,
733 phba->fc4NvmeLsCmpls);
734
735 len += snprintf(buf + len, size - len,
736 "FCP: Rd %016llx Wr %016llx IO %016llx\n",
737 phba->fc4NvmeInputRequests,
738 phba->fc4NvmeOutputRequests,
739 phba->fc4NvmeControlRequests);
740
741 len += snprintf(buf + len, size - len,
742 " Cmpl %016llx\n", phba->fc4NvmeIoCmpls);
743 }
744
745 return len;
746}
747
748
749/**
750 * lpfc_debugfs_nvmektime_data - Dump target node list to a buffer
751 * @vport: The vport to gather target node info from.
752 * @buf: The buffer to dump log into.
753 * @size: The maximum amount of data to process.
754 *
755 * Description:
756 * This routine dumps the NVME statistics associated with @vport
757 *
758 * Return Value:
759 * This routine returns the amount of bytes that were dumped into @buf and will
760 * not exceed @size.
761 **/
762static int
763lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size)
764{
765 struct lpfc_hba *phba = vport->phba;
766 int len = 0;
767
768 if (phba->nvmet_support == 0) {
769 /* NVME Initiator */
770 len += snprintf(buf + len, PAGE_SIZE - len,
771 "ktime %s: Total Samples: %lld\n",
772 (phba->ktime_on ? "Enabled" : "Disabled"),
773 phba->ktime_data_samples);
774 if (phba->ktime_data_samples == 0)
775 return len;
776
777 len += snprintf(
778 buf + len, PAGE_SIZE - len,
779 "Segment 1: Last NVME Cmd cmpl "
780 "done -to- Start of next NVME cnd (in driver)\n");
781 len += snprintf(
782 buf + len, PAGE_SIZE - len,
783 "avg:%08lld min:%08lld max %08lld\n",
784 phba->ktime_seg1_total /
785 phba->ktime_data_samples,
786 phba->ktime_seg1_min,
787 phba->ktime_seg1_max);
788 len += snprintf(
789 buf + len, PAGE_SIZE - len,
790 "Segment 2: Driver start of NVME cmd "
791 "-to- Firmware WQ doorbell\n");
792 len += snprintf(
793 buf + len, PAGE_SIZE - len,
794 "avg:%08lld min:%08lld max %08lld\n",
795 phba->ktime_seg2_total /
796 phba->ktime_data_samples,
797 phba->ktime_seg2_min,
798 phba->ktime_seg2_max);
799 len += snprintf(
800 buf + len, PAGE_SIZE - len,
801 "Segment 3: Firmware WQ doorbell -to- "
802 "MSI-X ISR cmpl\n");
803 len += snprintf(
804 buf + len, PAGE_SIZE - len,
805 "avg:%08lld min:%08lld max %08lld\n",
806 phba->ktime_seg3_total /
807 phba->ktime_data_samples,
808 phba->ktime_seg3_min,
809 phba->ktime_seg3_max);
810 len += snprintf(
811 buf + len, PAGE_SIZE - len,
812 "Segment 4: MSI-X ISR cmpl -to- "
813 "NVME cmpl done\n");
814 len += snprintf(
815 buf + len, PAGE_SIZE - len,
816 "avg:%08lld min:%08lld max %08lld\n",
817 phba->ktime_seg4_total /
818 phba->ktime_data_samples,
819 phba->ktime_seg4_min,
820 phba->ktime_seg4_max);
821 len += snprintf(
822 buf + len, PAGE_SIZE - len,
823 "Total IO avg time: %08lld\n",
824 ((phba->ktime_seg1_total +
825 phba->ktime_seg2_total +
826 phba->ktime_seg3_total +
827 phba->ktime_seg4_total) /
828 phba->ktime_data_samples));
829 return len;
830 }
831
832 return len;
833}
834
835/**
836 * lpfc_debugfs_nvmeio_trc_data - Dump NVME IO trace list to a buffer
837 * @phba: The phba to gather target node info from.
838 * @buf: The buffer to dump log into.
839 * @size: The maximum amount of data to process.
840 *
841 * Description:
842 * This routine dumps the NVME IO trace associated with @phba
843 *
844 * Return Value:
845 * This routine returns the amount of bytes that were dumped into @buf and will
846 * not exceed @size.
847 **/
848static int
849lpfc_debugfs_nvmeio_trc_data(struct lpfc_hba *phba, char *buf, int size)
850{
851 struct lpfc_debugfs_nvmeio_trc *dtp;
852 int i, state, index, skip;
853 int len = 0;
854
855 state = phba->nvmeio_trc_on;
856
857 index = (atomic_read(&phba->nvmeio_trc_cnt) + 1) &
858 (phba->nvmeio_trc_size - 1);
859 skip = phba->nvmeio_trc_output_idx;
860
861 len += snprintf(buf + len, size - len,
862 "%s IO Trace %s: next_idx %d skip %d size %d\n",
863 (phba->nvmet_support ? "NVME" : "NVMET"),
864 (state ? "Enabled" : "Disabled"),
865 index, skip, phba->nvmeio_trc_size);
866
867 if (!phba->nvmeio_trc || state)
868 return len;
869
870 /* trace MUST bhe off to continue */
871
872 for (i = index; i < phba->nvmeio_trc_size; i++) {
873 if (skip) {
874 skip--;
875 continue;
876 }
877 dtp = phba->nvmeio_trc + i;
878 phba->nvmeio_trc_output_idx++;
879
880 if (!dtp->fmt)
881 continue;
882
883 len += snprintf(buf + len, size - len, dtp->fmt,
884 dtp->data1, dtp->data2, dtp->data3);
885
886 if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) {
887 phba->nvmeio_trc_output_idx = 0;
888 len += snprintf(buf + len, size - len,
889 "Trace Complete\n");
890 goto out;
891 }
892
893 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) {
894 len += snprintf(buf + len, size - len,
895 "Trace Continue (%d of %d)\n",
896 phba->nvmeio_trc_output_idx,
897 phba->nvmeio_trc_size);
898 goto out;
899 }
900 }
901 for (i = 0; i < index; i++) {
902 if (skip) {
903 skip--;
904 continue;
905 }
906 dtp = phba->nvmeio_trc + i;
907 phba->nvmeio_trc_output_idx++;
908
909 if (!dtp->fmt)
910 continue;
911
912 len += snprintf(buf + len, size - len, dtp->fmt,
913 dtp->data1, dtp->data2, dtp->data3);
914
915 if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) {
916 phba->nvmeio_trc_output_idx = 0;
917 len += snprintf(buf + len, size - len,
918 "Trace Complete\n");
919 goto out;
920 }
921
922 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) {
923 len += snprintf(buf + len, size - len,
924 "Trace Continue (%d of %d)\n",
925 phba->nvmeio_trc_output_idx,
926 phba->nvmeio_trc_size);
927 goto out;
928 }
929 }
930
931 len += snprintf(buf + len, size - len,
932 "Trace Done\n");
933out:
934 return len;
935}
936
937/**
938 * lpfc_debugfs_cpucheck_data - Dump target node list to a buffer
939 * @vport: The vport to gather target node info from.
940 * @buf: The buffer to dump log into.
941 * @size: The maximum amount of data to process.
942 *
943 * Description:
944 * This routine dumps the NVME statistics associated with @vport
945 *
946 * Return Value:
947 * This routine returns the amount of bytes that were dumped into @buf and will
948 * not exceed @size.
949 **/
950static int
951lpfc_debugfs_cpucheck_data(struct lpfc_vport *vport, char *buf, int size)
952{
953 struct lpfc_hba *phba = vport->phba;
954 int i;
955 int len = 0;
956 uint32_t tot_xmt = 0;
957 uint32_t tot_cmpl = 0;
958
959 if (phba->nvmet_support == 0) {
960 /* NVME Initiator */
961 len += snprintf(buf + len, PAGE_SIZE - len,
962 "CPUcheck %s\n",
963 (phba->cpucheck_on & LPFC_CHECK_NVME_IO ?
964 "Enabled" : "Disabled"));
965 for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) {
966 if (i >= LPFC_CHECK_CPU_CNT)
967 break;
968 len += snprintf(buf + len, PAGE_SIZE - len,
969 "%02d: xmit x%08x cmpl x%08x\n",
970 i, phba->cpucheck_xmt_io[i],
971 phba->cpucheck_cmpl_io[i]);
972 tot_xmt += phba->cpucheck_xmt_io[i];
973 tot_cmpl += phba->cpucheck_cmpl_io[i];
974 }
975 len += snprintf(buf + len, PAGE_SIZE - len,
976 "tot:xmit x%08x cmpl x%08x\n",
977 tot_xmt, tot_cmpl);
978 return len;
979 }
980
615 return len; 981 return len;
616} 982}
617 983
@@ -699,6 +1065,40 @@ lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
699 return; 1065 return;
700} 1066}
701 1067
1068/**
1069 * lpfc_debugfs_nvme_trc - Store NVME/NVMET trace log
1070 * @phba: The phba to associate this trace string with for retrieval.
1071 * @fmt: Format string to be displayed when dumping the log.
1072 * @data1: 1st data parameter to be applied to @fmt.
1073 * @data2: 2nd data parameter to be applied to @fmt.
1074 * @data3: 3rd data parameter to be applied to @fmt.
1075 *
1076 * Description:
1077 * This routine is used by the driver code to add a debugfs log entry to the
1078 * nvme trace buffer associated with @phba. @fmt, @data1, @data2, and
1079 * @data3 are used like printf when displaying the log.
1080 **/
1081inline void
1082lpfc_debugfs_nvme_trc(struct lpfc_hba *phba, char *fmt,
1083 uint16_t data1, uint16_t data2, uint32_t data3)
1084{
1085#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1086 struct lpfc_debugfs_nvmeio_trc *dtp;
1087 int index;
1088
1089 if (!phba->nvmeio_trc_on || !phba->nvmeio_trc)
1090 return;
1091
1092 index = atomic_inc_return(&phba->nvmeio_trc_cnt) &
1093 (phba->nvmeio_trc_size - 1);
1094 dtp = phba->nvmeio_trc + index;
1095 dtp->fmt = fmt;
1096 dtp->data1 = data1;
1097 dtp->data2 = data2;
1098 dtp->data3 = data3;
1099#endif
1100}
1101
702#ifdef CONFIG_SCSI_LPFC_DEBUG_FS 1102#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
703/** 1103/**
704 * lpfc_debugfs_disc_trc_open - Open the discovery trace log 1104 * lpfc_debugfs_disc_trc_open - Open the discovery trace log
@@ -1231,6 +1631,356 @@ lpfc_debugfs_dumpDataDif_release(struct inode *inode, struct file *file)
1231 return 0; 1631 return 0;
1232} 1632}
1233 1633
1634
1635static int
1636lpfc_debugfs_nvmestat_open(struct inode *inode, struct file *file)
1637{
1638 struct lpfc_vport *vport = inode->i_private;
1639 struct lpfc_debug *debug;
1640 int rc = -ENOMEM;
1641
1642 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1643 if (!debug)
1644 goto out;
1645
1646 /* Round to page boundary */
1647 debug->buffer = kmalloc(LPFC_NVMESTAT_SIZE, GFP_KERNEL);
1648 if (!debug->buffer) {
1649 kfree(debug);
1650 goto out;
1651 }
1652
1653 debug->len = lpfc_debugfs_nvmestat_data(vport, debug->buffer,
1654 LPFC_NVMESTAT_SIZE);
1655
1656 debug->i_private = inode->i_private;
1657 file->private_data = debug;
1658
1659 rc = 0;
1660out:
1661 return rc;
1662}
1663
1664static int
1665lpfc_debugfs_nvmektime_open(struct inode *inode, struct file *file)
1666{
1667 struct lpfc_vport *vport = inode->i_private;
1668 struct lpfc_debug *debug;
1669 int rc = -ENOMEM;
1670
1671 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1672 if (!debug)
1673 goto out;
1674
1675 /* Round to page boundary */
1676 debug->buffer = kmalloc(LPFC_NVMEKTIME_SIZE, GFP_KERNEL);
1677 if (!debug->buffer) {
1678 kfree(debug);
1679 goto out;
1680 }
1681
1682 debug->len = lpfc_debugfs_nvmektime_data(vport, debug->buffer,
1683 LPFC_NVMEKTIME_SIZE);
1684
1685 debug->i_private = inode->i_private;
1686 file->private_data = debug;
1687
1688 rc = 0;
1689out:
1690 return rc;
1691}
1692
1693static ssize_t
1694lpfc_debugfs_nvmektime_write(struct file *file, const char __user *buf,
1695 size_t nbytes, loff_t *ppos)
1696{
1697 struct lpfc_debug *debug = file->private_data;
1698 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
1699 struct lpfc_hba *phba = vport->phba;
1700 char mybuf[64];
1701 char *pbuf;
1702
1703 if (nbytes > 64)
1704 nbytes = 64;
1705
1706 /* Protect copy from user */
1707 if (!access_ok(VERIFY_READ, buf, nbytes))
1708 return -EFAULT;
1709
1710 memset(mybuf, 0, sizeof(mybuf));
1711
1712 if (copy_from_user(mybuf, buf, nbytes))
1713 return -EFAULT;
1714 pbuf = &mybuf[0];
1715
1716 if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
1717 phba->ktime_data_samples = 0;
1718 phba->ktime_status_samples = 0;
1719 phba->ktime_seg1_total = 0;
1720 phba->ktime_seg1_max = 0;
1721 phba->ktime_seg1_min = 0xffffffff;
1722 phba->ktime_seg2_total = 0;
1723 phba->ktime_seg2_max = 0;
1724 phba->ktime_seg2_min = 0xffffffff;
1725 phba->ktime_seg3_total = 0;
1726 phba->ktime_seg3_max = 0;
1727 phba->ktime_seg3_min = 0xffffffff;
1728 phba->ktime_seg4_total = 0;
1729 phba->ktime_seg4_max = 0;
1730 phba->ktime_seg4_min = 0xffffffff;
1731 phba->ktime_seg5_total = 0;
1732 phba->ktime_seg5_max = 0;
1733 phba->ktime_seg5_min = 0xffffffff;
1734 phba->ktime_seg6_total = 0;
1735 phba->ktime_seg6_max = 0;
1736 phba->ktime_seg6_min = 0xffffffff;
1737 phba->ktime_seg7_total = 0;
1738 phba->ktime_seg7_max = 0;
1739 phba->ktime_seg7_min = 0xffffffff;
1740 phba->ktime_seg8_total = 0;
1741 phba->ktime_seg8_max = 0;
1742 phba->ktime_seg8_min = 0xffffffff;
1743 phba->ktime_seg9_total = 0;
1744 phba->ktime_seg9_max = 0;
1745 phba->ktime_seg9_min = 0xffffffff;
1746 phba->ktime_seg10_total = 0;
1747 phba->ktime_seg10_max = 0;
1748 phba->ktime_seg10_min = 0xffffffff;
1749
1750 phba->ktime_on = 1;
1751 return strlen(pbuf);
1752 } else if ((strncmp(pbuf, "off",
1753 sizeof("off") - 1) == 0)) {
1754 phba->ktime_on = 0;
1755 return strlen(pbuf);
1756 } else if ((strncmp(pbuf, "zero",
1757 sizeof("zero") - 1) == 0)) {
1758 phba->ktime_data_samples = 0;
1759 phba->ktime_status_samples = 0;
1760 phba->ktime_seg1_total = 0;
1761 phba->ktime_seg1_max = 0;
1762 phba->ktime_seg1_min = 0xffffffff;
1763 phba->ktime_seg2_total = 0;
1764 phba->ktime_seg2_max = 0;
1765 phba->ktime_seg2_min = 0xffffffff;
1766 phba->ktime_seg3_total = 0;
1767 phba->ktime_seg3_max = 0;
1768 phba->ktime_seg3_min = 0xffffffff;
1769 phba->ktime_seg4_total = 0;
1770 phba->ktime_seg4_max = 0;
1771 phba->ktime_seg4_min = 0xffffffff;
1772 phba->ktime_seg5_total = 0;
1773 phba->ktime_seg5_max = 0;
1774 phba->ktime_seg5_min = 0xffffffff;
1775 phba->ktime_seg6_total = 0;
1776 phba->ktime_seg6_max = 0;
1777 phba->ktime_seg6_min = 0xffffffff;
1778 phba->ktime_seg7_total = 0;
1779 phba->ktime_seg7_max = 0;
1780 phba->ktime_seg7_min = 0xffffffff;
1781 phba->ktime_seg8_total = 0;
1782 phba->ktime_seg8_max = 0;
1783 phba->ktime_seg8_min = 0xffffffff;
1784 phba->ktime_seg9_total = 0;
1785 phba->ktime_seg9_max = 0;
1786 phba->ktime_seg9_min = 0xffffffff;
1787 phba->ktime_seg10_total = 0;
1788 phba->ktime_seg10_max = 0;
1789 phba->ktime_seg10_min = 0xffffffff;
1790 return strlen(pbuf);
1791 }
1792 return -EINVAL;
1793}
1794
1795static int
1796lpfc_debugfs_nvmeio_trc_open(struct inode *inode, struct file *file)
1797{
1798 struct lpfc_hba *phba = inode->i_private;
1799 struct lpfc_debug *debug;
1800 int rc = -ENOMEM;
1801
1802 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1803 if (!debug)
1804 goto out;
1805
1806 /* Round to page boundary */
1807 debug->buffer = kmalloc(LPFC_NVMEIO_TRC_SIZE, GFP_KERNEL);
1808 if (!debug->buffer) {
1809 kfree(debug);
1810 goto out;
1811 }
1812
1813 debug->len = lpfc_debugfs_nvmeio_trc_data(phba, debug->buffer,
1814 LPFC_NVMEIO_TRC_SIZE);
1815
1816 debug->i_private = inode->i_private;
1817 file->private_data = debug;
1818
1819 rc = 0;
1820out:
1821 return rc;
1822}
1823
1824static ssize_t
1825lpfc_debugfs_nvmeio_trc_write(struct file *file, const char __user *buf,
1826 size_t nbytes, loff_t *ppos)
1827{
1828 struct lpfc_debug *debug = file->private_data;
1829 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1830 int i;
1831 unsigned long sz;
1832 char mybuf[64];
1833 char *pbuf;
1834
1835 if (nbytes > 64)
1836 nbytes = 64;
1837
1838 /* Protect copy from user */
1839 if (!access_ok(VERIFY_READ, buf, nbytes))
1840 return -EFAULT;
1841
1842 memset(mybuf, 0, sizeof(mybuf));
1843
1844 if (copy_from_user(mybuf, buf, nbytes))
1845 return -EFAULT;
1846 pbuf = &mybuf[0];
1847
1848 if ((strncmp(pbuf, "off", sizeof("off") - 1) == 0)) {
1849 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1850 "0570 nvmeio_trc_off\n");
1851 phba->nvmeio_trc_output_idx = 0;
1852 phba->nvmeio_trc_on = 0;
1853 return strlen(pbuf);
1854 } else if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
1855 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1856 "0571 nvmeio_trc_on\n");
1857 phba->nvmeio_trc_output_idx = 0;
1858 phba->nvmeio_trc_on = 1;
1859 return strlen(pbuf);
1860 }
1861
1862 /* We must be off to allocate the trace buffer */
1863 if (phba->nvmeio_trc_on != 0)
1864 return -EINVAL;
1865
1866 /* If not on or off, the parameter is the trace buffer size */
1867 i = kstrtoul(pbuf, 0, &sz);
1868 if (i)
1869 return -EINVAL;
1870 phba->nvmeio_trc_size = (uint32_t)sz;
1871
1872 /* It must be a power of 2 - round down */
1873 i = 0;
1874 while (sz > 1) {
1875 sz = sz >> 1;
1876 i++;
1877 }
1878 sz = (1 << i);
1879 if (phba->nvmeio_trc_size != sz)
1880 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1881 "0572 nvmeio_trc_size changed to %ld\n",
1882 sz);
1883 phba->nvmeio_trc_size = (uint32_t)sz;
1884
1885 /* If one previously exists, free it */
1886 kfree(phba->nvmeio_trc);
1887
1888 /* Allocate new trace buffer and initialize */
1889 phba->nvmeio_trc = kmalloc((sizeof(struct lpfc_debugfs_nvmeio_trc) *
1890 sz), GFP_KERNEL);
1891 if (!phba->nvmeio_trc) {
1892 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1893 "0573 Cannot create debugfs "
1894 "nvmeio_trc buffer\n");
1895 return -ENOMEM;
1896 }
1897 memset(phba->nvmeio_trc, 0,
1898 (sizeof(struct lpfc_debugfs_nvmeio_trc) * sz));
1899 atomic_set(&phba->nvmeio_trc_cnt, 0);
1900 phba->nvmeio_trc_on = 0;
1901 phba->nvmeio_trc_output_idx = 0;
1902
1903 return strlen(pbuf);
1904}
1905
1906static int
1907lpfc_debugfs_cpucheck_open(struct inode *inode, struct file *file)
1908{
1909 struct lpfc_vport *vport = inode->i_private;
1910 struct lpfc_debug *debug;
1911 int rc = -ENOMEM;
1912
1913 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1914 if (!debug)
1915 goto out;
1916
1917 /* Round to page boundary */
1918 debug->buffer = kmalloc(LPFC_CPUCHECK_SIZE, GFP_KERNEL);
1919 if (!debug->buffer) {
1920 kfree(debug);
1921 goto out;
1922 }
1923
1924 debug->len = lpfc_debugfs_cpucheck_data(vport, debug->buffer,
1925 LPFC_NVMEKTIME_SIZE);
1926
1927 debug->i_private = inode->i_private;
1928 file->private_data = debug;
1929
1930 rc = 0;
1931out:
1932 return rc;
1933}
1934
1935static ssize_t
1936lpfc_debugfs_cpucheck_write(struct file *file, const char __user *buf,
1937 size_t nbytes, loff_t *ppos)
1938{
1939 struct lpfc_debug *debug = file->private_data;
1940 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
1941 struct lpfc_hba *phba = vport->phba;
1942 char mybuf[64];
1943 char *pbuf;
1944 int i;
1945
1946 if (nbytes > 64)
1947 nbytes = 64;
1948
1949 /* Protect copy from user */
1950 if (!access_ok(VERIFY_READ, buf, nbytes))
1951 return -EFAULT;
1952
1953 memset(mybuf, 0, sizeof(mybuf));
1954
1955 if (copy_from_user(mybuf, buf, nbytes))
1956 return -EFAULT;
1957 pbuf = &mybuf[0];
1958
1959 if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
1960 phba->cpucheck_on |= LPFC_CHECK_NVME_IO;
1961 return strlen(pbuf);
1962 } else if ((strncmp(pbuf, "rcv",
1963 sizeof("rcv") - 1) == 0)) {
1964 return -EINVAL;
1965 } else if ((strncmp(pbuf, "off",
1966 sizeof("off") - 1) == 0)) {
1967 phba->cpucheck_on = LPFC_CHECK_OFF;
1968 return strlen(pbuf);
1969 } else if ((strncmp(pbuf, "zero",
1970 sizeof("zero") - 1) == 0)) {
1971 for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) {
1972 if (i >= LPFC_CHECK_CPU_CNT)
1973 break;
1974 phba->cpucheck_rcv_io[i] = 0;
1975 phba->cpucheck_xmt_io[i] = 0;
1976 phba->cpucheck_cmpl_io[i] = 0;
1977 phba->cpucheck_ccmpl_io[i] = 0;
1978 }
1979 return strlen(pbuf);
1980 }
1981 return -EINVAL;
1982}
1983
1234/* 1984/*
1235 * --------------------------------- 1985 * ---------------------------------
1236 * iDiag debugfs file access methods 1986 * iDiag debugfs file access methods
@@ -2581,6 +3331,17 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
2581 idiag.ptr_private = phba->sli4_hba.nvmels_cq; 3331 idiag.ptr_private = phba->sli4_hba.nvmels_cq;
2582 goto pass_check; 3332 goto pass_check;
2583 } 3333 }
3334 /* NVME LS complete queue */
3335 if (phba->sli4_hba.nvmels_cq &&
3336 phba->sli4_hba.nvmels_cq->queue_id == queid) {
3337 /* Sanity check */
3338 rc = lpfc_idiag_que_param_check(
3339 phba->sli4_hba.nvmels_cq, index, count);
3340 if (rc)
3341 goto error_out;
3342 idiag.ptr_private = phba->sli4_hba.nvmels_cq;
3343 goto pass_check;
3344 }
2584 /* FCP complete queue */ 3345 /* FCP complete queue */
2585 if (phba->sli4_hba.fcp_cq) { 3346 if (phba->sli4_hba.fcp_cq) {
2586 for (qidx = 0; qidx < phba->cfg_fcp_io_channel; 3347 for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
@@ -2597,6 +3358,25 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
2597 } 3358 }
2598 } 3359 }
2599 } 3360 }
3361 /* NVME complete queue */
3362 if (phba->sli4_hba.nvme_cq) {
3363 qidx = 0;
3364 do {
3365 if (phba->sli4_hba.nvme_cq[qidx] &&
3366 phba->sli4_hba.nvme_cq[qidx]->queue_id ==
3367 queid) {
3368 /* Sanity check */
3369 rc = lpfc_idiag_que_param_check(
3370 phba->sli4_hba.nvme_cq[qidx],
3371 index, count);
3372 if (rc)
3373 goto error_out;
3374 idiag.ptr_private =
3375 phba->sli4_hba.nvme_cq[qidx];
3376 goto pass_check;
3377 }
3378 } while (++qidx < phba->cfg_nvme_io_channel);
3379 }
2600 goto error_out; 3380 goto error_out;
2601 break; 3381 break;
2602 case LPFC_IDIAG_MQ: 3382 case LPFC_IDIAG_MQ:
@@ -2636,6 +3416,17 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
2636 idiag.ptr_private = phba->sli4_hba.nvmels_wq; 3416 idiag.ptr_private = phba->sli4_hba.nvmels_wq;
2637 goto pass_check; 3417 goto pass_check;
2638 } 3418 }
3419 /* NVME LS work queue */
3420 if (phba->sli4_hba.nvmels_wq &&
3421 phba->sli4_hba.nvmels_wq->queue_id == queid) {
3422 /* Sanity check */
3423 rc = lpfc_idiag_que_param_check(
3424 phba->sli4_hba.nvmels_wq, index, count);
3425 if (rc)
3426 goto error_out;
3427 idiag.ptr_private = phba->sli4_hba.nvmels_wq;
3428 goto pass_check;
3429 }
2639 /* FCP work queue */ 3430 /* FCP work queue */
2640 if (phba->sli4_hba.fcp_wq) { 3431 if (phba->sli4_hba.fcp_wq) {
2641 for (qidx = 0; qidx < phba->cfg_fcp_io_channel; 3432 for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
@@ -2668,6 +3459,27 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
2668 } 3459 }
2669 } 3460 }
2670 } 3461 }
3462
3463 /* NVME work queues */
3464 if (phba->sli4_hba.nvme_wq) {
3465 for (qidx = 0; qidx < phba->cfg_nvme_io_channel;
3466 qidx++) {
3467 if (!phba->sli4_hba.nvme_wq[qidx])
3468 continue;
3469 if (phba->sli4_hba.nvme_wq[qidx]->queue_id ==
3470 queid) {
3471 /* Sanity check */
3472 rc = lpfc_idiag_que_param_check(
3473 phba->sli4_hba.nvme_wq[qidx],
3474 index, count);
3475 if (rc)
3476 goto error_out;
3477 idiag.ptr_private =
3478 phba->sli4_hba.nvme_wq[qidx];
3479 goto pass_check;
3480 }
3481 }
3482 }
2671 goto error_out; 3483 goto error_out;
2672 break; 3484 break;
2673 case LPFC_IDIAG_RQ: 3485 case LPFC_IDIAG_RQ:
@@ -3651,6 +4463,45 @@ static const struct file_operations lpfc_debugfs_op_dumpHostSlim = {
3651 .release = lpfc_debugfs_release, 4463 .release = lpfc_debugfs_release,
3652}; 4464};
3653 4465
4466#undef lpfc_debugfs_op_nvmestat
4467static const struct file_operations lpfc_debugfs_op_nvmestat = {
4468 .owner = THIS_MODULE,
4469 .open = lpfc_debugfs_nvmestat_open,
4470 .llseek = lpfc_debugfs_lseek,
4471 .read = lpfc_debugfs_read,
4472 .release = lpfc_debugfs_release,
4473};
4474
4475#undef lpfc_debugfs_op_nvmektime
4476static const struct file_operations lpfc_debugfs_op_nvmektime = {
4477 .owner = THIS_MODULE,
4478 .open = lpfc_debugfs_nvmektime_open,
4479 .llseek = lpfc_debugfs_lseek,
4480 .read = lpfc_debugfs_read,
4481 .write = lpfc_debugfs_nvmektime_write,
4482 .release = lpfc_debugfs_release,
4483};
4484
4485#undef lpfc_debugfs_op_nvmeio_trc
4486static const struct file_operations lpfc_debugfs_op_nvmeio_trc = {
4487 .owner = THIS_MODULE,
4488 .open = lpfc_debugfs_nvmeio_trc_open,
4489 .llseek = lpfc_debugfs_lseek,
4490 .read = lpfc_debugfs_read,
4491 .write = lpfc_debugfs_nvmeio_trc_write,
4492 .release = lpfc_debugfs_release,
4493};
4494
4495#undef lpfc_debugfs_op_cpucheck
4496static const struct file_operations lpfc_debugfs_op_cpucheck = {
4497 .owner = THIS_MODULE,
4498 .open = lpfc_debugfs_cpucheck_open,
4499 .llseek = lpfc_debugfs_lseek,
4500 .read = lpfc_debugfs_read,
4501 .write = lpfc_debugfs_cpucheck_write,
4502 .release = lpfc_debugfs_release,
4503};
4504
3654#undef lpfc_debugfs_op_dumpData 4505#undef lpfc_debugfs_op_dumpData
3655static const struct file_operations lpfc_debugfs_op_dumpData = { 4506static const struct file_operations lpfc_debugfs_op_dumpData = {
3656 .owner = THIS_MODULE, 4507 .owner = THIS_MODULE,
@@ -4237,6 +5088,60 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
4237 lpfc_debugfs_max_slow_ring_trc)); 5088 lpfc_debugfs_max_slow_ring_trc));
4238 } 5089 }
4239 5090
5091 snprintf(name, sizeof(name), "nvmeio_trc");
5092 phba->debug_nvmeio_trc =
5093 debugfs_create_file(name, 0644,
5094 phba->hba_debugfs_root,
5095 phba, &lpfc_debugfs_op_nvmeio_trc);
5096 if (!phba->debug_nvmeio_trc) {
5097 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
5098 "0574 No create debugfs nvmeio_trc\n");
5099 goto debug_failed;
5100 }
5101
5102 atomic_set(&phba->nvmeio_trc_cnt, 0);
5103 if (lpfc_debugfs_max_nvmeio_trc) {
5104 num = lpfc_debugfs_max_nvmeio_trc - 1;
5105 if (num & lpfc_debugfs_max_disc_trc) {
5106 /* Change to be a power of 2 */
5107 num = lpfc_debugfs_max_nvmeio_trc;
5108 i = 0;
5109 while (num > 1) {
5110 num = num >> 1;
5111 i++;
5112 }
5113 lpfc_debugfs_max_nvmeio_trc = (1 << i);
5114 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
5115 "0575 lpfc_debugfs_max_nvmeio_trc "
5116 "changed to %d\n",
5117 lpfc_debugfs_max_nvmeio_trc);
5118 }
5119 phba->nvmeio_trc_size = lpfc_debugfs_max_nvmeio_trc;
5120
5121 /* Allocate trace buffer and initialize */
5122 phba->nvmeio_trc = kmalloc(
5123 (sizeof(struct lpfc_debugfs_nvmeio_trc) *
5124 phba->nvmeio_trc_size), GFP_KERNEL);
5125
5126 if (!phba->nvmeio_trc) {
5127 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
5128 "0576 Cannot create debugfs "
5129 "nvmeio_trc buffer\n");
5130 goto nvmeio_off;
5131 }
5132 memset(phba->nvmeio_trc, 0,
5133 (sizeof(struct lpfc_debugfs_nvmeio_trc) *
5134 phba->nvmeio_trc_size));
5135 phba->nvmeio_trc_on = 1;
5136 phba->nvmeio_trc_output_idx = 0;
5137 phba->nvmeio_trc = NULL;
5138 } else {
5139nvmeio_off:
5140 phba->nvmeio_trc_size = 0;
5141 phba->nvmeio_trc_on = 0;
5142 phba->nvmeio_trc_output_idx = 0;
5143 phba->nvmeio_trc = NULL;
5144 }
4240 } 5145 }
4241 5146
4242 snprintf(name, sizeof(name), "vport%d", vport->vpi); 5147 snprintf(name, sizeof(name), "vport%d", vport->vpi);
@@ -4301,6 +5206,39 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
4301 goto debug_failed; 5206 goto debug_failed;
4302 } 5207 }
4303 5208
5209 snprintf(name, sizeof(name), "nvmestat");
5210 vport->debug_nvmestat =
5211 debugfs_create_file(name, 0644,
5212 vport->vport_debugfs_root,
5213 vport, &lpfc_debugfs_op_nvmestat);
5214 if (!vport->debug_nvmestat) {
5215 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
5216 "0811 Cannot create debugfs nvmestat\n");
5217 goto debug_failed;
5218 }
5219
5220 snprintf(name, sizeof(name), "nvmektime");
5221 vport->debug_nvmektime =
5222 debugfs_create_file(name, 0644,
5223 vport->vport_debugfs_root,
5224 vport, &lpfc_debugfs_op_nvmektime);
5225 if (!vport->debug_nvmektime) {
5226 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
5227 "0815 Cannot create debugfs nvmektime\n");
5228 goto debug_failed;
5229 }
5230
5231 snprintf(name, sizeof(name), "cpucheck");
5232 vport->debug_cpucheck =
5233 debugfs_create_file(name, 0644,
5234 vport->vport_debugfs_root,
5235 vport, &lpfc_debugfs_op_cpucheck);
5236 if (!vport->debug_cpucheck) {
5237 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
5238 "0819 Cannot create debugfs cpucheck\n");
5239 goto debug_failed;
5240 }
5241
4304 /* 5242 /*
4305 * The following section is for additional directories/files for the 5243 * The following section is for additional directories/files for the
4306 * physical port. 5244 * physical port.
@@ -4465,140 +5403,126 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
4465 kfree(vport->disc_trc); 5403 kfree(vport->disc_trc);
4466 vport->disc_trc = NULL; 5404 vport->disc_trc = NULL;
4467 } 5405 }
4468 if (vport->debug_disc_trc) { 5406
4469 debugfs_remove(vport->debug_disc_trc); /* discovery_trace */ 5407 debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
4470 vport->debug_disc_trc = NULL; 5408 vport->debug_disc_trc = NULL;
4471 } 5409
4472 if (vport->debug_nodelist) { 5410 debugfs_remove(vport->debug_nodelist); /* nodelist */
4473 debugfs_remove(vport->debug_nodelist); /* nodelist */ 5411 vport->debug_nodelist = NULL;
4474 vport->debug_nodelist = NULL; 5412
4475 } 5413 debugfs_remove(vport->debug_nvmestat); /* nvmestat */
5414 vport->debug_nvmestat = NULL;
5415
5416 debugfs_remove(vport->debug_nvmektime); /* nvmektime */
5417 vport->debug_nvmektime = NULL;
5418
5419 debugfs_remove(vport->debug_cpucheck); /* cpucheck */
5420 vport->debug_cpucheck = NULL;
5421
4476 if (vport->vport_debugfs_root) { 5422 if (vport->vport_debugfs_root) {
4477 debugfs_remove(vport->vport_debugfs_root); /* vportX */ 5423 debugfs_remove(vport->vport_debugfs_root); /* vportX */
4478 vport->vport_debugfs_root = NULL; 5424 vport->vport_debugfs_root = NULL;
4479 atomic_dec(&phba->debugfs_vport_count); 5425 atomic_dec(&phba->debugfs_vport_count);
4480 } 5426 }
5427
4481 if (atomic_read(&phba->debugfs_vport_count) == 0) { 5428 if (atomic_read(&phba->debugfs_vport_count) == 0) {
4482 5429
4483 if (phba->debug_hbqinfo) { 5430 debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
4484 debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */ 5431 phba->debug_hbqinfo = NULL;
4485 phba->debug_hbqinfo = NULL;
4486 }
4487 if (phba->debug_dumpHBASlim) {
4488 debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */
4489 phba->debug_dumpHBASlim = NULL;
4490 }
4491 if (phba->debug_dumpHostSlim) {
4492 debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */
4493 phba->debug_dumpHostSlim = NULL;
4494 }
4495 if (phba->debug_dumpData) {
4496 debugfs_remove(phba->debug_dumpData); /* dumpData */
4497 phba->debug_dumpData = NULL;
4498 }
4499 5432
4500 if (phba->debug_dumpDif) { 5433 debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */
4501 debugfs_remove(phba->debug_dumpDif); /* dumpDif */ 5434 phba->debug_dumpHBASlim = NULL;
4502 phba->debug_dumpDif = NULL; 5435
4503 } 5436 debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */
4504 if (phba->debug_InjErrLBA) { 5437 phba->debug_dumpHostSlim = NULL;
4505 debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */ 5438
4506 phba->debug_InjErrLBA = NULL; 5439 debugfs_remove(phba->debug_dumpData); /* dumpData */
4507 } 5440 phba->debug_dumpData = NULL;
4508 if (phba->debug_InjErrNPortID) { /* InjErrNPortID */ 5441
4509 debugfs_remove(phba->debug_InjErrNPortID); 5442 debugfs_remove(phba->debug_dumpDif); /* dumpDif */
4510 phba->debug_InjErrNPortID = NULL; 5443 phba->debug_dumpDif = NULL;
4511 } 5444
4512 if (phba->debug_InjErrWWPN) { 5445 debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */
4513 debugfs_remove(phba->debug_InjErrWWPN); /* InjErrWWPN */ 5446 phba->debug_InjErrLBA = NULL;
4514 phba->debug_InjErrWWPN = NULL; 5447
4515 } 5448 debugfs_remove(phba->debug_InjErrNPortID);
4516 if (phba->debug_writeGuard) { 5449 phba->debug_InjErrNPortID = NULL;
4517 debugfs_remove(phba->debug_writeGuard); /* writeGuard */ 5450
4518 phba->debug_writeGuard = NULL; 5451 debugfs_remove(phba->debug_InjErrWWPN); /* InjErrWWPN */
4519 } 5452 phba->debug_InjErrWWPN = NULL;
4520 if (phba->debug_writeApp) { 5453
4521 debugfs_remove(phba->debug_writeApp); /* writeApp */ 5454 debugfs_remove(phba->debug_writeGuard); /* writeGuard */
4522 phba->debug_writeApp = NULL; 5455 phba->debug_writeGuard = NULL;
4523 } 5456
4524 if (phba->debug_writeRef) { 5457 debugfs_remove(phba->debug_writeApp); /* writeApp */
4525 debugfs_remove(phba->debug_writeRef); /* writeRef */ 5458 phba->debug_writeApp = NULL;
4526 phba->debug_writeRef = NULL; 5459
4527 } 5460 debugfs_remove(phba->debug_writeRef); /* writeRef */
4528 if (phba->debug_readGuard) { 5461 phba->debug_writeRef = NULL;
4529 debugfs_remove(phba->debug_readGuard); /* readGuard */ 5462
4530 phba->debug_readGuard = NULL; 5463 debugfs_remove(phba->debug_readGuard); /* readGuard */
4531 } 5464 phba->debug_readGuard = NULL;
4532 if (phba->debug_readApp) { 5465
4533 debugfs_remove(phba->debug_readApp); /* readApp */ 5466 debugfs_remove(phba->debug_readApp); /* readApp */
4534 phba->debug_readApp = NULL; 5467 phba->debug_readApp = NULL;
4535 } 5468
4536 if (phba->debug_readRef) { 5469 debugfs_remove(phba->debug_readRef); /* readRef */
4537 debugfs_remove(phba->debug_readRef); /* readRef */ 5470 phba->debug_readRef = NULL;
4538 phba->debug_readRef = NULL;
4539 }
4540 5471
4541 if (phba->slow_ring_trc) { 5472 if (phba->slow_ring_trc) {
4542 kfree(phba->slow_ring_trc); 5473 kfree(phba->slow_ring_trc);
4543 phba->slow_ring_trc = NULL; 5474 phba->slow_ring_trc = NULL;
4544 } 5475 }
4545 if (phba->debug_slow_ring_trc) { 5476
4546 /* slow_ring_trace */ 5477 /* slow_ring_trace */
4547 debugfs_remove(phba->debug_slow_ring_trc); 5478 debugfs_remove(phba->debug_slow_ring_trc);
4548 phba->debug_slow_ring_trc = NULL; 5479 phba->debug_slow_ring_trc = NULL;
4549 } 5480
5481 debugfs_remove(phba->debug_nvmeio_trc);
5482 phba->debug_nvmeio_trc = NULL;
5483
5484 kfree(phba->nvmeio_trc);
5485 phba->nvmeio_trc = NULL;
4550 5486
4551 /* 5487 /*
4552 * iDiag release 5488 * iDiag release
4553 */ 5489 */
4554 if (phba->sli_rev == LPFC_SLI_REV4) { 5490 if (phba->sli_rev == LPFC_SLI_REV4) {
4555 if (phba->idiag_ext_acc) { 5491 /* iDiag extAcc */
4556 /* iDiag extAcc */ 5492 debugfs_remove(phba->idiag_ext_acc);
4557 debugfs_remove(phba->idiag_ext_acc); 5493 phba->idiag_ext_acc = NULL;
4558 phba->idiag_ext_acc = NULL; 5494
4559 } 5495 /* iDiag mbxAcc */
4560 if (phba->idiag_mbx_acc) { 5496 debugfs_remove(phba->idiag_mbx_acc);
4561 /* iDiag mbxAcc */ 5497 phba->idiag_mbx_acc = NULL;
4562 debugfs_remove(phba->idiag_mbx_acc); 5498
4563 phba->idiag_mbx_acc = NULL; 5499 /* iDiag ctlAcc */
4564 } 5500 debugfs_remove(phba->idiag_ctl_acc);
4565 if (phba->idiag_ctl_acc) { 5501 phba->idiag_ctl_acc = NULL;
4566 /* iDiag ctlAcc */ 5502
4567 debugfs_remove(phba->idiag_ctl_acc); 5503 /* iDiag drbAcc */
4568 phba->idiag_ctl_acc = NULL; 5504 debugfs_remove(phba->idiag_drb_acc);
4569 } 5505 phba->idiag_drb_acc = NULL;
4570 if (phba->idiag_drb_acc) { 5506
4571 /* iDiag drbAcc */ 5507 /* iDiag queAcc */
4572 debugfs_remove(phba->idiag_drb_acc); 5508 debugfs_remove(phba->idiag_que_acc);
4573 phba->idiag_drb_acc = NULL; 5509 phba->idiag_que_acc = NULL;
4574 } 5510
4575 if (phba->idiag_que_acc) { 5511 /* iDiag queInfo */
4576 /* iDiag queAcc */ 5512 debugfs_remove(phba->idiag_que_info);
4577 debugfs_remove(phba->idiag_que_acc); 5513 phba->idiag_que_info = NULL;
4578 phba->idiag_que_acc = NULL; 5514
4579 } 5515 /* iDiag barAcc */
4580 if (phba->idiag_que_info) { 5516 debugfs_remove(phba->idiag_bar_acc);
4581 /* iDiag queInfo */ 5517 phba->idiag_bar_acc = NULL;
4582 debugfs_remove(phba->idiag_que_info); 5518
4583 phba->idiag_que_info = NULL; 5519 /* iDiag pciCfg */
4584 } 5520 debugfs_remove(phba->idiag_pci_cfg);
4585 if (phba->idiag_bar_acc) { 5521 phba->idiag_pci_cfg = NULL;
4586 /* iDiag barAcc */
4587 debugfs_remove(phba->idiag_bar_acc);
4588 phba->idiag_bar_acc = NULL;
4589 }
4590 if (phba->idiag_pci_cfg) {
4591 /* iDiag pciCfg */
4592 debugfs_remove(phba->idiag_pci_cfg);
4593 phba->idiag_pci_cfg = NULL;
4594 }
4595 5522
4596 /* Finally remove the iDiag debugfs root */ 5523 /* Finally remove the iDiag debugfs root */
4597 if (phba->idiag_root) { 5524 debugfs_remove(phba->idiag_root);
4598 /* iDiag root */ 5525 phba->idiag_root = NULL;
4599 debugfs_remove(phba->idiag_root);
4600 phba->idiag_root = NULL;
4601 }
4602 } 5526 }
4603 5527
4604 if (phba->hba_debugfs_root) { 5528 if (phba->hba_debugfs_root) {
@@ -4607,10 +5531,8 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
4607 atomic_dec(&lpfc_debugfs_hba_count); 5531 atomic_dec(&lpfc_debugfs_hba_count);
4608 } 5532 }
4609 5533
4610 if (atomic_read(&lpfc_debugfs_hba_count) == 0) { 5534 debugfs_remove(lpfc_debugfs_root); /* lpfc */
4611 debugfs_remove(lpfc_debugfs_root); /* lpfc */ 5535 lpfc_debugfs_root = NULL;
4612 lpfc_debugfs_root = NULL;
4613 }
4614 } 5536 }
4615#endif 5537#endif
4616 return; 5538 return;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index 98814d651239..5312e0f9deb6 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -50,6 +50,14 @@ enum {
50 DUMP_NVMELS, 50 DUMP_NVMELS,
51}; 51};
52 52
53/* nvmestat output buffer size */
54#define LPFC_NVMESTAT_SIZE 8192
55#define LPFC_NVMEKTIME_SIZE 8192
56#define LPFC_CPUCHECK_SIZE 8192
57#define LPFC_NVMEIO_TRC_SIZE 8192
58
59#define LPFC_DEBUG_OUT_LINE_SZ 80
60
53/* 61/*
54 * For SLI4 iDiag debugfs diagnostics tool 62 * For SLI4 iDiag debugfs diagnostics tool
55 */ 63 */
@@ -196,6 +204,12 @@ enum {
196#define SIZE_U16 sizeof(uint16_t) 204#define SIZE_U16 sizeof(uint16_t)
197#define SIZE_U32 sizeof(uint32_t) 205#define SIZE_U32 sizeof(uint32_t)
198 206
207#define lpfc_nvmeio_data(phba, fmt, arg...) \
208 { \
209 if (phba->nvmeio_trc_on) \
210 lpfc_debugfs_nvme_trc(phba, fmt, ##arg); \
211 }
212
199struct lpfc_debug { 213struct lpfc_debug {
200 char *i_private; 214 char *i_private;
201 char op; 215 char op;
@@ -214,6 +228,13 @@ struct lpfc_debugfs_trc {
214 unsigned long jif; 228 unsigned long jif;
215}; 229};
216 230
231struct lpfc_debugfs_nvmeio_trc {
232 char *fmt;
233 uint16_t data1;
234 uint16_t data2;
235 uint32_t data3;
236};
237
217struct lpfc_idiag_offset { 238struct lpfc_idiag_offset {
218 uint32_t last_rd; 239 uint32_t last_rd;
219}; 240};
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 729803dacf15..56b4b94a372e 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -50,6 +50,7 @@
50#include "lpfc_logmsg.h" 50#include "lpfc_logmsg.h"
51#include "lpfc_crtn.h" 51#include "lpfc_crtn.h"
52#include "lpfc_vport.h" 52#include "lpfc_vport.h"
53#include "lpfc_debugfs.h"
53 54
54/* NVME initiator-based functions */ 55/* NVME initiator-based functions */
55 56
@@ -222,6 +223,9 @@ lpfc_nvme_cmpl_gen_req(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
222 cmdwqe->sli4_xritag, status, 223 cmdwqe->sli4_xritag, status,
223 cmdwqe, pnvme_lsreq, cmdwqe->context3, ndlp); 224 cmdwqe, pnvme_lsreq, cmdwqe->context3, ndlp);
224 225
226 lpfc_nvmeio_data(phba, "NVME LS CMPL: xri x%x stat x%x parm x%x\n",
227 cmdwqe->sli4_xritag, status, wcqe->parameter);
228
225 if (cmdwqe->context3) { 229 if (cmdwqe->context3) {
226 buf_ptr = (struct lpfc_dmabuf *)cmdwqe->context3; 230 buf_ptr = (struct lpfc_dmabuf *)cmdwqe->context3;
227 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); 231 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
@@ -355,6 +359,9 @@ lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
355 genwqe->vport = vport; 359 genwqe->vport = vport;
356 genwqe->retry = retry; 360 genwqe->retry = retry;
357 361
362 lpfc_nvmeio_data(phba, "NVME LS XMIT: xri x%x iotag x%x to x%06x\n",
363 genwqe->sli4_xritag, genwqe->iotag, ndlp->nlp_DID);
364
358 rc = lpfc_sli4_issue_wqe(phba, LPFC_ELS_RING, genwqe); 365 rc = lpfc_sli4_issue_wqe(phba, LPFC_ELS_RING, genwqe);
359 if (rc == WQE_ERROR) { 366 if (rc == WQE_ERROR) {
360 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, 367 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
@@ -637,6 +644,79 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
637 *wptr = *dptr; /* Word 23 */ 644 *wptr = *dptr; /* Word 23 */
638} 645}
639 646
647#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
648static void
649lpfc_nvme_ktime(struct lpfc_hba *phba,
650 struct lpfc_nvme_buf *lpfc_ncmd)
651{
652 uint64_t seg1, seg2, seg3, seg4;
653
654 if (!phba->ktime_on)
655 return;
656 if (!lpfc_ncmd->ts_last_cmd ||
657 !lpfc_ncmd->ts_cmd_start ||
658 !lpfc_ncmd->ts_cmd_wqput ||
659 !lpfc_ncmd->ts_isr_cmpl ||
660 !lpfc_ncmd->ts_data_nvme)
661 return;
662 if (lpfc_ncmd->ts_cmd_start < lpfc_ncmd->ts_last_cmd)
663 return;
664 if (lpfc_ncmd->ts_cmd_wqput < lpfc_ncmd->ts_cmd_start)
665 return;
666 if (lpfc_ncmd->ts_isr_cmpl < lpfc_ncmd->ts_cmd_wqput)
667 return;
668 if (lpfc_ncmd->ts_data_nvme < lpfc_ncmd->ts_isr_cmpl)
669 return;
670 /*
671 * Segment 1 - Time from Last FCP command cmpl is handed
672 * off to NVME Layer to start of next command.
673 * Segment 2 - Time from Driver receives a IO cmd start
674 * from NVME Layer to WQ put is done on IO cmd.
675 * Segment 3 - Time from Driver WQ put is done on IO cmd
676 * to MSI-X ISR for IO cmpl.
677 * Segment 4 - Time from MSI-X ISR for IO cmpl to when
678 * cmpl is handled off to the NVME Layer.
679 */
680 seg1 = lpfc_ncmd->ts_cmd_start - lpfc_ncmd->ts_last_cmd;
681 if (seg1 > 5000000) /* 5 ms - for sequential IOs */
682 return;
683
684 /* Calculate times relative to start of IO */
685 seg2 = (lpfc_ncmd->ts_cmd_wqput - lpfc_ncmd->ts_cmd_start);
686 seg3 = (lpfc_ncmd->ts_isr_cmpl -
687 lpfc_ncmd->ts_cmd_start) - seg2;
688 seg4 = (lpfc_ncmd->ts_data_nvme -
689 lpfc_ncmd->ts_cmd_start) - seg2 - seg3;
690 phba->ktime_data_samples++;
691 phba->ktime_seg1_total += seg1;
692 if (seg1 < phba->ktime_seg1_min)
693 phba->ktime_seg1_min = seg1;
694 else if (seg1 > phba->ktime_seg1_max)
695 phba->ktime_seg1_max = seg1;
696 phba->ktime_seg2_total += seg2;
697 if (seg2 < phba->ktime_seg2_min)
698 phba->ktime_seg2_min = seg2;
699 else if (seg2 > phba->ktime_seg2_max)
700 phba->ktime_seg2_max = seg2;
701 phba->ktime_seg3_total += seg3;
702 if (seg3 < phba->ktime_seg3_min)
703 phba->ktime_seg3_min = seg3;
704 else if (seg3 > phba->ktime_seg3_max)
705 phba->ktime_seg3_max = seg3;
706 phba->ktime_seg4_total += seg4;
707 if (seg4 < phba->ktime_seg4_min)
708 phba->ktime_seg4_min = seg4;
709 else if (seg4 > phba->ktime_seg4_max)
710 phba->ktime_seg4_max = seg4;
711
712 lpfc_ncmd->ts_last_cmd = 0;
713 lpfc_ncmd->ts_cmd_start = 0;
714 lpfc_ncmd->ts_cmd_wqput = 0;
715 lpfc_ncmd->ts_isr_cmpl = 0;
716 lpfc_ncmd->ts_data_nvme = 0;
717}
718#endif
719
640/** 720/**
641 * lpfc_nvme_io_cmd_wqe_cmpl - Complete an NVME-over-FCP IO 721 * lpfc_nvme_io_cmd_wqe_cmpl - Complete an NVME-over-FCP IO
642 * @lpfc_pnvme: Pointer to the driver's nvme instance data 722 * @lpfc_pnvme: Pointer to the driver's nvme instance data
@@ -680,6 +760,9 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,
680 nCmd = lpfc_ncmd->nvmeCmd; 760 nCmd = lpfc_ncmd->nvmeCmd;
681 rport = lpfc_ncmd->nrport; 761 rport = lpfc_ncmd->nrport;
682 762
763 lpfc_nvmeio_data(phba, "NVME FCP CMPL: xri x%x stat x%x parm x%x\n",
764 lpfc_ncmd->cur_iocbq.sli4_xritag,
765 bf_get(lpfc_wcqe_c_status, wcqe), wcqe->parameter);
683 /* 766 /*
684 * Catch race where our node has transitioned, but the 767 * Catch race where our node has transitioned, but the
685 * transport is still transitioning. 768 * transport is still transitioning.
@@ -798,6 +881,23 @@ out_err:
798 * no need for dma unprep because the nvme_transport 881 * no need for dma unprep because the nvme_transport
799 * owns the dma address. 882 * owns the dma address.
800 */ 883 */
884#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
885 if (phba->ktime_on) {
886 lpfc_ncmd->ts_isr_cmpl = pwqeIn->isr_timestamp;
887 lpfc_ncmd->ts_data_nvme = ktime_get_ns();
888 phba->ktime_last_cmd = lpfc_ncmd->ts_data_nvme;
889 lpfc_nvme_ktime(phba, lpfc_ncmd);
890 }
891 if (phba->cpucheck_on & LPFC_CHECK_NVME_IO) {
892 if (lpfc_ncmd->cpu != smp_processor_id())
893 lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_IOERR,
894 "6701 CPU Check cmpl: "
895 "cpu %d expect %d\n",
896 smp_processor_id(), lpfc_ncmd->cpu);
897 if (lpfc_ncmd->cpu < LPFC_CHECK_CPU_CNT)
898 phba->cpucheck_cmpl_io[lpfc_ncmd->cpu]++;
899 }
900#endif
801 nCmd->done(nCmd); 901 nCmd->done(nCmd);
802 902
803 spin_lock_irqsave(&phba->hbalock, flags); 903 spin_lock_irqsave(&phba->hbalock, flags);
@@ -1103,11 +1203,18 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
1103 struct lpfc_nvme_buf *lpfc_ncmd; 1203 struct lpfc_nvme_buf *lpfc_ncmd;
1104 struct lpfc_nvme_rport *rport; 1204 struct lpfc_nvme_rport *rport;
1105 struct lpfc_nvme_qhandle *lpfc_queue_info; 1205 struct lpfc_nvme_qhandle *lpfc_queue_info;
1206#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1207 uint64_t start = 0;
1208#endif
1106 1209
1107 lport = (struct lpfc_nvme_lport *)pnvme_lport->private; 1210 lport = (struct lpfc_nvme_lport *)pnvme_lport->private;
1108 vport = lport->vport; 1211 vport = lport->vport;
1109 phba = vport->phba; 1212 phba = vport->phba;
1110 1213
1214#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1215 if (phba->ktime_on)
1216 start = ktime_get_ns();
1217#endif
1111 rport = (struct lpfc_nvme_rport *)pnvme_rport->private; 1218 rport = (struct lpfc_nvme_rport *)pnvme_rport->private;
1112 lpfc_queue_info = (struct lpfc_nvme_qhandle *)hw_queue_handle; 1219 lpfc_queue_info = (struct lpfc_nvme_qhandle *)hw_queue_handle;
1113 1220
@@ -1161,6 +1268,12 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
1161 ret = -ENOMEM; 1268 ret = -ENOMEM;
1162 goto out_fail; 1269 goto out_fail;
1163 } 1270 }
1271#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1272 if (phba->ktime_on) {
1273 lpfc_ncmd->ts_cmd_start = start;
1274 lpfc_ncmd->ts_last_cmd = phba->ktime_last_cmd;
1275 }
1276#endif
1164 1277
1165 /* 1278 /*
1166 * Store the data needed by the driver to issue, abort, and complete 1279 * Store the data needed by the driver to issue, abort, and complete
@@ -1192,6 +1305,10 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
1192 */ 1305 */
1193 lpfc_ncmd->cur_iocbq.hba_wqidx = lpfc_queue_info->index; 1306 lpfc_ncmd->cur_iocbq.hba_wqidx = lpfc_queue_info->index;
1194 1307
1308 lpfc_nvmeio_data(phba, "NVME FCP XMIT: xri x%x idx %d to %06x\n",
1309 lpfc_ncmd->cur_iocbq.sli4_xritag,
1310 lpfc_queue_info->index, ndlp->nlp_DID);
1311
1195 ret = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, &lpfc_ncmd->cur_iocbq); 1312 ret = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, &lpfc_ncmd->cur_iocbq);
1196 if (ret) { 1313 if (ret) {
1197 atomic_dec(&ndlp->cmd_pending); 1314 atomic_dec(&ndlp->cmd_pending);
@@ -1204,6 +1321,28 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
1204 goto out_free_nvme_buf; 1321 goto out_free_nvme_buf;
1205 } 1322 }
1206 1323
1324#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1325 if (phba->ktime_on)
1326 lpfc_ncmd->ts_cmd_wqput = ktime_get_ns();
1327
1328 if (phba->cpucheck_on & LPFC_CHECK_NVME_IO) {
1329 lpfc_ncmd->cpu = smp_processor_id();
1330 if (lpfc_ncmd->cpu != lpfc_queue_info->index) {
1331 /* Check for admin queue */
1332 if (lpfc_queue_info->qidx) {
1333 lpfc_printf_vlog(vport,
1334 KERN_ERR, LOG_NVME_IOERR,
1335 "6702 CPU Check cmd: "
1336 "cpu %d wq %d\n",
1337 lpfc_ncmd->cpu,
1338 lpfc_queue_info->index);
1339 }
1340 lpfc_ncmd->cpu = lpfc_queue_info->index;
1341 }
1342 if (lpfc_ncmd->cpu < LPFC_CHECK_CPU_CNT)
1343 phba->cpucheck_xmt_io[lpfc_ncmd->cpu]++;
1344 }
1345#endif
1207 return 0; 1346 return 0;
1208 1347
1209 out_free_nvme_buf: 1348 out_free_nvme_buf:
@@ -1377,6 +1516,10 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport,
1377 return; 1516 return;
1378 } 1517 }
1379 1518
1519 lpfc_nvmeio_data(phba, "NVME FCP ABORT: xri x%x idx %d to %06x\n",
1520 nvmereq_wqe->sli4_xritag,
1521 nvmereq_wqe->hba_wqidx, ndlp->nlp_DID);
1522
1380 /* Outstanding abort is in progress */ 1523 /* Outstanding abort is in progress */
1381 if (nvmereq_wqe->iocb_flag & LPFC_DRIVER_ABORTED) { 1524 if (nvmereq_wqe->iocb_flag & LPFC_DRIVER_ABORTED) {
1382 spin_unlock_irqrestore(&phba->hbalock, flags); 1525 spin_unlock_irqrestore(&phba->hbalock, flags);
diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h
index 4cc51086a5f7..85961c1ddecf 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.h
+++ b/drivers/scsi/lpfc/lpfc_nvme.h
@@ -91,4 +91,11 @@ struct lpfc_nvme_buf {
91 91
92 wait_queue_head_t *waitq; 92 wait_queue_head_t *waitq;
93 unsigned long start_time; 93 unsigned long start_time;
94#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
95 uint64_t ts_cmd_start;
96 uint64_t ts_last_cmd;
97 uint64_t ts_cmd_wqput;
98 uint64_t ts_isr_cmpl;
99 uint64_t ts_data_nvme;
100#endif
94}; 101};
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index ccda1f73ae84..5f6ad67d5a73 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -13299,6 +13299,11 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id)
13299 if (unlikely(!fpeq)) 13299 if (unlikely(!fpeq))
13300 return IRQ_NONE; 13300 return IRQ_NONE;
13301 13301
13302#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
13303 if (phba->ktime_on)
13304 fpeq->isr_timestamp = ktime_get_ns();
13305#endif
13306
13302 if (lpfc_fcp_look_ahead) { 13307 if (lpfc_fcp_look_ahead) {
13303 if (atomic_dec_and_test(&hba_eq_hdl->hba_eq_in_use)) 13308 if (atomic_dec_and_test(&hba_eq_hdl->hba_eq_in_use))
13304 lpfc_sli4_eq_clr_intr(fpeq); 13309 lpfc_sli4_eq_clr_intr(fpeq);