2019-05-12 07:35:42

by Minwoo Im

[permalink] [raw]
Subject: [PATCH V3 0/5] nvme-trace: Add support for fabrics command

Hi,

Here's a third patchset to support fabrics command tracing. The first
patch updated host/trace module to a outside of it to provide common
interfaces for host and target both. The second one adds support for
tracing fabrics command from host-side. The third is a trivial clean-up
for providing a helper function to figure out given command structure is
for fabrics or not.

The fourth and fifth are the major change points of this patchset. 4th
patch adds request tracing from the target-side. 5th updated, of course,
completion of given request.

Please review.
Thanks,

Changes to V2:
- Provide a common code for both host and target. (Chaitanya)
- Add support for tracing requests in target-side (Chaitanya)
- Make it simple in trace.h without branch out from nvme core module
(Christoph)

Changes to V1:
- fabrics commands should also be decoded, not just showing that it's
a fabrics command. (Christoph)
- do not make it within nvme admin commands (Chaitanya)

Minwoo Im (5):
nvme: Make trace common for host and target both
nvme-trace: Support tracing fabrics commands from host-side
nvme: Introduce nvme_is_fabrics to check fabrics cmd
nvme-trace: Add tracing for req_init in trarget
nvme-trace: Add tracing for req_comp in target

MAINTAINERS | 2 +
drivers/nvme/Makefile | 3 +
drivers/nvme/host/Makefile | 1 -
drivers/nvme/host/core.c | 7 +-
drivers/nvme/host/fabrics.c | 2 +-
drivers/nvme/host/pci.c | 2 +-
drivers/nvme/target/core.c | 8 +-
drivers/nvme/target/fabrics-cmd.c | 2 +-
drivers/nvme/target/fc.c | 2 +-
drivers/nvme/target/nvmet.h | 9 ++
drivers/nvme/{host => }/trace.c | 75 ++++++++++++++++
drivers/nvme/{host => }/trace.h | 144 ++++++++++++++++++++++++------
include/linux/nvme.h | 7 +-
13 files changed, 227 insertions(+), 37 deletions(-)
rename drivers/nvme/{host => }/trace.c (65%)
rename drivers/nvme/{host => }/trace.h (59%)

--
2.17.1


2019-05-12 07:35:56

by Minwoo Im

[permalink] [raw]
Subject: [PATCH V3 1/5] nvme: Make trace common for host and target both

To support target-side trace, nvme-trace should be commonized for host
and target both. Of course, not every single tracepoints are necessary
by both of them, but we don't need to have more than one trace module
for host and target.

