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 | const char *nvme_trace_parse_admin_cmd(struct trace_seq *p, u8 opcode, |
20 | u8 *cdw10); |
21 | const char *nvme_trace_parse_nvm_cmd(struct trace_seq *p, u8 opcode, |
22 | u8 *cdw10); |
23 | const char *nvme_trace_parse_fabrics_cmd(struct trace_seq *p, u8 fctype, |
24 | u8 *spc); |
25 | |
26 | #define parse_nvme_cmd(qid, opcode, fctype, cdw10) \ |
27 | ((opcode) == nvme_fabrics_command ? \ |
28 | nvme_trace_parse_fabrics_cmd(p, fctype, cdw10) : \ |
29 | ((qid) ? \ |
30 | nvme_trace_parse_nvm_cmd(p, opcode, cdw10) : \ |
31 | nvme_trace_parse_admin_cmd(p, opcode, cdw10))) |
32 | |
33 | const char *nvme_trace_disk_name(struct trace_seq *p, char *name); |
34 | #define __print_disk_name(name) \ |
35 | nvme_trace_disk_name(p, name) |
36 | |
37 | #ifndef TRACE_HEADER_MULTI_READ |
38 | static inline void __assign_disk_name(char *name, struct gendisk *disk) |
39 | { |
40 | if (disk) |
41 | memcpy(name, disk->disk_name, DISK_NAME_LEN); |
42 | else |
43 | memset(name, 0, DISK_NAME_LEN); |
44 | } |
45 | #endif |
46 | |
47 | TRACE_EVENT(nvme_setup_cmd, |
48 | TP_PROTO(struct request *req, struct nvme_command *cmd), |
49 | TP_ARGS(req, cmd), |
50 | TP_STRUCT__entry( |
51 | __array(char, disk, DISK_NAME_LEN) |
52 | __field(int, ctrl_id) |
53 | __field(int, qid) |
54 | __field(u8, opcode) |
55 | __field(u8, flags) |
56 | __field(u8, fctype) |
57 | __field(u16, cid) |
58 | __field(u32, nsid) |
59 | __field(bool, metadata) |
60 | __array(u8, cdw10, 24) |
61 | ), |
62 | TP_fast_assign( |
63 | __entry->ctrl_id = nvme_req(req)->ctrl->instance; |
64 | __entry->qid = nvme_req_qid(req); |
65 | __entry->opcode = cmd->common.opcode; |
66 | __entry->flags = cmd->common.flags; |
67 | __entry->cid = cmd->common.command_id; |
68 | __entry->nsid = le32_to_cpu(cmd->common.nsid); |
69 | __entry->metadata = !!blk_integrity_rq(req); |
70 | __entry->fctype = cmd->fabrics.fctype; |
71 | __assign_disk_name(__entry->disk, req->q->disk); |
72 | memcpy(__entry->cdw10, &cmd->common.cdws, |
73 | sizeof(__entry->cdw10)); |
74 | ), |
75 | TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%x, cmd=(%s %s)" , |
76 | __entry->ctrl_id, __print_disk_name(__entry->disk), |
77 | __entry->qid, __entry->cid, __entry->nsid, |
78 | __entry->flags, __entry->metadata, |
79 | show_opcode_name(__entry->qid, __entry->opcode, |
80 | __entry->fctype), |
81 | parse_nvme_cmd(__entry->qid, __entry->opcode, |
82 | __entry->fctype, __entry->cdw10)) |
83 | ); |
84 | |
85 | TRACE_EVENT(nvme_complete_rq, |
86 | TP_PROTO(struct request *req), |
87 | TP_ARGS(req), |
88 | TP_STRUCT__entry( |
89 | __array(char, disk, DISK_NAME_LEN) |
90 | __field(int, ctrl_id) |
91 | __field(int, qid) |
92 | __field(int, cid) |
93 | __field(u64, result) |
94 | __field(u8, retries) |
95 | __field(u8, flags) |
96 | __field(u16, status) |
97 | ), |
98 | TP_fast_assign( |
99 | __entry->ctrl_id = nvme_req(req)->ctrl->instance; |
100 | __entry->qid = nvme_req_qid(req); |
101 | __entry->cid = nvme_req(req)->cmd->common.command_id; |
102 | __entry->result = le64_to_cpu(nvme_req(req)->result.u64); |
103 | __entry->retries = nvme_req(req)->retries; |
104 | __entry->flags = nvme_req(req)->flags; |
105 | __entry->status = nvme_req(req)->status; |
106 | __assign_disk_name(__entry->disk, req->q->disk); |
107 | ), |
108 | TP_printk("nvme%d: %sqid=%d, cmdid=%u, res=%#llx, retries=%u, flags=0x%x, status=%#x" , |
109 | __entry->ctrl_id, __print_disk_name(__entry->disk), |
110 | __entry->qid, __entry->cid, __entry->result, |
111 | __entry->retries, __entry->flags, __entry->status) |
112 | |
113 | ); |
114 | |
115 | #define aer_name(aer) { aer, #aer } |
116 | |
117 | TRACE_EVENT(nvme_async_event, |
118 | TP_PROTO(struct nvme_ctrl *ctrl, u32 result), |
119 | TP_ARGS(ctrl, result), |
120 | TP_STRUCT__entry( |
121 | __field(int, ctrl_id) |
122 | __field(u32, result) |
123 | ), |
124 | TP_fast_assign( |
125 | __entry->ctrl_id = ctrl->instance; |
126 | __entry->result = result; |
127 | ), |
128 | TP_printk("nvme%d: NVME_AEN=%#08x [%s]" , |
129 | __entry->ctrl_id, __entry->result, |
130 | __print_symbolic(__entry->result & 0x7, |
131 | aer_name(NVME_AER_ERROR), |
132 | aer_name(NVME_AER_SMART), |
133 | aer_name(NVME_AER_NOTICE), |
134 | aer_name(NVME_AER_CSS), |
135 | aer_name(NVME_AER_VS)) |
136 | ) |
137 | ); |
138 | |
139 | #undef aer_name |
140 | |
141 | TRACE_EVENT(nvme_sq, |
142 | TP_PROTO(struct request *req, __le16 sq_head, int sq_tail), |
143 | TP_ARGS(req, sq_head, sq_tail), |
144 | TP_STRUCT__entry( |
145 | __field(int, ctrl_id) |
146 | __array(char, disk, DISK_NAME_LEN) |
147 | __field(int, qid) |
148 | __field(u16, sq_head) |
149 | __field(u16, sq_tail) |
150 | ), |
151 | TP_fast_assign( |
152 | __entry->ctrl_id = nvme_req(req)->ctrl->instance; |
153 | __assign_disk_name(__entry->disk, req->q->disk); |
154 | __entry->qid = nvme_req_qid(req); |
155 | __entry->sq_head = le16_to_cpu(sq_head); |
156 | __entry->sq_tail = sq_tail; |
157 | ), |
158 | TP_printk("nvme%d: %sqid=%d, head=%u, tail=%u" , |
159 | __entry->ctrl_id, __print_disk_name(__entry->disk), |
160 | __entry->qid, __entry->sq_head, __entry->sq_tail |
161 | ) |
162 | ); |
163 | |
164 | #endif /* _TRACE_NVME_H */ |
165 | |
166 | #undef TRACE_INCLUDE_PATH |
167 | #define TRACE_INCLUDE_PATH . |
168 | #undef TRACE_INCLUDE_FILE |
169 | #define TRACE_INCLUDE_FILE trace |
170 | |
171 | /* This part must be outside protection */ |
172 | #include <trace/define_trace.h> |
173 | |