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