Cc: Keith Busch <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: James Smart <[email protected]>
Signed-off-by: Minwoo Im <[email protected]>
---
MAINTAINERS | 2 ++
drivers/nvme/Makefile | 3 +++
drivers/nvme/host/Makefile | 1 -
drivers/nvme/host/core.c | 3 +--
drivers/nvme/host/pci.c | 2 +-
drivers/nvme/{host => }/trace.c | 5 +++++
drivers/nvme/{host => }/trace.h | 2 +-
7 files changed, 13 insertions(+), 5 deletions(-)
rename drivers/nvme/{host => }/trace.c (95%)
rename drivers/nvme/{host => }/trace.h (99%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 09f43f1bdd15..5974cadafcf7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11084,6 +11084,7 @@ L: [email protected]
T: git://git.infradead.org/nvme.git
W: http://git.infradead.org/nvme.git
S: Supported
+F: drivers/nvme/
F: drivers/nvme/host/
F: include/linux/nvme.h
F: include/uapi/linux/nvme_ioctl.h
@@ -11105,6 +11106,7 @@ L: [email protected]
T: git://git.infradead.org/nvme.git
W: http://git.infradead.org/nvme.git
S: Supported
+F: drivers/nvme/
F: drivers/nvme/target/

NVMEM FRAMEWORK
diff --git a/drivers/nvme/Makefile b/drivers/nvme/Makefile
index 0096a7fd1431..12f193502d46 100644
--- a/drivers/nvme/Makefile
+++ b/drivers/nvme/Makefile
@@ -1,3 +1,6 @@

+ccflags-y += -I$(src)
+obj-$(CONFIG_TRACING) += trace.o
+
obj-y += host/
obj-y += target/
diff --git a/drivers/nvme/host/Makefile b/drivers/nvme/host/Makefile
index 8a4b671c5f0c..46453352bfa0 100644
--- a/drivers/nvme/host/Makefile
+++ b/drivers/nvme/host/Makefile
@@ -10,7 +10,6 @@ obj-$(CONFIG_NVME_FC) += nvme-fc.o
obj-$(CONFIG_NVME_TCP) += nvme-tcp.o

nvme-core-y := core.o
-nvme-core-$(CONFIG_TRACING) += trace.o
nvme-core-$(CONFIG_NVME_MULTIPATH) += multipath.o
nvme-core-$(CONFIG_NVM) += lightnvm.o
nvme-core-$(CONFIG_FAULT_INJECTION_DEBUG_FS) += fault_inject.o
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index eebaeadaa800..ae76c0b78a5f 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -21,8 +21,7 @@
#include <linux/pm_qos.h>
#include <asm/unaligned.h>

-#define CREATE_TRACE_POINTS
-#include "trace.h"
+#include "../trace.h"

#include "nvme.h"
#include "fabrics.h"
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 2a8708c9ac18..d90b66543d25 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -24,7 +24,7 @@
#include <linux/sed-opal.h>
#include <linux/pci-p2pdma.h>

-#include "trace.h"
+#include "../trace.h"
#include "nvme.h"

#define SQ_SIZE(depth) (depth * sizeof(struct nvme_command))
diff --git a/drivers/nvme/host/trace.c b/drivers/nvme/trace.c
similarity index 95%
rename from drivers/nvme/host/trace.c
rename to drivers/nvme/trace.c
index 5f24ea7a28eb..a2c8186d122d 100644
--- a/drivers/nvme/host/trace.c
+++ b/drivers/nvme/trace.c
@@ -5,6 +5,8 @@
*/

#include <asm/unaligned.h>
+
+#define CREATE_TRACE_POINTS
#include "trace.h"

static const char *nvme_trace_create_sq(struct trace_seq *p, u8 *cdw10)
@@ -147,4 +149,7 @@ const char *nvme_trace_disk_name(struct trace_seq *p, char *name)
}
EXPORT_SYMBOL_GPL(nvme_trace_disk_name);

+EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_setup_cmd);
+EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_complete_rq);
+EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_async_event);
EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_sq);
diff --git a/drivers/nvme/host/trace.h b/drivers/nvme/trace.h
similarity index 99%
rename from drivers/nvme/host/trace.h
rename to drivers/nvme/trace.h
index 97d3c77365b8..acf10c7a5bef 100644
--- a/drivers/nvme/host/trace.h
+++ b/drivers/nvme/trace.h
@@ -14,7 +14,7 @@
#include <linux/tracepoint.h>
#include <linux/trace_seq.h>

-#include "nvme.h"
+#include "host/nvme.h"

#define nvme_admin_opcode_name(opcode) { opcode, #opcode }
#define show_admin_opcode_name(val) \
--
2.17.1

2019-05-12 07:36:28

by Minwoo Im

[permalink] [raw]
Subject: [PATCH V3 3/5] nvme: Introduce nvme_is_fabrics to check fabrics cmd

This patch introduce a nvme_is_fabrics() inline function to check
whether or not the given command structure is for fabrics.

