1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * NVM Express target device driver tracepoints
4*4882a593Smuzhiyun * Copyright (c) 2018 Johannes Thumshirn, SUSE Linux GmbH
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * This is entirely based on drivers/nvme/host/trace.h
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #undef TRACE_SYSTEM
10*4882a593Smuzhiyun #define TRACE_SYSTEM nvmet
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #if !defined(_TRACE_NVMET_H) || defined(TRACE_HEADER_MULTI_READ)
13*4882a593Smuzhiyun #define _TRACE_NVMET_H
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #include <linux/nvme.h>
16*4882a593Smuzhiyun #include <linux/tracepoint.h>
17*4882a593Smuzhiyun #include <linux/trace_seq.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include "nvmet.h"
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun const char *nvmet_trace_parse_admin_cmd(struct trace_seq *p, u8 opcode,
22*4882a593Smuzhiyun u8 *cdw10);
23*4882a593Smuzhiyun const char *nvmet_trace_parse_nvm_cmd(struct trace_seq *p, u8 opcode,
24*4882a593Smuzhiyun u8 *cdw10);
25*4882a593Smuzhiyun const char *nvmet_trace_parse_fabrics_cmd(struct trace_seq *p, u8 fctype,
26*4882a593Smuzhiyun u8 *spc);
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #define parse_nvme_cmd(qid, opcode, fctype, cdw10) \
29*4882a593Smuzhiyun ((opcode) == nvme_fabrics_command ? \
30*4882a593Smuzhiyun nvmet_trace_parse_fabrics_cmd(p, fctype, cdw10) : \
31*4882a593Smuzhiyun (qid ? \
32*4882a593Smuzhiyun nvmet_trace_parse_nvm_cmd(p, opcode, cdw10) : \
33*4882a593Smuzhiyun nvmet_trace_parse_admin_cmd(p, opcode, cdw10)))
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl);
36*4882a593Smuzhiyun #define __print_ctrl_name(ctrl) \
37*4882a593Smuzhiyun nvmet_trace_ctrl_name(p, ctrl)
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun const char *nvmet_trace_disk_name(struct trace_seq *p, char *name);
40*4882a593Smuzhiyun #define __print_disk_name(name) \
41*4882a593Smuzhiyun nvmet_trace_disk_name(p, name)
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #ifndef TRACE_HEADER_MULTI_READ
nvmet_req_to_ctrl(struct nvmet_req * req)44*4882a593Smuzhiyun static inline struct nvmet_ctrl *nvmet_req_to_ctrl(struct nvmet_req *req)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun return req->sq->ctrl;
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun
__assign_req_name(char * name,struct nvmet_req * req)49*4882a593Smuzhiyun static inline void __assign_req_name(char *name, struct nvmet_req *req)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun if (req->ns)
52*4882a593Smuzhiyun strncpy(name, req->ns->device_path, DISK_NAME_LEN);
53*4882a593Smuzhiyun else
54*4882a593Smuzhiyun memset(name, 0, DISK_NAME_LEN);
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun #endif
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun TRACE_EVENT(nvmet_req_init,
59*4882a593Smuzhiyun TP_PROTO(struct nvmet_req *req, struct nvme_command *cmd),
60*4882a593Smuzhiyun TP_ARGS(req, cmd),
61*4882a593Smuzhiyun TP_STRUCT__entry(
62*4882a593Smuzhiyun __field(struct nvme_command *, cmd)
63*4882a593Smuzhiyun __field(struct nvmet_ctrl *, ctrl)
64*4882a593Smuzhiyun __array(char, disk, DISK_NAME_LEN)
65*4882a593Smuzhiyun __field(int, qid)
66*4882a593Smuzhiyun __field(u16, cid)
67*4882a593Smuzhiyun __field(u8, opcode)
68*4882a593Smuzhiyun __field(u8, fctype)
69*4882a593Smuzhiyun __field(u8, flags)
70*4882a593Smuzhiyun __field(u32, nsid)
71*4882a593Smuzhiyun __field(u64, metadata)
72*4882a593Smuzhiyun __array(u8, cdw10, 24)
73*4882a593Smuzhiyun ),
74*4882a593Smuzhiyun TP_fast_assign(
75*4882a593Smuzhiyun __entry->cmd = cmd;
76*4882a593Smuzhiyun __entry->ctrl = nvmet_req_to_ctrl(req);
77*4882a593Smuzhiyun __assign_req_name(__entry->disk, req);
78*4882a593Smuzhiyun __entry->qid = req->sq->qid;
79*4882a593Smuzhiyun __entry->cid = cmd->common.command_id;
80*4882a593Smuzhiyun __entry->opcode = cmd->common.opcode;
81*4882a593Smuzhiyun __entry->fctype = cmd->fabrics.fctype;
82*4882a593Smuzhiyun __entry->flags = cmd->common.flags;
83*4882a593Smuzhiyun __entry->nsid = le32_to_cpu(cmd->common.nsid);
84*4882a593Smuzhiyun __entry->metadata = le64_to_cpu(cmd->common.metadata);
85*4882a593Smuzhiyun memcpy(__entry->cdw10, &cmd->common.cdw10,
86*4882a593Smuzhiyun sizeof(__entry->cdw10));
87*4882a593Smuzhiyun ),
88*4882a593Smuzhiyun TP_printk("nvmet%s: %sqid=%d, cmdid=%u, nsid=%u, flags=%#x, "
89*4882a593Smuzhiyun "meta=%#llx, cmd=(%s, %s)",
90*4882a593Smuzhiyun __print_ctrl_name(__entry->ctrl),
91*4882a593Smuzhiyun __print_disk_name(__entry->disk),
92*4882a593Smuzhiyun __entry->qid, __entry->cid, __entry->nsid,
93*4882a593Smuzhiyun __entry->flags, __entry->metadata,
94*4882a593Smuzhiyun show_opcode_name(__entry->qid, __entry->opcode,
95*4882a593Smuzhiyun __entry->fctype),
96*4882a593Smuzhiyun parse_nvme_cmd(__entry->qid, __entry->opcode,
97*4882a593Smuzhiyun __entry->fctype, __entry->cdw10))
98*4882a593Smuzhiyun );
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun TRACE_EVENT(nvmet_req_complete,
101*4882a593Smuzhiyun TP_PROTO(struct nvmet_req *req),
102*4882a593Smuzhiyun TP_ARGS(req),
103*4882a593Smuzhiyun TP_STRUCT__entry(
104*4882a593Smuzhiyun __field(struct nvmet_ctrl *, ctrl)
105*4882a593Smuzhiyun __array(char, disk, DISK_NAME_LEN)
106*4882a593Smuzhiyun __field(int, qid)
107*4882a593Smuzhiyun __field(int, cid)
108*4882a593Smuzhiyun __field(u64, result)
109*4882a593Smuzhiyun __field(u16, status)
110*4882a593Smuzhiyun ),
111*4882a593Smuzhiyun TP_fast_assign(
112*4882a593Smuzhiyun __entry->ctrl = nvmet_req_to_ctrl(req);
113*4882a593Smuzhiyun __entry->qid = req->cq->qid;
114*4882a593Smuzhiyun __entry->cid = req->cqe->command_id;
115*4882a593Smuzhiyun __entry->result = le64_to_cpu(req->cqe->result.u64);
116*4882a593Smuzhiyun __entry->status = le16_to_cpu(req->cqe->status) >> 1;
117*4882a593Smuzhiyun __assign_req_name(__entry->disk, req);
118*4882a593Smuzhiyun ),
119*4882a593Smuzhiyun TP_printk("nvmet%s: %sqid=%d, cmdid=%u, res=%#llx, status=%#x",
120*4882a593Smuzhiyun __print_ctrl_name(__entry->ctrl),
121*4882a593Smuzhiyun __print_disk_name(__entry->disk),
122*4882a593Smuzhiyun __entry->qid, __entry->cid, __entry->result, __entry->status)
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun );
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun #define aer_name(aer) { aer, #aer }
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun TRACE_EVENT(nvmet_async_event,
129*4882a593Smuzhiyun TP_PROTO(struct nvmet_ctrl *ctrl, __le32 result),
130*4882a593Smuzhiyun TP_ARGS(ctrl, result),
131*4882a593Smuzhiyun TP_STRUCT__entry(
132*4882a593Smuzhiyun __field(int, ctrl_id)
133*4882a593Smuzhiyun __field(u32, result)
134*4882a593Smuzhiyun ),
135*4882a593Smuzhiyun TP_fast_assign(
136*4882a593Smuzhiyun __entry->ctrl_id = ctrl->cntlid;
137*4882a593Smuzhiyun __entry->result = (le32_to_cpu(result) & 0xff00) >> 8;
138*4882a593Smuzhiyun ),
139*4882a593Smuzhiyun TP_printk("nvmet%d: NVME_AEN=%#08x [%s]",
140*4882a593Smuzhiyun __entry->ctrl_id, __entry->result,
141*4882a593Smuzhiyun __print_symbolic(__entry->result,
142*4882a593Smuzhiyun aer_name(NVME_AER_NOTICE_NS_CHANGED),
143*4882a593Smuzhiyun aer_name(NVME_AER_NOTICE_ANA),
144*4882a593Smuzhiyun aer_name(NVME_AER_NOTICE_FW_ACT_STARTING),
145*4882a593Smuzhiyun aer_name(NVME_AER_NOTICE_DISC_CHANGED),
146*4882a593Smuzhiyun aer_name(NVME_AER_ERROR),
147*4882a593Smuzhiyun aer_name(NVME_AER_SMART),
148*4882a593Smuzhiyun aer_name(NVME_AER_CSS),
149*4882a593Smuzhiyun aer_name(NVME_AER_VS))
150*4882a593Smuzhiyun )
151*4882a593Smuzhiyun );
152*4882a593Smuzhiyun #undef aer_name
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun #endif /* _TRACE_NVMET_H */
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun #undef TRACE_INCLUDE_PATH
157*4882a593Smuzhiyun #define TRACE_INCLUDE_PATH .
158*4882a593Smuzhiyun #undef TRACE_INCLUDE_FILE
159*4882a593Smuzhiyun #define TRACE_INCLUDE_FILE trace
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun /* This part must be outside protection */
162*4882a593Smuzhiyun #include <trace/define_trace.h>
163