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 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 #endif /* _TRACE_NVME_H */ 160 161 #undef TRACE_INCLUDE_PATH 162 #define TRACE_INCLUDE_PATH . 163 #undef TRACE_INCLUDE_FILE 164 #define TRACE_INCLUDE_FILE trace 165 166 /* This part must be outside protection */ 167 #include <trace/define_trace.h> 168