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