]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/ftl/ftl_trace.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / lib / ftl / ftl_trace.c
1 /*-
2 * BSD LICENSE
3 *
4 * Copyright (c) Intel Corporation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include "spdk/trace.h"
35
36 #include "ftl_core.h"
37 #include "ftl_trace.h"
38 #include "ftl_io.h"
39 #include "ftl_band.h"
40
41 #if defined(DEBUG)
42
43 #define OWNER_FTL 0x20
44 #define TRACE_GROUP_FTL 0x6
45
46 enum ftl_trace_source {
47 FTL_TRACE_SOURCE_INTERNAL,
48 FTL_TRACE_SOURCE_USER,
49 FTL_TRACE_SOURCE_MAX,
50 };
51
52 #define FTL_TPOINT_ID(id, src) SPDK_TPOINT_ID(TRACE_GROUP_FTL, (((id) << 1) | (!!(src))))
53
54 #define FTL_TRACE_BAND_DEFRAG(src) FTL_TPOINT_ID(0, src)
55 #define FTL_TRACE_BAND_WRITE(src) FTL_TPOINT_ID(1, src)
56 #define FTL_TRACE_LIMITS(src) FTL_TPOINT_ID(2, src)
57 #define FTL_TRACE_WBUF_POP(src) FTL_TPOINT_ID(3, src)
58
59 #define FTL_TRACE_READ_SCHEDULE(src) FTL_TPOINT_ID(4, src)
60 #define FTL_TRACE_READ_SUBMISSION(src) FTL_TPOINT_ID(5, src)
61 #define FTL_TRACE_READ_COMPLETION_INVALID(src) FTL_TPOINT_ID(6, src)
62 #define FTL_TRACE_READ_COMPLETION_CACHE(src) FTL_TPOINT_ID(7, src)
63 #define FTL_TRACE_READ_COMPLETION_DISK(src) FTL_TPOINT_ID(8, src)
64
65 #define FTL_TRACE_MD_READ_SCHEDULE(src) FTL_TPOINT_ID(9, src)
66 #define FTL_TRACE_MD_READ_SUBMISSION(src) FTL_TPOINT_ID(10, src)
67 #define FTL_TRACE_MD_READ_COMPLETION(src) FTL_TPOINT_ID(11, src)
68
69 #define FTL_TRACE_WRITE_SCHEDULE(src) FTL_TPOINT_ID(12, src)
70 #define FTL_TRACE_WRITE_WBUF_FILL(src) FTL_TPOINT_ID(13, src)
71 #define FTL_TRACE_WRITE_SUBMISSION(src) FTL_TPOINT_ID(14, src)
72 #define FTL_TRACE_WRITE_COMPLETION(src) FTL_TPOINT_ID(15, src)
73
74 #define FTL_TRACE_MD_WRITE_SCHEDULE(src) FTL_TPOINT_ID(16, src)
75 #define FTL_TRACE_MD_WRITE_SUBMISSION(src) FTL_TPOINT_ID(17, src)
76 #define FTL_TRACE_MD_WRITE_COMPLETION(src) FTL_TPOINT_ID(18, src)
77
78 #define FTL_TRACE_ERASE_SUBMISSION(src) FTL_TPOINT_ID(19, src)
79 #define FTL_TRACE_ERASE_COMPLETION(src) FTL_TPOINT_ID(20, src)
80
81 SPDK_TRACE_REGISTER_FN(ftl_trace_func, "ftl", TRACE_GROUP_FTL)
82 {
83 const char source[] = { 'i', 'u' };
84 char descbuf[128];
85 int i;
86
87 spdk_trace_register_owner(OWNER_FTL, 'f');
88
89 for (i = 0; i < FTL_TRACE_SOURCE_MAX; ++i) {
90 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "band_defrag");
91 spdk_trace_register_description(descbuf, FTL_TRACE_BAND_DEFRAG(i),
92 OWNER_FTL, OBJECT_NONE, 0, 0, "band: ");
93 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "band_write");
94 spdk_trace_register_description(descbuf, FTL_TRACE_BAND_WRITE(i),
95 OWNER_FTL, OBJECT_NONE, 0, 0, "band: ");
96 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "limits");
97 spdk_trace_register_description(descbuf, FTL_TRACE_LIMITS(i),
98 OWNER_FTL, OBJECT_NONE, 0, 0, "limits: ");
99 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "rwb_pop");
100 spdk_trace_register_description(descbuf, FTL_TRACE_WBUF_POP(i),
101 OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
102
103 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_sched");
104 spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_SCHEDULE(i),
105 OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
106 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_submit");
107 spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_SUBMISSION(i),
108 OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
109 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_cmpl");
110 spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_COMPLETION(i),
111 OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
112
113 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_sched");
114 spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_SCHEDULE(i),
115 OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
116 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_submit");
117 spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_SUBMISSION(i),
118 OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
119 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_cmpl");
120 spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_COMPLETION(i),
121 OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
122
123 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_sched");
124 spdk_trace_register_description(descbuf, FTL_TRACE_READ_SCHEDULE(i),
125 OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
126 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_submit");
127 spdk_trace_register_description(descbuf, FTL_TRACE_READ_SUBMISSION(i),
128 OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
129 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_cmpl_invld");
130 spdk_trace_register_description(descbuf, FTL_TRACE_READ_COMPLETION_INVALID(i),
131 OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
132 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_cmpl_cache");
133 spdk_trace_register_description(descbuf, FTL_TRACE_READ_COMPLETION_CACHE(i),
134 OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
135 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_cmpl_ssd");
136 spdk_trace_register_description(descbuf, FTL_TRACE_READ_COMPLETION_DISK(i),
137 OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
138
139 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "write_sched");
140 spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_SCHEDULE(i),
141 OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
142 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "rwb_fill");
143 spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_WBUF_FILL(i),
144 OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
145 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "write_submit");
146 spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_SUBMISSION(i),
147 OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
148 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "write_cmpl");
149 spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_COMPLETION(i),
150 OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
151
152 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "erase_submit");
153 spdk_trace_register_description(descbuf, FTL_TRACE_ERASE_SUBMISSION(i),
154 OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
155 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "erase_cmpl");
156 spdk_trace_register_description(descbuf, FTL_TRACE_ERASE_COMPLETION(i),
157 OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
158 }
159 }
160
161 static uint16_t
162 ftl_trace_io_source(const struct ftl_io *io)
163 {
164 if (io->flags & FTL_IO_INTERNAL) {
165 return FTL_TRACE_SOURCE_INTERNAL;
166 } else {
167 return FTL_TRACE_SOURCE_USER;
168 }
169 }
170
171 static uint64_t
172 ftl_trace_next_id(struct ftl_trace *trace)
173 {
174 assert(trace->id != FTL_TRACE_INVALID_ID);
175 return __atomic_fetch_add(&trace->id, 1, __ATOMIC_SEQ_CST);
176 }
177
178 void
179 ftl_trace_defrag_band(struct spdk_ftl_dev *dev, const struct ftl_band *band)
180 {
181 struct ftl_trace *trace = &dev->stats.trace;
182
183 spdk_trace_record(FTL_TRACE_BAND_DEFRAG(FTL_TRACE_SOURCE_INTERNAL),
184 ftl_trace_next_id(trace), 0, band->lba_map.num_vld, band->id);
185 }
186
187 void
188 ftl_trace_write_band(struct spdk_ftl_dev *dev, const struct ftl_band *band)
189 {
190 struct ftl_trace *trace = &dev->stats.trace;
191
192 spdk_trace_record(FTL_TRACE_BAND_WRITE(FTL_TRACE_SOURCE_INTERNAL),
193 ftl_trace_next_id(trace), 0, 0, band->id);
194 }
195
196 void
197 ftl_trace_lba_io_init(struct spdk_ftl_dev *dev, const struct ftl_io *io)
198 {
199 uint16_t tpoint_id = 0, source;
200
201 assert(io->trace != FTL_TRACE_INVALID_ID);
202 source = ftl_trace_io_source(io);
203
204 if (io->flags & FTL_IO_MD) {
205 switch (io->type) {
206 case FTL_IO_READ:
207 tpoint_id = FTL_TRACE_MD_READ_SCHEDULE(source);
208 break;
209 case FTL_IO_WRITE:
210 tpoint_id = FTL_TRACE_MD_WRITE_SCHEDULE(source);
211 break;
212 default:
213 assert(0);
214 }
215 } else {
216 switch (io->type) {
217 case FTL_IO_READ:
218 tpoint_id = FTL_TRACE_READ_SCHEDULE(source);
219 break;
220 case FTL_IO_WRITE:
221 tpoint_id = FTL_TRACE_WRITE_SCHEDULE(source);
222 break;
223 default:
224 assert(0);
225 }
226 }
227
228 spdk_trace_record(tpoint_id, io->trace, io->num_blocks, 0, ftl_io_get_lba(io, 0));
229 }
230
231 void
232 ftl_trace_wbuf_fill(struct spdk_ftl_dev *dev, const struct ftl_io *io)
233 {
234 assert(io->trace != FTL_TRACE_INVALID_ID);
235
236 spdk_trace_record(FTL_TRACE_WRITE_WBUF_FILL(ftl_trace_io_source(io)), io->trace,
237 0, 0, ftl_io_current_lba(io));
238 }
239
240 void
241 ftl_trace_wbuf_pop(struct spdk_ftl_dev *dev, const struct ftl_wbuf_entry *entry)
242 {
243 uint16_t tpoint_id;
244
245 assert(entry->trace != FTL_TRACE_INVALID_ID);
246
247 if (entry->io_flags & FTL_IO_INTERNAL) {
248 tpoint_id = FTL_TRACE_WBUF_POP(FTL_TRACE_SOURCE_INTERNAL);
249 } else {
250 tpoint_id = FTL_TRACE_WBUF_POP(FTL_TRACE_SOURCE_USER);
251 }
252
253 spdk_trace_record(tpoint_id, entry->trace, 0, entry->addr.offset, entry->lba);
254 }
255
256 void
257 ftl_trace_completion(struct spdk_ftl_dev *dev, const struct ftl_io *io,
258 enum ftl_trace_completion completion)
259 {
260 uint16_t tpoint_id = 0, source;
261
262 assert(io->trace != FTL_TRACE_INVALID_ID);
263 source = ftl_trace_io_source(io);
264
265 if (io->flags & FTL_IO_MD) {
266 switch (io->type) {
267 case FTL_IO_READ:
268 tpoint_id = FTL_TRACE_MD_READ_COMPLETION(source);
269 break;
270 case FTL_IO_WRITE:
271 tpoint_id = FTL_TRACE_MD_WRITE_COMPLETION(source);
272 break;
273 default:
274 assert(0);
275 }
276 } else {
277 switch (io->type) {
278 case FTL_IO_READ:
279 switch (completion) {
280 case FTL_TRACE_COMPLETION_INVALID:
281 tpoint_id = FTL_TRACE_READ_COMPLETION_INVALID(source);
282 break;
283 case FTL_TRACE_COMPLETION_CACHE:
284 tpoint_id = FTL_TRACE_READ_COMPLETION_CACHE(source);
285 break;
286 case FTL_TRACE_COMPLETION_DISK:
287 tpoint_id = FTL_TRACE_READ_COMPLETION_DISK(source);
288 break;
289 }
290 break;
291 case FTL_IO_WRITE:
292 tpoint_id = FTL_TRACE_WRITE_COMPLETION(source);
293 break;
294 case FTL_IO_ERASE:
295 tpoint_id = FTL_TRACE_ERASE_COMPLETION(source);
296 break;
297 default:
298 assert(0);
299 }
300 }
301
302 spdk_trace_record(tpoint_id, io->trace, 0, 0, ftl_io_get_lba(io, io->pos - 1));
303 }
304
305 void
306 ftl_trace_submission(struct spdk_ftl_dev *dev, const struct ftl_io *io, struct ftl_addr addr,
307 size_t addr_cnt)
308 {
309 uint16_t tpoint_id = 0, source;
310
311 assert(io->trace != FTL_TRACE_INVALID_ID);
312 source = ftl_trace_io_source(io);
313
314 if (io->flags & FTL_IO_MD) {
315 switch (io->type) {
316 case FTL_IO_READ:
317 tpoint_id = FTL_TRACE_MD_READ_SUBMISSION(source);
318 break;
319 case FTL_IO_WRITE:
320 tpoint_id = FTL_TRACE_MD_WRITE_SUBMISSION(source);
321 break;
322 default:
323 assert(0);
324 }
325 } else {
326 switch (io->type) {
327 case FTL_IO_READ:
328 tpoint_id = FTL_TRACE_READ_SUBMISSION(source);
329 break;
330 case FTL_IO_WRITE:
331 tpoint_id = FTL_TRACE_WRITE_SUBMISSION(source);
332 break;
333 case FTL_IO_ERASE:
334 tpoint_id = FTL_TRACE_ERASE_SUBMISSION(source);
335 break;
336 default:
337 assert(0);
338 }
339 }
340
341 spdk_trace_record(tpoint_id, io->trace, addr_cnt, 0, addr.offset);
342 }
343
344 void
345 ftl_trace_limits(struct spdk_ftl_dev *dev, int limit, size_t num_free)
346 {
347 struct ftl_trace *trace = &dev->stats.trace;
348
349 spdk_trace_record(FTL_TRACE_LIMITS(FTL_TRACE_SOURCE_INTERNAL), ftl_trace_next_id(trace),
350 num_free, limit, 0);
351 }
352
353 uint64_t
354 ftl_trace_alloc_id(struct spdk_ftl_dev *dev)
355 {
356 struct ftl_trace *trace = &dev->stats.trace;
357
358 return ftl_trace_next_id(trace);
359 }
360
361 #endif /* defined(DEBUG) */