trace.c (8355B)
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 10static 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 21static 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 37static 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 48static 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 63static 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 75static const char *nvme_trace_admin_set_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 sv = cdw10[3] & 0x8; 81 u32 cdw11 = get_unaligned_le32(cdw10 + 4); 82 83 trace_seq_printf(p, "fid=0x%x, sv=0x%x, cdw11=0x%x", fid, sv, cdw11); 84 trace_seq_putc(p, 0); 85 86 return ret; 87} 88 89static const char *nvme_trace_admin_get_features(struct trace_seq *p, 90 u8 *cdw10) 91{ 92 const char *ret = trace_seq_buffer_ptr(p); 93 u8 fid = cdw10[0]; 94 u8 sel = cdw10[1] & 0x7; 95 u32 cdw11 = get_unaligned_le32(cdw10 + 4); 96 97 trace_seq_printf(p, "fid=0x%x, sel=0x%x, cdw11=0x%x", fid, sel, cdw11); 98 trace_seq_putc(p, 0); 99 100 return ret; 101} 102 103static const char *nvme_trace_get_lba_status(struct trace_seq *p, 104 u8 *cdw10) 105{ 106 const char *ret = trace_seq_buffer_ptr(p); 107 u64 slba = get_unaligned_le64(cdw10); 108 u32 mndw = get_unaligned_le32(cdw10 + 8); 109 u16 rl = get_unaligned_le16(cdw10 + 12); 110 u8 atype = cdw10[15]; 111 112 trace_seq_printf(p, "slba=0x%llx, mndw=0x%x, rl=0x%x, atype=%u", 113 slba, mndw, rl, atype); 114 trace_seq_putc(p, 0); 115 116 return ret; 117} 118 119static const char *nvme_trace_admin_format_nvm(struct trace_seq *p, u8 *cdw10) 120{ 121 const char *ret = trace_seq_buffer_ptr(p); 122 u8 lbaf = cdw10[0] & 0xF; 123 u8 mset = (cdw10[0] >> 4) & 0x1; 124 u8 pi = (cdw10[0] >> 5) & 0x7; 125 u8 pil = cdw10[1] & 0x1; 126 u8 ses = (cdw10[1] >> 1) & 0x7; 127 128 trace_seq_printf(p, "lbaf=%u, mset=%u, pi=%u, pil=%u, ses=%u", 129 lbaf, mset, pi, pil, ses); 130 131 trace_seq_putc(p, 0); 132 133 return ret; 134} 135 136static const char *nvme_trace_read_write(struct trace_seq *p, u8 *cdw10) 137{ 138 const char *ret = trace_seq_buffer_ptr(p); 139 u64 slba = get_unaligned_le64(cdw10); 140 u16 length = get_unaligned_le16(cdw10 + 8); 141 u16 control = get_unaligned_le16(cdw10 + 10); 142 u32 dsmgmt = get_unaligned_le32(cdw10 + 12); 143 u32 reftag = get_unaligned_le32(cdw10 + 16); 144 145 trace_seq_printf(p, 146 "slba=%llu, len=%u, ctrl=0x%x, dsmgmt=%u, reftag=%u", 147 slba, length, control, dsmgmt, reftag); 148 trace_seq_putc(p, 0); 149 150 return ret; 151} 152 153static const char *nvme_trace_dsm(struct trace_seq *p, u8 *cdw10) 154{ 155 const char *ret = trace_seq_buffer_ptr(p); 156 157 trace_seq_printf(p, "nr=%u, attributes=%u", 158 get_unaligned_le32(cdw10), 159 get_unaligned_le32(cdw10 + 4)); 160 trace_seq_putc(p, 0); 161 162 return ret; 163} 164 165static const char *nvme_trace_zone_mgmt_send(struct trace_seq *p, u8 *cdw10) 166{ 167 const char *ret = trace_seq_buffer_ptr(p); 168 u64 slba = get_unaligned_le64(cdw10); 169 u8 zsa = cdw10[12]; 170 u8 all = cdw10[13]; 171 172 trace_seq_printf(p, "slba=%llu, zsa=%u, all=%u", slba, zsa, all); 173 trace_seq_putc(p, 0); 174 175 return ret; 176} 177 178static const char *nvme_trace_zone_mgmt_recv(struct trace_seq *p, u8 *cdw10) 179{ 180 const char *ret = trace_seq_buffer_ptr(p); 181 u64 slba = get_unaligned_le64(cdw10); 182 u32 numd = get_unaligned_le32(cdw10 + 8); 183 u8 zra = cdw10[12]; 184 u8 zrasf = cdw10[13]; 185 u8 pr = cdw10[14]; 186 187 trace_seq_printf(p, "slba=%llu, numd=%u, zra=%u, zrasf=%u, pr=%u", 188 slba, numd, zra, zrasf, pr); 189 trace_seq_putc(p, 0); 190 191 return ret; 192} 193 194static const char *nvme_trace_common(struct trace_seq *p, u8 *cdw10) 195{ 196 const char *ret = trace_seq_buffer_ptr(p); 197 198 trace_seq_printf(p, "cdw10=%*ph", 24, cdw10); 199 trace_seq_putc(p, 0); 200 201 return ret; 202} 203 204const char *nvme_trace_parse_admin_cmd(struct trace_seq *p, 205 u8 opcode, u8 *cdw10) 206{ 207 switch (opcode) { 208 case nvme_admin_delete_sq: 209 return nvme_trace_delete_sq(p, cdw10); 210 case nvme_admin_create_sq: 211 return nvme_trace_create_sq(p, cdw10); 212 case nvme_admin_delete_cq: 213 return nvme_trace_delete_cq(p, cdw10); 214 case nvme_admin_create_cq: 215 return nvme_trace_create_cq(p, cdw10); 216 case nvme_admin_identify: 217 return nvme_trace_admin_identify(p, cdw10); 218 case nvme_admin_set_features: 219 return nvme_trace_admin_set_features(p, cdw10); 220 case nvme_admin_get_features: 221 return nvme_trace_admin_get_features(p, cdw10); 222 case nvme_admin_get_lba_status: 223 return nvme_trace_get_lba_status(p, cdw10); 224 case nvme_admin_format_nvm: 225 return nvme_trace_admin_format_nvm(p, cdw10); 226 default: 227 return nvme_trace_common(p, cdw10); 228 } 229} 230 231const char *nvme_trace_parse_nvm_cmd(struct trace_seq *p, 232 u8 opcode, u8 *cdw10) 233{ 234 switch (opcode) { 235 case nvme_cmd_read: 236 case nvme_cmd_write: 237 case nvme_cmd_write_zeroes: 238 case nvme_cmd_zone_append: 239 return nvme_trace_read_write(p, cdw10); 240 case nvme_cmd_dsm: 241 return nvme_trace_dsm(p, cdw10); 242 case nvme_cmd_zone_mgmt_send: 243 return nvme_trace_zone_mgmt_send(p, cdw10); 244 case nvme_cmd_zone_mgmt_recv: 245 return nvme_trace_zone_mgmt_recv(p, cdw10); 246 default: 247 return nvme_trace_common(p, cdw10); 248 } 249} 250 251static const char *nvme_trace_fabrics_property_set(struct trace_seq *p, u8 *spc) 252{ 253 const char *ret = trace_seq_buffer_ptr(p); 254 u8 attrib = spc[0]; 255 u32 ofst = get_unaligned_le32(spc + 4); 256 u64 value = get_unaligned_le64(spc + 8); 257 258 trace_seq_printf(p, "attrib=%u, ofst=0x%x, value=0x%llx", 259 attrib, ofst, value); 260 trace_seq_putc(p, 0); 261 return ret; 262} 263 264static const char *nvme_trace_fabrics_connect(struct trace_seq *p, u8 *spc) 265{ 266 const char *ret = trace_seq_buffer_ptr(p); 267 u16 recfmt = get_unaligned_le16(spc); 268 u16 qid = get_unaligned_le16(spc + 2); 269 u16 sqsize = get_unaligned_le16(spc + 4); 270 u8 cattr = spc[6]; 271 u32 kato = get_unaligned_le32(spc + 8); 272 273 trace_seq_printf(p, "recfmt=%u, qid=%u, sqsize=%u, cattr=%u, kato=%u", 274 recfmt, qid, sqsize, cattr, kato); 275 trace_seq_putc(p, 0); 276 return ret; 277} 278 279static const char *nvme_trace_fabrics_property_get(struct trace_seq *p, u8 *spc) 280{ 281 const char *ret = trace_seq_buffer_ptr(p); 282 u8 attrib = spc[0]; 283 u32 ofst = get_unaligned_le32(spc + 4); 284 285 trace_seq_printf(p, "attrib=%u, ofst=0x%x", attrib, ofst); 286 trace_seq_putc(p, 0); 287 return ret; 288} 289 290static const char *nvme_trace_fabrics_common(struct trace_seq *p, u8 *spc) 291{ 292 const char *ret = trace_seq_buffer_ptr(p); 293 294 trace_seq_printf(p, "specific=%*ph", 24, spc); 295 trace_seq_putc(p, 0); 296 return ret; 297} 298 299const char *nvme_trace_parse_fabrics_cmd(struct trace_seq *p, 300 u8 fctype, u8 *spc) 301{ 302 switch (fctype) { 303 case nvme_fabrics_type_property_set: 304 return nvme_trace_fabrics_property_set(p, spc); 305 case nvme_fabrics_type_connect: 306 return nvme_trace_fabrics_connect(p, spc); 307 case nvme_fabrics_type_property_get: 308 return nvme_trace_fabrics_property_get(p, spc); 309 default: 310 return nvme_trace_fabrics_common(p, spc); 311 } 312} 313 314const char *nvme_trace_disk_name(struct trace_seq *p, char *name) 315{ 316 const char *ret = trace_seq_buffer_ptr(p); 317 318 if (*name) 319 trace_seq_printf(p, "disk=%s, ", name); 320 trace_seq_putc(p, 0); 321 322 return ret; 323} 324 325EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_sq);