linux/drivers/nvme/host/trace.c
<<
>>
Prefs
   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);
 326