Cc: Keith Busch <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: James Smart <[email protected]>
Signed-off-by: Minwoo Im <[email protected]>
---
drivers/nvme/host/fabrics.c | 2 +-
drivers/nvme/target/core.c | 2 +-
drivers/nvme/target/fabrics-cmd.c | 2 +-
drivers/nvme/target/fc.c | 2 +-
include/linux/nvme.h | 7 ++++++-
5 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index 592d1e61ef7e..931995f2dbc3 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -578,7 +578,7 @@ bool __nvmf_check_ready(struct nvme_ctrl *ctrl, struct request *rq,
switch (ctrl->state) {
case NVME_CTRL_NEW:
case NVME_CTRL_CONNECTING:
- if (req->cmd->common.opcode == nvme_fabrics_command &&
+ if (nvme_is_fabrics(req->cmd) &&
req->cmd->fabrics.fctype == nvme_fabrics_type_connect)
return true;
break;
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 7734a6acff85..da2ea97042af 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -871,7 +871,7 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
status = nvmet_parse_connect_cmd(req);
else if (likely(req->sq->qid != 0))
status = nvmet_parse_io_cmd(req);
- else if (req->cmd->common.opcode == nvme_fabrics_command)
+ else if (nvme_is_fabrics(req->cmd))
status = nvmet_parse_fabrics_cmd(req);
else if (req->sq->ctrl->subsys->type == NVME_NQN_DISC)
status = nvmet_parse_discovery_cmd(req);
diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c
index 3b9f79aba98f..d16b55ffe79f 100644
--- a/drivers/nvme/target/fabrics-cmd.c
+++ b/drivers/nvme/target/fabrics-cmd.c
@@ -268,7 +268,7 @@ u16 nvmet_parse_connect_cmd(struct nvmet_req *req)
{
struct nvme_command *cmd = req->cmd;

- if (cmd->common.opcode != nvme_fabrics_command) {
+ if (!nvme_is_fabrics(cmd)) {
pr_err("invalid command 0x%x on unconnected queue.\n",
cmd->fabrics.opcode);
req->error_loc = offsetof(struct nvme_common_command, opcode);
diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c
index 508661af0f50..a59c5a013a5c 100644
--- a/drivers/nvme/target/fc.c
+++ b/drivers/nvme/target/fc.c
@@ -1806,7 +1806,7 @@ nvmet_fc_prep_fcp_rsp(struct nvmet_fc_tgtport *tgtport,
*/
rspcnt = atomic_inc_return(&fod->queue->zrspcnt);
if (!(rspcnt % fod->queue->ersp_ratio) ||
- sqe->opcode == nvme_fabrics_command ||
+ nvme_is_fabrics((struct nvme_command *) sqe) ||
xfr_length != fod->req.transfer_len ||
(le16_to_cpu(cqe->status) & 0xFFFE) || cqewd[0] || cqewd[1] ||
(sqe->flags & (NVME_CMD_FUSE_FIRST | NVME_CMD_FUSE_SECOND)) ||
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index c40720cb59ac..ab5e9392b42d 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -1165,6 +1165,11 @@ struct nvme_command {
};
};

+static inline bool nvme_is_fabrics(struct nvme_command *cmd)
+{
+ return cmd->common.opcode == nvme_fabrics_command;
+}
+
struct nvme_error_slot {
__le64 error_count;
__le16 sqid;
@@ -1186,7 +1191,7 @@ static inline bool nvme_is_write(struct nvme_command *cmd)
*
* Why can't we simply have a Fabrics In and Fabrics out command?
*/
- if (unlikely(cmd->common.opcode == nvme_fabrics_command))
+ if (unlikely(nvme_is_fabrics(cmd)))
return cmd->fabrics.fctype & 1;
return cmd->common.opcode & 1;
}
--
2.17.1

2019-05-12 07:36:59

by Minwoo Im

[permalink] [raw]
Subject: [PATCH V3 4/5] nvme-trace: Add tracing for req_init in trarget

We can have the common tracing code with different event entries.
- nvme_setup_cmd
- nvmet_req_init

This patch updates existing TRACE_EVENT to a template to provide a
common tracing interface. More than that, nvme_setup_cmd entry point
has been defined as an event referring template made.

It also introduces tracing at the point of request creation for the
target system. This might be useful to figure out what kind of
request has been received in the target.

Here's the example of target tracing introduced with RDMA:
kworker/0:1H-1043 [000] .... 276.785946: nvmet_req_init: nvme0: qid=0, cmdid=0, nsid=1, flags=0x40, meta=0x0, cmd=(nvme_fabrics_type_connect recfmt=0, qid=0, sqsize=31, cattr=0, kato=0)
kworker/0:1H-1043 [000] .... 276.789893: nvmet_req_init: nvme1: qid=0, cmdid=10, nsid=4, flags=0x40, meta=0x0, cmd=(nvme_fabrics_type_property_get attrib=1, ofst=0x0)
kworker/0:1H-1043 [000] .... 276.791781: nvmet_req_init: nvme1: qid=0, cmdid=11, nsid=0, flags=0x40, meta=0x0, cmd=(nvme_fabrics_type_property_set attrib=0, ofst=0x14, value=0x460001)
kworker/0:1H-1043 [000] .... 276.794799: nvmet_req_init: nvme1: qid=0, cmdid=12, nsid=4, flags=0x40, meta=0x0, cmd=(nvme_fabrics_type_property_get attrib=0, ofst=0x1c)
kworker/0:1H-1043 [000] .... 276.796804: nvmet_req_init: nvme1: qid=0, cmdid=13, nsid=4, flags=0x40, meta=0x0, cmd=(nvme_fabrics_type_property_get attrib=0, ofst=0x8)
kworker/0:1H-1043 [000] .... 276.799163: nvmet_req_init: nvme1: qid=0, cmdid=10, nsid=4, flags=0x40, meta=0x0, cmd=(nvme_fabrics_type_property_get attrib=1, ofst=0x0)
kworker/0:1H-1043 [000] .... 276.801070: nvmet_req_init: nvme1: qid=0, cmdid=11, nsid=0, flags=0x40, meta=0x0, cmd=(nvme_admin_identify cns=1, ctrlid=0)
kworker/0:1H-1043 [000] .... 276.817592: nvmet_req_init: nvme1: qid=0, cmdid=12, nsid=0, flags=0x40, meta=0x0, cmd=(nvme_admin_get_log_page cdw10=70 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
kworker/0:1H-1043 [000] .... 276.822963: nvmet_req_init: nvme1: qid=0, cmdid=13, nsid=0, flags=0x40, meta=0x0, cmd=(nvme_admin_get_log_page cdw10=70 00 ff 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
kworker/0:1H-1043 [000] .... 276.831908: nvmet_req_init: nvme1: qid=0, cmdid=10, nsid=0, flags=0x40, meta=0x0, cmd=(nvme_admin_get_log_page cdw10=70 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)

Cc: Keith Busch <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: James Smart <[email protected]>
Signed-off-by: Minwoo Im <[email protected]>
---
drivers/nvme/host/core.c | 2 +-
drivers/nvme/target/core.c | 3 +++
drivers/nvme/target/nvmet.h | 9 +++++++
drivers/nvme/trace.c | 2 ++
drivers/nvme/trace.h | 50 ++++++++++++++++++++++++++++++++-----
5 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index ae76c0b78a5f..39e49e9948c3 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -732,7 +732,7 @@ blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req,
}

cmd->common.command_id = req->tag;
- trace_nvme_setup_cmd(req, cmd);
+ trace_nvme_setup_cmd(NVME_TRACE_HOST, req, cmd);
return ret;
}
EXPORT_SYMBOL_GPL(nvme_setup_cmd);
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index da2ea97042af..10b3b3767f91 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -10,6 +10,7 @@
#include <linux/pci-p2pdma.h>
#include <linux/scatterlist.h>

+#include "../trace.h"
#include "nvmet.h"

struct workqueue_struct *buffered_io_wq;
@@ -848,6 +849,8 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
req->error_loc = NVMET_NO_ERROR_LOC;
req->error_slba = 0;

+ trace_nvmet_req_init(NVME_TRACE_TARGET, req, req->cmd);
+
/* no support for fused commands yet */
if (unlikely(flags & (NVME_CMD_FUSE_FIRST | NVME_CMD_FUSE_SECOND))) {
req->error_loc = offsetof(struct nvme_common_command, flags);
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index c25d88fc9dec..2d569a1dc3f4 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -318,6 +318,15 @@ struct nvmet_req {
u64 error_slba;
};

+static inline struct nvmet_ctrl *nvmet_req_to_ctrl(struct nvmet_req *req)
+{
+ struct nvmet_sq *sq = req->sq;
+
+ if (sq)
+ return sq->ctrl;
+ return NULL;
+}
+
extern struct workqueue_struct *buffered_io_wq;

static inline void nvmet_set_result(struct nvmet_req *req, u32 result)
diff --git a/drivers/nvme/trace.c b/drivers/nvme/trace.c
index 88dfadb68b92..8fe2dcee6a42 100644
--- a/drivers/nvme/trace.c
+++ b/drivers/nvme/trace.c
@@ -220,3 +220,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_setup_cmd);
EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_complete_rq);
EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_async_event);
EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_sq);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(nvmet_req_init);
diff --git a/drivers/nvme/trace.h b/drivers/nvme/trace.h
index 7fbfd6cb815c..afda9c2ab4a1 100644
--- a/drivers/nvme/trace.h
+++ b/drivers/nvme/trace.h
@@ -15,6 +15,7 @@
#include <linux/trace_seq.h>

#include "host/nvme.h"
+#include "target/nvmet.h"

#define nvme_admin_opcode_name(opcode) { opcode, #opcode }
#define show_admin_opcode_name(val) \
@@ -103,11 +104,17 @@ static inline void __assign_disk_name(char *name, struct gendisk *disk)
else
memset(name, 0, DISK_NAME_LEN);
}
+
+enum nvme_trace_type {
+ NVME_TRACE_HOST,
+ NVME_TRACE_TARGET,
+};
#endif

-TRACE_EVENT(nvme_setup_cmd,
- TP_PROTO(struct request *req, struct nvme_command *cmd),
- TP_ARGS(req, cmd),
+DECLARE_EVENT_CLASS(nvme__cmd_begin,
+ TP_PROTO(enum nvme_trace_type type, void *req,
+ struct nvme_command *cmd),
+ TP_ARGS(type, req, cmd),
TP_STRUCT__entry(
__array(char, disk, DISK_NAME_LEN)
__field(int, ctrl_id)
@@ -121,15 +128,28 @@ TRACE_EVENT(nvme_setup_cmd,
__array(u8, cdw10, 24)
),
TP_fast_assign(
- __entry->ctrl_id = nvme_req(req)->ctrl->instance;
- __entry->qid = nvme_req_qid(req);
+ if (type != NVME_TRACE_TARGET) {
+ __entry->ctrl_id = nvme_req(req)->ctrl->instance;
+ __entry->qid = nvme_req_qid(req);
+ __assign_disk_name(__entry->disk,
+ ((struct request *) req)->rq_disk);
+ } else {
+ struct nvmet_ctrl *ctrl = nvmet_req_to_ctrl(req);
+ struct nvmet_sq *sq = ((struct nvmet_req *) req)->sq;
+ struct nvmet_ns *ns = ((struct nvmet_req *) req)->ns;
+
+ __entry->ctrl_id = ctrl ? ctrl->cntlid : 0;
+ __entry->qid = sq ? sq->qid : 0;
+ __assign_disk_name(__entry->disk, ns ?
+ ns->bdev->bd_disk : NULL);
+ }
+
__entry->opcode = cmd->common.opcode;
__entry->flags = cmd->common.flags;
__entry->cid = cmd->common.command_id;
__entry->nsid = le32_to_cpu(cmd->common.nsid);
__entry->fctype = __entry->nsid & 0xff;
__entry->metadata = le64_to_cpu(cmd->common.metadata);
- __assign_disk_name(__entry->disk, req->rq_disk);
memcpy(__entry->cdw10, &cmd->common.cdw10,
sizeof(__entry->cdw10));
),
@@ -143,6 +163,24 @@ TRACE_EVENT(nvme_setup_cmd,
__entry->fctype, __entry->cdw10))
);

+/*
+ * @req: (struct request *) req needs to be here for nvme common commands
+ */
+DEFINE_EVENT(nvme__cmd_begin, nvme_setup_cmd,
+ TP_PROTO(enum nvme_trace_type type, void *req,
+ struct nvme_command *cmd),
+ TP_ARGS(type, req, cmd)
+);
+
+/*
+ * @req: (struct nvmet_req *) req needs to be here for nvme fabrics commands
+ */
+DEFINE_EVENT(nvme__cmd_begin, nvmet_req_init,
+ TP_PROTO(enum nvme_trace_type type, void *req,
+ struct nvme_command *cmd),
+ TP_ARGS(type, req, cmd)
+);
+
TRACE_EVENT(nvme_complete_rq,
TP_PROTO(struct request *req),
TP_ARGS(req),
--
2.17.1

2019-05-12 07:37:59

by Minwoo Im

[permalink] [raw]
Subject: [PATCH V3 5/5] nvme-trace: Add tracing for req_comp in target

We can have the common tracing code with different event entries.
- nvme_complete_rq
- nvmet_req_complete

This patch updates existing TRACE_EVENT to a template to provide a
common tracing interface.

We can have it as a common code because most of the fields need to be
printed out for both host and target system.

Cc: Keith Busch <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: James Smart <[email protected]>
Signed-off-by: Minwoo Im <[email protected]>
---
drivers/nvme/host/core.c | 2 +-
drivers/nvme/target/core.c | 3 +++
drivers/nvme/trace.c | 1 +
drivers/nvme/trace.h | 51 ++++++++++++++++++++++++++++++--------
4 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 39e49e9948c3..f377ed039a83 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -260,7 +260,7 @@ void nvme_complete_rq(struct request *req)
{
blk_status_t status = nvme_error_status(req);

- trace_nvme_complete_rq(req);
+ trace_nvme_complete_rq(NVME_TRACE_HOST, req);

if (nvme_req(req)->ctrl->kas)
nvme_req(req)->ctrl->comp_seen = true;
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 10b3b3767f91..0f184abe432f 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -690,6 +690,9 @@ static void __nvmet_req_complete(struct nvmet_req *req, u16 status)

if (unlikely(status))
nvmet_set_error(req, status);
+
+ trace_nvmet_req_complete(NVME_TRACE_TARGET, req);
+
if (req->ns)
nvmet_put_namespace(req->ns);
req->ops->queue_response(req);
diff --git a/drivers/nvme/trace.c b/drivers/nvme/trace.c
index 8fe2dcee6a42..8071b60ec71d 100644
--- a/drivers/nvme/trace.c
+++ b/drivers/nvme/trace.c
@@ -222,3 +222,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_async_event);
EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_sq);

EXPORT_TRACEPOINT_SYMBOL_GPL(nvmet_req_init);
+EXPORT_TRACEPOINT_SYMBOL_GPL(nvmet_req_complete);
diff --git a/drivers/nvme/trace.h b/drivers/nvme/trace.h
index afda9c2ab4a1..0674bb85ac66 100644
--- a/drivers/nvme/trace.h
+++ b/drivers/nvme/trace.h
@@ -181,9 +181,9 @@ DEFINE_EVENT(nvme__cmd_begin, nvmet_req_init,
TP_ARGS(type, req, cmd)
);

-TRACE_EVENT(nvme_complete_rq,
- TP_PROTO(struct request *req),
- TP_ARGS(req),
+DECLARE_EVENT_CLASS(nvme__cmd_end,
+ TP_PROTO(enum nvme_trace_type type, void *req),
+ TP_ARGS(type, req),
TP_STRUCT__entry(
__array(char, disk, DISK_NAME_LEN)
__field(int, ctrl_id)
@@ -195,20 +195,49 @@ TRACE_EVENT(nvme_complete_rq,
__field(u16, status)
),
TP_fast_assign(
- __entry->ctrl_id = nvme_req(req)->ctrl->instance;
- __entry->qid = nvme_req_qid(req);
- __entry->cid = req->tag;
- __entry->result = le64_to_cpu(nvme_req(req)->result.u64);
- __entry->retries = nvme_req(req)->retries;
- __entry->flags = nvme_req(req)->flags;
- __entry->status = nvme_req(req)->status;
- __assign_disk_name(__entry->disk, req->rq_disk);
+ if (type != NVME_TRACE_TARGET) {
+ struct request *req = (struct request *) req;
+
+ __entry->ctrl_id = nvme_req(req)->ctrl->instance;
+ __entry->qid = nvme_req_qid(req);
+ __entry->cid = req->tag;
+ __entry->result =
+ le64_to_cpu(nvme_req(req)->result.u64);
+ __entry->retries = nvme_req(req)->retries;
+ __entry->flags = nvme_req(req)->flags;
+ __entry->status = nvme_req(req)->status;
+ __assign_disk_name(__entry->disk, req->rq_disk);
+ } else {
+ struct nvmet_ctrl *ctrl = nvmet_req_to_ctrl(req);
+ struct nvmet_cq *cq = ((struct nvmet_req *) req)->cq;
+ struct nvme_completion *cqe =
+ ((struct nvmet_req *) req)->cqe;
+ struct nvmet_ns *ns = ((struct nvmet_req *) req)->ns;
+
+ __entry->ctrl_id = ctrl ? ctrl->cntlid : 0;
+ __entry->qid = cq->qid;
+ __entry->cid = cqe->command_id;
+ __entry->result = cqe->result.u64;
+ __entry->flags = 0;
+ __entry->status = cqe->status >> 1;
+ __assign_disk_name(__entry->disk, ns ?
+ ns->bdev->bd_disk : NULL);
+ }
),
TP_printk("nvme%d: %sqid=%d, cmdid=%u, res=%llu, retries=%u, flags=0x%x, status=%u",
__entry->ctrl_id, __print_disk_name(__entry->disk),
__entry->qid, __entry->cid, __entry->result,
__entry->retries, __entry->flags, __entry->status)
+);
+
+DEFINE_EVENT(nvme__cmd_end, nvme_complete_rq,
+ TP_PROTO(enum nvme_trace_type type, void *req),
+ TP_ARGS(type, req)
+);

+DEFINE_EVENT(nvme__cmd_end, nvmet_req_complete,
+ TP_PROTO(enum nvme_trace_type type, void *req),
+ TP_ARGS(type, req)
);

#define aer_name(aer) { aer, #aer }
--
2.17.1

2019-05-12 07:38:07

by Minwoo Im

[permalink] [raw]
Subject: [PATCH V3 2/5] nvme-trace: Support tracing fabrics commands from host-side

This patch adds support for tracing fabrics commands detected from
host-side. We can have trace_nvme_setup_cmd for nvme and nvme fabrics
both even fabrics submission queue entry does not have valid fields in
where nvme's fields are valid.

This patch modifies existing parse_nvme_cmd to have fctype as an
argument to support fabrics command which will be ignored in case of
nvme common case.

Cc: Keith Busch <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: James Smart <[email protected]>
Signed-off-by: Minwoo Im <[email protected]>
---
drivers/nvme/trace.c | 67 ++++++++++++++++++++++++++++++++++++++++++++
drivers/nvme/trace.h | 41 +++++++++++++++++++++------
2 files changed, 100 insertions(+), 8 deletions(-)

diff --git a/drivers/nvme/trace.c b/drivers/nvme/trace.c
index a2c8186d122d..88dfadb68b92 100644
--- a/drivers/nvme/trace.c
+++ b/drivers/nvme/trace.c
@@ -137,6 +137,73 @@ const char *nvme_trace_parse_nvm_cmd(struct trace_seq *p,
}
}

+static const char *nvme_trace_fabrics_property_set(struct trace_seq *p, u8 *spc)
+{
+ const char *ret = trace_seq_buffer_ptr(p);
+ u8 attrib = spc[0];
+ u32 ofst = get_unaligned_le32(spc + 4);
+ u64 value = get_unaligned_le64(spc + 8);
+
+ trace_seq_printf(p, "attrib=%u, ofst=0x%x, value=0x%llx",
+ attrib, ofst, value);
+ trace_seq_putc(p, 0);
+
+ return ret;
+}
+
+static const char *nvme_trace_fabrics_connect(struct trace_seq *p, u8 *spc)
+{
+ const char *ret = trace_seq_buffer_ptr(p);
+ u16 recfmt = get_unaligned_le16(spc);
+ u16 qid = get_unaligned_le16(spc + 2);
+ u16 sqsize = get_unaligned_le16(spc + 4);
+ u8 cattr = spc[6];
+ u32 kato = get_unaligned_le32(spc + 8);
+
+ trace_seq_printf(p, "recfmt=%u, qid=%u, sqsize=%u, cattr=%u, kato=%u",
+ recfmt, qid, sqsize, cattr, kato);
+ trace_seq_putc(p, 0);
+
+ return ret;
+}
+
+static const char *nvme_trace_fabrics_property_get(struct trace_seq *p, u8 *spc)
+{
+ const char *ret = trace_seq_buffer_ptr(p);
+ u8 attrib = spc[0];
+ u32 ofst = get_unaligned_le32(spc + 4);
+
+ trace_seq_printf(p, "attrib=%u, ofst=0x%x", attrib, ofst);
+ trace_seq_putc(p, 0);
+
+ return ret;
+}
+
+static const char *nvme_trace_fabrics_common(struct trace_seq *p, u8 *spc)
+{
+ const char *ret = trace_seq_buffer_ptr(p);
+
+ trace_seq_printf(p, "spcecific=%*ph", 24, spc);
+ trace_seq_putc(p, 0);
+
+ return ret;
+}
+
+const char *nvme_trace_parse_fabrics_cmd(struct trace_seq *p,
+ u8 fctype, u8 *spc)
+{
+ switch (fctype) {
+ case nvme_fabrics_type_property_set:
+ return nvme_trace_fabrics_property_set(p, spc);
+ case nvme_fabrics_type_connect:
+ return nvme_trace_fabrics_connect(p, spc);
+ case nvme_fabrics_type_property_get:
+ return nvme_trace_fabrics_property_get(p, spc);
+ default:
+ return nvme_trace_fabrics_common(p, spc);
+ }
+}
+
const char *nvme_trace_disk_name(struct trace_seq *p, char *name)
{
const char *ret = trace_seq_buffer_ptr(p);
diff --git a/drivers/nvme/trace.h b/drivers/nvme/trace.h
index acf10c7a5bef..7fbfd6cb815c 100644
--- a/drivers/nvme/trace.h
+++ b/drivers/nvme/trace.h
@@ -57,18 +57,39 @@
nvme_opcode_name(nvme_cmd_resv_acquire), \
nvme_opcode_name(nvme_cmd_resv_release))

-#define show_opcode_name(qid, opcode) \
- (qid ? show_nvm_opcode_name(opcode) : show_admin_opcode_name(opcode))
+#define nvme_fabrics_type_name(type) { type, #type }
+#define show_fabrics_type_name(type) \
+ __print_symbolic(type, \
+ nvme_fabrics_type_name(nvme_fabrics_type_property_set), \
+ nvme_fabrics_type_name(nvme_fabrics_type_connect), \
+ nvme_fabrics_type_name(nvme_fabrics_type_property_get))
+
+/*
+ * If not fabrics, fctype will be ignored.
+ */
+#define show_opcode_name(qid, opcode, fctype) \
+ ((opcode != nvme_fabrics_command) ? \
+ (qid ? \
+ show_nvm_opcode_name(opcode) : \
+ show_admin_opcode_name(opcode)) : \
+ show_fabrics_type_name(fctype))

const char *nvme_trace_parse_admin_cmd(struct trace_seq *p, u8 opcode,
u8 *cdw10);
const char *nvme_trace_parse_nvm_cmd(struct trace_seq *p, u8 opcode,
u8 *cdw10);
+const char *nvme_trace_parse_fabrics_cmd(struct trace_seq *p,
+ u8 fctype, u8 *spc);

-#define parse_nvme_cmd(qid, opcode, cdw10) \
- (qid ? \
- nvme_trace_parse_nvm_cmd(p, opcode, cdw10) : \
- nvme_trace_parse_admin_cmd(p, opcode, cdw10))
+/*
+ * If not fabrics, fctype will be ignored.
+ */
+#define parse_nvme_cmd(qid, opcode, fctype, cdw10) \
+ ((opcode != nvme_fabrics_command) ? \
+ (qid ? \
+ nvme_trace_parse_nvm_cmd(p, opcode, cdw10) : \
+ nvme_trace_parse_admin_cmd(p, opcode, cdw10)) : \
+ nvme_trace_parse_fabrics_cmd(p, fctype, cdw10))

const char *nvme_trace_disk_name(struct trace_seq *p, char *name);
#define __print_disk_name(name) \
@@ -95,6 +116,7 @@ TRACE_EVENT(nvme_setup_cmd,
__field(u8, flags)
__field(u16, cid)
__field(u32, nsid)
+ __field(u8, fctype)
__field(u64, metadata)
__array(u8, cdw10, 24)
),
@@ -105,6 +127,7 @@ TRACE_EVENT(nvme_setup_cmd,
__entry->flags = cmd->common.flags;
__entry->cid = cmd->common.command_id;
__entry->nsid = le32_to_cpu(cmd->common.nsid);
+ __entry->fctype = __entry->nsid & 0xff;
__entry->metadata = le64_to_cpu(cmd->common.metadata);
__assign_disk_name(__entry->disk, req->rq_disk);
memcpy(__entry->cdw10, &cmd->common.cdw10,
@@ -114,8 +137,10 @@ TRACE_EVENT(nvme_setup_cmd,
__entry->ctrl_id, __print_disk_name(__entry->disk),
__entry->qid, __entry->cid, __entry->nsid,
__entry->flags, __entry->metadata,
- show_opcode_name(__entry->qid, __entry->opcode),
- parse_nvme_cmd(__entry->qid, __entry->opcode, __entry->cdw10))
+ show_opcode_name(__entry->qid, __entry->opcode,
+ __entry->fctype),
+ parse_nvme_cmd(__entry->qid, __entry->opcode,
+ __entry->fctype, __entry->cdw10))
);

TRACE_EVENT(nvme_complete_rq,
--
2.17.1

2019-05-18 02:32:32

by Minwoo Im

[permalink] [raw]
Subject: Re: [PATCH V3 0/5] nvme-trace: Add support for fabrics command

On 19-05-12 16:34:08, Minwoo Im wrote:
> Hi,
>
> Here's a third patchset to support fabrics command tracing. The first
> patch updated host/trace module to a outside of it to provide common
> interfaces for host and target both. The second one adds support for
> tracing fabrics command from host-side. The third is a trivial clean-up
> for providing a helper function to figure out given command structure is
> for fabrics or not.
>
> The fourth and fifth are the major change points of this patchset. 4th
> patch adds request tracing from the target-side. 5th updated, of course,
> completion of given request.
>
> Please review.
> Thanks,
>
> Changes to V2:
> - Provide a common code for both host and target. (Chaitanya)
> - Add support for tracing requests in target-side (Chaitanya)
> - Make it simple in trace.h without branch out from nvme core module
> (Christoph)
>
> Changes to V1:
> - fabrics commands should also be decoded, not just showing that it's
> a fabrics command. (Christoph)
> - do not make it within nvme admin commands (Chaitanya)
>
> Minwoo Im (5):
> nvme: Make trace common for host and target both
> nvme-trace: Support tracing fabrics commands from host-side
> nvme: Introduce nvme_is_fabrics to check fabrics cmd
> nvme-trace: Add tracing for req_init in trarget
> nvme-trace: Add tracing for req_comp in target

Ping :)