xref: /linux/drivers/nvme/host/trace.c (revision c88fb897c1fb5a590dc6353ac4b01c8f46a347b3)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * NVM Express device driver tracepoints
4  * Copyright (c) 2018 Johannes Thumshirn, SUSE Linux GmbH
5  */
6 
7 #include <asm/unaligned.h>
8 #include "trace.h"
9 
10 static const char *nvme_trace_delete_sq(struct trace_seq *p, u8 *cdw10)
11 {
12 	const char *ret = trace_seq_buffer_ptr(p);
13 	u16 sqid = get_unaligned_le16(cdw10);
14 
15 	trace_seq_printf(p, "sqid=%u", sqid);
16 	trace_seq_putc(p, 0);
17 
18 	return ret;
19 }
20 
21 static const char *nvme_trace_create_sq(struct trace_seq *p, u8 *cdw10)
22 {
23 	const char *ret = trace_seq_buffer_ptr(p);
24 	u16 sqid = get_unaligned_le16(cdw10);
25 	u16 qsize = get_unaligned_le16(cdw10 + 2);
26 	u16 sq_flags = get_unaligned_le16(cdw10 + 4);
27 	u16 cqid = get_unaligned_le16(cdw10 + 6);
28 
29 
30 	trace_seq_printf(p, "sqid=%u, qsize=%u, sq_flags=0x%x, cqid=%u",
31 			 sqid, qsize, sq_flags, cqid);
32 	trace_seq_putc(p, 0);
33 
34 	return ret;
35 }
36 
37 static const char *nvme_trace_delete_cq(struct trace_seq *p, u8 *cdw10)
38 {
39 	const char *ret = trace_seq_buffer_ptr(p);
40 	u16 cqid = get_unaligned_le16(cdw10);
41 
42 	trace_seq_printf(p, "cqid=%u", cqid);
43 	trace_seq_putc(p, 0);
44 
45 	return ret;
46 }
47 
48 static const char *nvme_trace_create_cq(struct trace_seq *p, u8 *cdw10)
49 {
50 	const char *ret = trace_seq_buffer_ptr(p);
51 	u16 cqid = get_unaligned_le16(cdw10);
52 	u16 qsize = get_unaligned_le16(cdw10 + 2);
53 	u16 cq_flags = get_unaligned_le16(cdw10 + 4);
54 	u16 irq_vector = get_unaligned_le16(cdw10 + 6);
55 
56 	trace_seq_printf(p, "cqid=%u, qsize=%u, cq_flags=0x%x, irq_vector=%u",
57 			 cqid, qsize, cq_flags, irq_vector);
58 	trace_seq_putc(p, 0);
59 
60 	return ret;
61 }
62 
63 static const char *nvme_trace_admin_identify(struct trace_seq *p, u8 *cdw10)
64 {
65 	const char *ret = trace_seq_buffer_ptr(p);
66 	u8 cns = cdw10[0];
67 	u16 ctrlid = get_unaligned_le16(cdw10 + 2);
68 
69 	trace_seq_printf(p, "cns=%u, ctrlid=%u", cns, ctrlid);
70 	trace_seq_putc(p, 0);
71 
72 	return ret;
73 }
74 
75 static const char *nvme_trace_admin_get_features(struct trace_seq *p,
76 						 u8 *cdw10)
77 {
78 	const char *ret = trace_seq_buffer_ptr(p);
79 	u8 fid = cdw10[0];
80 	u8 sel = cdw10[1] & 0x7;
81 	u32 cdw11 = get_unaligned_le32(cdw10 + 4);
82 
83 	trace_seq_printf(p, "fid=0x%x sel=0x%x cdw11=0x%x", fid, sel, cdw11);
84 	trace_seq_putc(p, 0);
85 
86 	return ret;
87 }
88 
89 static const char *nvme_trace_get_lba_status(struct trace_seq *p,
90 					     u8 *cdw10)
91 {
92 	const char *ret = trace_seq_buffer_ptr(p);
93 	u64 slba = get_unaligned_le64(cdw10);
94 	u32 mndw = get_unaligned_le32(cdw10 + 8);
95 	u16 rl = get_unaligned_le16(cdw10 + 12);
96 	u8 atype = cdw10[15];
97 
98 	trace_seq_printf(p, "slba=0x%llx, mndw=0x%x, rl=0x%x, atype=%u",
99 			slba, mndw, rl, atype);
100 	trace_seq_putc(p, 0);
101 
102 	return ret;
103 }
104 
105 static const char *nvme_trace_admin_format_nvm(struct trace_seq *p, u8 *cdw10)
106 {
107 	const char *ret = trace_seq_buffer_ptr(p);
108 	u8 lbaf = cdw10[0] & 0xF;
109 	u8 mset = (cdw10[0] >> 4) & 0x1;
110 	u8 pi = (cdw10[0] >> 5) & 0x7;
111 	u8 pil = cdw10[1] & 0x1;
112 	u8 ses = (cdw10[1] >> 1) & 0x7;
113 
114 	trace_seq_printf(p, "lbaf=%u, mset=%u, pi=%u, pil=%u, ses=%u",
115 			lbaf, mset, pi, pil, ses);
116 
117 	trace_seq_putc(p, 0);
118 
119 	return ret;
120 }
121 
122 static const char *nvme_trace_read_write(struct trace_seq *p, u8 *cdw10)
123 {
124 	const char *ret = trace_seq_buffer_ptr(p);
125 	u64 slba = get_unaligned_le64(cdw10);
126 	u16 length = get_unaligned_le16(cdw10 + 8);
127 	u16 control = get_unaligned_le16(cdw10 + 10);
128 	u32 dsmgmt = get_unaligned_le32(cdw10 + 12);
129 	u32 reftag = get_unaligned_le32(cdw10 +  16);
130 
131 	trace_seq_printf(p,
132 			 "slba=%llu, len=%u, ctrl=0x%x, dsmgmt=%u, reftag=%u",
133 			 slba, length, control, dsmgmt, reftag);
134 	trace_seq_putc(p, 0);
135 
136 	return ret;
137 }
138 
139 static const char *nvme_trace_dsm(struct trace_seq *p, u8 *cdw10)
140 {
141 	const char *ret = trace_seq_buffer_ptr(p);
142 
143 	trace_seq_printf(p, "nr=%u, attributes=%u",
144 			 get_unaligned_le32(cdw10),
145 			 get_unaligned_le32(cdw10 + 4));
146 	trace_seq_putc(p, 0);
147 
148 	return ret;
149 }
150 
151 static const char *nvme_trace_zone_mgmt_send(struct trace_seq *p, u8 *cdw10)
152 {
153 	const char *ret = trace_seq_buffer_ptr(p);
154 	u64 slba = get_unaligned_le64(cdw10);
155 	u8 zsa = cdw10[12];
156 	u8 all = cdw10[13];
157 
158 	trace_seq_printf(p, "slba=%llu, zsa=%u, all=%u", slba, zsa, all);
159 	trace_seq_putc(p, 0);
160 
161 	return ret;
162 }
163 
164 static const char *nvme_trace_zone_mgmt_recv(struct trace_seq *p, u8 *cdw10)
165 {
166 	const char *ret = trace_seq_buffer_ptr(p);
167 	u64 slba = get_unaligned_le64(cdw10);
168 	u32 numd = get_unaligned_le32(cdw10 + 8);
169 	u8 zra = cdw10[12];
170 	u8 zrasf = cdw10[13];
171 	u8 pr = cdw10[14];
172 
173 	trace_seq_printf(p, "slba=%llu, numd=%u, zra=%u, zrasf=%u, pr=%u",
174 			 slba, numd, zra, zrasf, pr);
175 	trace_seq_putc(p, 0);
176 
177 	return ret;
178 }
179 
180 static const char *nvme_trace_common(struct trace_seq *p, u8 *cdw10)
181 {
182 	const char *ret = trace_seq_buffer_ptr(p);
183 
184 	trace_seq_printf(p, "cdw10=%*ph", 24, cdw10);
185 	trace_seq_putc(p, 0);
186 
187 	return ret;
188 }
189 
190 const char *nvme_trace_parse_admin_cmd(struct trace_seq *p,
191 				       u8 opcode, u8 *cdw10)
192 {
193 	switch (opcode) {
194 	case nvme_admin_delete_sq:
195 		return nvme_trace_delete_sq(p, cdw10);
196 	case nvme_admin_create_sq:
197 		return nvme_trace_create_sq(p, cdw10);
198 	case nvme_admin_delete_cq:
199 		return nvme_trace_delete_cq(p, cdw10);
200 	case nvme_admin_create_cq:
201 		return nvme_trace_create_cq(p, cdw10);
202 	case nvme_admin_identify:
203 		return nvme_trace_admin_identify(p, cdw10);
204 	case nvme_admin_get_features:
205 		return nvme_trace_admin_get_features(p, cdw10);
206 	case nvme_admin_get_lba_status:
207 		return nvme_trace_get_lba_status(p, cdw10);
208 	case nvme_admin_format_nvm:
209 		return nvme_trace_admin_format_nvm(p, cdw10);
210 	default:
211 		return nvme_trace_common(p, cdw10);
212 	}
213 }
214 
215 const char *nvme_trace_parse_nvm_cmd(struct trace_seq *p,
216 				     u8 opcode, u8 *cdw10)
217 {
218 	switch (opcode) {
219 	case nvme_cmd_read:
220 	case nvme_cmd_write:
221 	case nvme_cmd_write_zeroes:
222 	case nvme_cmd_zone_append:
223 		return nvme_trace_read_write(p, cdw10);
224 	case nvme_cmd_dsm:
225 		return nvme_trace_dsm(p, cdw10);
226 	case nvme_cmd_zone_mgmt_send:
227 		return nvme_trace_zone_mgmt_send(p, cdw10);
228 	case nvme_cmd_zone_mgmt_recv:
229 		return nvme_trace_zone_mgmt_recv(p, cdw10);
230 	default:
231 		return nvme_trace_common(p, cdw10);
232 	}
233 }
234 
235 static const char *nvme_trace_fabrics_property_set(struct trace_seq *p, u8 *spc)
236 {
237 	const char *ret = trace_seq_buffer_ptr(p);
238 	u8 attrib = spc[0];
239 	u32 ofst = get_unaligned_le32(spc + 4);
240 	u64 value = get_unaligned_le64(spc + 8);
241 
242 	trace_seq_printf(p, "attrib=%u, ofst=0x%x, value=0x%llx",
243 			 attrib, ofst, value);
244 	trace_seq_putc(p, 0);
245 	return ret;
246 }
247 
248 static const char *nvme_trace_fabrics_connect(struct trace_seq *p, u8 *spc)
249 {
250 	const char *ret = trace_seq_buffer_ptr(p);
251 	u16 recfmt = get_unaligned_le16(spc);
252 	u16 qid = get_unaligned_le16(spc + 2);
253 	u16 sqsize = get_unaligned_le16(spc + 4);
254 	u8 cattr = spc[6];
255 	u32 kato = get_unaligned_le32(spc + 8);
256 
257 	trace_seq_printf(p, "recfmt=%u, qid=%u, sqsize=%u, cattr=%u, kato=%u",
258 			 recfmt, qid, sqsize, cattr, kato);
259 	trace_seq_putc(p, 0);
260 	return ret;
261 }
262 
263 static const char *nvme_trace_fabrics_property_get(struct trace_seq *p, u8 *spc)
264 {
265 	const char *ret = trace_seq_buffer_ptr(p);
266 	u8 attrib = spc[0];
267 	u32 ofst = get_unaligned_le32(spc + 4);
268 
269 	trace_seq_printf(p, "attrib=%u, ofst=0x%x", attrib, ofst);
270 	trace_seq_putc(p, 0);
271 	return ret;
272 }
273 
274 static const char *nvme_trace_fabrics_common(struct trace_seq *p, u8 *spc)
275 {
276 	const char *ret = trace_seq_buffer_ptr(p);
277 
278 	trace_seq_printf(p, "specific=%*ph", 24, spc);
279 	trace_seq_putc(p, 0);
280 	return ret;
281 }
282 
283 const char *nvme_trace_parse_fabrics_cmd(struct trace_seq *p,
284 		u8 fctype, u8 *spc)
285 {
286 	switch (fctype) {
287 	case nvme_fabrics_type_property_set:
288 		return nvme_trace_fabrics_property_set(p, spc);
289 	case nvme_fabrics_type_connect:
290 		return nvme_trace_fabrics_connect(p, spc);
291 	case nvme_fabrics_type_property_get:
292 		return nvme_trace_fabrics_property_get(p, spc);
293 	default:
294 		return nvme_trace_fabrics_common(p, spc);
295 	}
296 }
297 
298 const char *nvme_trace_disk_name(struct trace_seq *p, char *name)
299 {
300 	const char *ret = trace_seq_buffer_ptr(p);
301 
302 	if (*name)
303 		trace_seq_printf(p, "disk=%s, ", name);
304 	trace_seq_putc(p, 0);
305 
306 	return ret;
307 }
308 
309 EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_sq);
310