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
__assign_disk_name(char * name,struct gendisk * disk)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