xref: /openbmc/linux/drivers/nvme/host/trace.h (revision 9fb29c73)
1 /*
2  * NVM Express device driver tracepoints
3  * Copyright (c) 2018 Johannes Thumshirn, SUSE Linux GmbH
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  */
14 
15 #undef TRACE_SYSTEM
16 #define TRACE_SYSTEM nvme
17 
18 #if !defined(_TRACE_NVME_H) || defined(TRACE_HEADER_MULTI_READ)
19 #define _TRACE_NVME_H
20 
21 #include <linux/nvme.h>
22 #include <linux/tracepoint.h>
23 #include <linux/trace_seq.h>
24 
25 #include "nvme.h"
26 
27 #define nvme_admin_opcode_name(opcode)	{ opcode, #opcode }
28 #define show_admin_opcode_name(val)					\
29 	__print_symbolic(val,						\
30 		nvme_admin_opcode_name(nvme_admin_delete_sq),		\
31 		nvme_admin_opcode_name(nvme_admin_create_sq),		\
32 		nvme_admin_opcode_name(nvme_admin_get_log_page),	\
33 		nvme_admin_opcode_name(nvme_admin_delete_cq),		\
34 		nvme_admin_opcode_name(nvme_admin_create_cq),		\
35 		nvme_admin_opcode_name(nvme_admin_identify),		\
36 		nvme_admin_opcode_name(nvme_admin_abort_cmd),		\
37 		nvme_admin_opcode_name(nvme_admin_set_features),	\
38 		nvme_admin_opcode_name(nvme_admin_get_features),	\
39 		nvme_admin_opcode_name(nvme_admin_async_event),		\
40 		nvme_admin_opcode_name(nvme_admin_ns_mgmt),		\
41 		nvme_admin_opcode_name(nvme_admin_activate_fw),		\
42 		nvme_admin_opcode_name(nvme_admin_download_fw),		\
43 		nvme_admin_opcode_name(nvme_admin_ns_attach),		\
44 		nvme_admin_opcode_name(nvme_admin_keep_alive),		\
45 		nvme_admin_opcode_name(nvme_admin_directive_send),	\
46 		nvme_admin_opcode_name(nvme_admin_directive_recv),	\
47 		nvme_admin_opcode_name(nvme_admin_dbbuf),		\
48 		nvme_admin_opcode_name(nvme_admin_format_nvm),		\
49 		nvme_admin_opcode_name(nvme_admin_security_send),	\
50 		nvme_admin_opcode_name(nvme_admin_security_recv),	\
51 		nvme_admin_opcode_name(nvme_admin_sanitize_nvm))
52 
53 #define nvme_opcode_name(opcode)	{ opcode, #opcode }
54 #define show_nvm_opcode_name(val)				\
55 	__print_symbolic(val,					\
56 		nvme_opcode_name(nvme_cmd_flush),		\
57 		nvme_opcode_name(nvme_cmd_write),		\
58 		nvme_opcode_name(nvme_cmd_read),		\
59 		nvme_opcode_name(nvme_cmd_write_uncor),		\
60 		nvme_opcode_name(nvme_cmd_compare),		\
61 		nvme_opcode_name(nvme_cmd_write_zeroes),	\
62 		nvme_opcode_name(nvme_cmd_dsm),			\
63 		nvme_opcode_name(nvme_cmd_resv_register),	\
64 		nvme_opcode_name(nvme_cmd_resv_report),		\
65 		nvme_opcode_name(nvme_cmd_resv_acquire),	\
66 		nvme_opcode_name(nvme_cmd_resv_release))
67 
68 #define show_opcode_name(qid, opcode)					\
69 	(qid ? show_nvm_opcode_name(opcode) : show_admin_opcode_name(opcode))
70 
71 const char *nvme_trace_parse_admin_cmd(struct trace_seq *p, u8 opcode,
72 		u8 *cdw10);
73 const char *nvme_trace_parse_nvm_cmd(struct trace_seq *p, u8 opcode,
74 		u8 *cdw10);
75 
76 #define parse_nvme_cmd(qid, opcode, cdw10) 			\
77 	(qid ?							\
78 	 nvme_trace_parse_nvm_cmd(p, opcode, cdw10) : 		\
79 	 nvme_trace_parse_admin_cmd(p, opcode, cdw10))
80 
81 const char *nvme_trace_disk_name(struct trace_seq *p, char *name);
82 #define __print_disk_name(name)				\
83 	nvme_trace_disk_name(p, name)
84 
85 #ifndef TRACE_HEADER_MULTI_READ
86 static inline void __assign_disk_name(char *name, struct gendisk *disk)
87 {
88 	if (disk)
89 		memcpy(name, disk->disk_name, DISK_NAME_LEN);
90 	else
91 		memset(name, 0, DISK_NAME_LEN);
92 }
93 #endif
94 
95 TRACE_EVENT(nvme_setup_cmd,
96 	    TP_PROTO(struct request *req, struct nvme_command *cmd),
97 	    TP_ARGS(req, cmd),
98 	    TP_STRUCT__entry(
99 		__array(char, disk, DISK_NAME_LEN)
100 		__field(int, ctrl_id)
101 		__field(int, qid)
102 		__field(u8, opcode)
103 		__field(u8, flags)
104 		__field(u16, cid)
105 		__field(u32, nsid)
106 		__field(u64, metadata)
107 		__array(u8, cdw10, 24)
108 	    ),
109 	    TP_fast_assign(
110 		__entry->ctrl_id = nvme_req(req)->ctrl->instance;
111 		__entry->qid = nvme_req_qid(req);
112 		__entry->opcode = cmd->common.opcode;
113 		__entry->flags = cmd->common.flags;
114 		__entry->cid = cmd->common.command_id;
115 		__entry->nsid = le32_to_cpu(cmd->common.nsid);
116 		__entry->metadata = le64_to_cpu(cmd->common.metadata);
117 		__assign_disk_name(__entry->disk, req->rq_disk);
118 		memcpy(__entry->cdw10, &cmd->common.cdw10,
119 			6 * sizeof(__entry->cdw10));
120 	    ),
121 	    TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%llx, cmd=(%s %s)",
122 		      __entry->ctrl_id, __print_disk_name(__entry->disk),
123 		      __entry->qid, __entry->cid, __entry->nsid,
124 		      __entry->flags, __entry->metadata,
125 		      show_opcode_name(__entry->qid, __entry->opcode),
126 		      parse_nvme_cmd(__entry->qid, __entry->opcode, __entry->cdw10))
127 );
128 
129 TRACE_EVENT(nvme_complete_rq,
130 	    TP_PROTO(struct request *req),
131 	    TP_ARGS(req),
132 	    TP_STRUCT__entry(
133 		__array(char, disk, DISK_NAME_LEN)
134 		__field(int, ctrl_id)
135 		__field(int, qid)
136 		__field(int, cid)
137 		__field(u64, result)
138 		__field(u8, retries)
139 		__field(u8, flags)
140 		__field(u16, status)
141 	    ),
142 	    TP_fast_assign(
143 		__entry->ctrl_id = nvme_req(req)->ctrl->instance;
144 		__entry->qid = nvme_req_qid(req);
145 		__entry->cid = req->tag;
146 		__entry->result = le64_to_cpu(nvme_req(req)->result.u64);
147 		__entry->retries = nvme_req(req)->retries;
148 		__entry->flags = nvme_req(req)->flags;
149 		__entry->status = nvme_req(req)->status;
150 		__assign_disk_name(__entry->disk, req->rq_disk);
151 	    ),
152 	    TP_printk("nvme%d: %sqid=%d, cmdid=%u, res=%llu, retries=%u, flags=0x%x, status=%u",
153 		      __entry->ctrl_id, __print_disk_name(__entry->disk),
154 		      __entry->qid, __entry->cid, __entry->result,
155 		      __entry->retries, __entry->flags, __entry->status)
156 
157 );
158 
159 #define aer_name(aer) { aer, #aer }
160 
161 TRACE_EVENT(nvme_async_event,
162 	TP_PROTO(struct nvme_ctrl *ctrl, u32 result),
163 	TP_ARGS(ctrl, result),
164 	TP_STRUCT__entry(
165 		__field(int, ctrl_id)
166 		__field(u32, result)
167 	),
168 	TP_fast_assign(
169 		__entry->ctrl_id = ctrl->instance;
170 		__entry->result = result;
171 	),
172 	TP_printk("nvme%d: NVME_AEN=%#08x [%s]",
173 		__entry->ctrl_id, __entry->result,
174 		__print_symbolic(__entry->result,
175 		aer_name(NVME_AER_NOTICE_NS_CHANGED),
176 		aer_name(NVME_AER_NOTICE_ANA),
177 		aer_name(NVME_AER_NOTICE_FW_ACT_STARTING),
178 		aer_name(NVME_AER_ERROR),
179 		aer_name(NVME_AER_SMART),
180 		aer_name(NVME_AER_CSS),
181 		aer_name(NVME_AER_VS))
182 	)
183 );
184 
185 #undef aer_name
186 
187 TRACE_EVENT(nvme_sq,
188 	TP_PROTO(struct request *req, __le16 sq_head, int sq_tail),
189 	TP_ARGS(req, sq_head, sq_tail),
190 	TP_STRUCT__entry(
191 		__field(int, ctrl_id)
192 		__array(char, disk, DISK_NAME_LEN)
193 		__field(int, qid)
194 		__field(u16, sq_head)
195 		__field(u16, sq_tail)
196 	),
197 	TP_fast_assign(
198 		__entry->ctrl_id = nvme_req(req)->ctrl->instance;
199 		__assign_disk_name(__entry->disk, req->rq_disk);
200 		__entry->qid = nvme_req_qid(req);
201 		__entry->sq_head = le16_to_cpu(sq_head);
202 		__entry->sq_tail = sq_tail;
203 	),
204 	TP_printk("nvme%d: %sqid=%d, head=%u, tail=%u",
205 		__entry->ctrl_id, __print_disk_name(__entry->disk),
206 		__entry->qid, __entry->sq_head, __entry->sq_tail
207 	)
208 );
209 
210 #endif /* _TRACE_NVME_H */
211 
212 #undef TRACE_INCLUDE_PATH
213 #define TRACE_INCLUDE_PATH .
214 #undef TRACE_INCLUDE_FILE
215 #define TRACE_INCLUDE_FILE trace
216 
217 /* This part must be outside protection */
218 #include <trace/define_trace.h>
219