xref: /spdk/lib/ftl/ftl_trace.c (revision 2f5c602574a98ede645991abe279a96e19c50196)
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,
93 						SPDK_TRACE_ARG_TYPE_INT, "band");
94 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "band_write");
95 		spdk_trace_register_description(descbuf, FTL_TRACE_BAND_WRITE(i),
96 						OWNER_FTL, OBJECT_NONE, 0,
97 						SPDK_TRACE_ARG_TYPE_INT, "band");
98 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "limits");
99 		spdk_trace_register_description(descbuf, FTL_TRACE_LIMITS(i),
100 						OWNER_FTL, OBJECT_NONE, 0,
101 						SPDK_TRACE_ARG_TYPE_INT, "limits");
102 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "rwb_pop");
103 		spdk_trace_register_description(descbuf, FTL_TRACE_WBUF_POP(i),
104 						OWNER_FTL, OBJECT_NONE, 0,
105 						SPDK_TRACE_ARG_TYPE_INT, "lba");
106 
107 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_sched");
108 		spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_SCHEDULE(i),
109 						OWNER_FTL, OBJECT_NONE, 0,
110 						SPDK_TRACE_ARG_TYPE_INT, "addr");
111 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_submit");
112 		spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_SUBMISSION(i),
113 						OWNER_FTL, OBJECT_NONE, 0,
114 						SPDK_TRACE_ARG_TYPE_INT, "addr");
115 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_cmpl");
116 		spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_COMPLETION(i),
117 						OWNER_FTL, OBJECT_NONE, 0,
118 						SPDK_TRACE_ARG_TYPE_INT, "lba");
119 
120 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_sched");
121 		spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_SCHEDULE(i),
122 						OWNER_FTL, OBJECT_NONE, 0,
123 						SPDK_TRACE_ARG_TYPE_INT, "addr");
124 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_submit");
125 		spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_SUBMISSION(i),
126 						OWNER_FTL, OBJECT_NONE, 0,
127 						SPDK_TRACE_ARG_TYPE_INT, "addr");
128 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_cmpl");
129 		spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_COMPLETION(i),
130 						OWNER_FTL, OBJECT_NONE, 0,
131 						SPDK_TRACE_ARG_TYPE_INT, "lba");
132 
133 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_sched");
134 		spdk_trace_register_description(descbuf, FTL_TRACE_READ_SCHEDULE(i),
135 						OWNER_FTL, OBJECT_NONE, 0,
136 						SPDK_TRACE_ARG_TYPE_INT, "lba");
137 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_submit");
138 		spdk_trace_register_description(descbuf, FTL_TRACE_READ_SUBMISSION(i),
139 						OWNER_FTL, OBJECT_NONE, 0,
140 						SPDK_TRACE_ARG_TYPE_INT, "addr");
141 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_cmpl_invld");
142 		spdk_trace_register_description(descbuf, FTL_TRACE_READ_COMPLETION_INVALID(i),
143 						OWNER_FTL, OBJECT_NONE, 0,
144 						SPDK_TRACE_ARG_TYPE_INT, "lba");
145 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_cmpl_cache");
146 		spdk_trace_register_description(descbuf, FTL_TRACE_READ_COMPLETION_CACHE(i),
147 						OWNER_FTL, OBJECT_NONE, 0,
148 						SPDK_TRACE_ARG_TYPE_INT, "lba");
149 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_cmpl_ssd");
150 		spdk_trace_register_description(descbuf, FTL_TRACE_READ_COMPLETION_DISK(i),
151 						OWNER_FTL, OBJECT_NONE, 0,
152 						SPDK_TRACE_ARG_TYPE_INT, "lba");
153 
154 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "write_sched");
155 		spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_SCHEDULE(i),
156 						OWNER_FTL, OBJECT_NONE, 0,
157 						SPDK_TRACE_ARG_TYPE_INT, "lba");
158 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "rwb_fill");
159 		spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_WBUF_FILL(i),
160 						OWNER_FTL, OBJECT_NONE, 0,
161 						SPDK_TRACE_ARG_TYPE_INT, "lba");
162 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "write_submit");
163 		spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_SUBMISSION(i),
164 						OWNER_FTL, OBJECT_NONE, 0,
165 						SPDK_TRACE_ARG_TYPE_INT, "addr");
166 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "write_cmpl");
167 		spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_COMPLETION(i),
168 						OWNER_FTL, OBJECT_NONE, 0,
169 						SPDK_TRACE_ARG_TYPE_INT, "lba");
170 
171 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "erase_submit");
172 		spdk_trace_register_description(descbuf, FTL_TRACE_ERASE_SUBMISSION(i),
173 						OWNER_FTL, OBJECT_NONE, 0,
174 						SPDK_TRACE_ARG_TYPE_INT, "addr");
175 		snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "erase_cmpl");
176 		spdk_trace_register_description(descbuf, FTL_TRACE_ERASE_COMPLETION(i),
177 						OWNER_FTL, OBJECT_NONE, 0,
178 						SPDK_TRACE_ARG_TYPE_INT, "addr");
179 	}
180 }
181 
182 static uint16_t
183 ftl_trace_io_source(const struct ftl_io *io)
184 {
185 	if (io->flags & FTL_IO_INTERNAL) {
186 		return FTL_TRACE_SOURCE_INTERNAL;
187 	} else {
188 		return FTL_TRACE_SOURCE_USER;
189 	}
190 }
191 
192 static uint64_t
193 ftl_trace_next_id(struct ftl_trace *trace)
194 {
195 	assert(trace->id != FTL_TRACE_INVALID_ID);
196 	return __atomic_fetch_add(&trace->id, 1, __ATOMIC_SEQ_CST);
197 }
198 
199 void
200 ftl_trace_defrag_band(struct spdk_ftl_dev *dev, const struct ftl_band *band)
201 {
202 	struct ftl_trace *trace = &dev->stats.trace;
203 
204 	spdk_trace_record(FTL_TRACE_BAND_DEFRAG(FTL_TRACE_SOURCE_INTERNAL),
205 			  ftl_trace_next_id(trace), 0, band->lba_map.num_vld, band->id);
206 }
207 
208 void
209 ftl_trace_write_band(struct spdk_ftl_dev *dev, const struct ftl_band *band)
210 {
211 	struct ftl_trace *trace = &dev->stats.trace;
212 
213 	spdk_trace_record(FTL_TRACE_BAND_WRITE(FTL_TRACE_SOURCE_INTERNAL),
214 			  ftl_trace_next_id(trace), 0, 0, band->id);
215 }
216 
217 void
218 ftl_trace_lba_io_init(struct spdk_ftl_dev *dev, const struct ftl_io *io)
219 {
220 	uint16_t tpoint_id = 0, source;
221 
222 	assert(io->trace != FTL_TRACE_INVALID_ID);
223 	source = ftl_trace_io_source(io);
224 
225 	if (io->flags & FTL_IO_MD) {
226 		switch (io->type) {
227 		case FTL_IO_READ:
228 			tpoint_id = FTL_TRACE_MD_READ_SCHEDULE(source);
229 			break;
230 		case FTL_IO_WRITE:
231 			tpoint_id = FTL_TRACE_MD_WRITE_SCHEDULE(source);
232 			break;
233 		default:
234 			assert(0);
235 		}
236 	} else {
237 		switch (io->type) {
238 		case FTL_IO_READ:
239 			tpoint_id = FTL_TRACE_READ_SCHEDULE(source);
240 			break;
241 		case FTL_IO_WRITE:
242 			tpoint_id = FTL_TRACE_WRITE_SCHEDULE(source);
243 			break;
244 		default:
245 			assert(0);
246 		}
247 	}
248 
249 	spdk_trace_record(tpoint_id, io->trace, io->num_blocks, 0, ftl_io_get_lba(io, 0));
250 }
251 
252 void
253 ftl_trace_wbuf_fill(struct spdk_ftl_dev *dev, const struct ftl_io *io)
254 {
255 	assert(io->trace != FTL_TRACE_INVALID_ID);
256 
257 	spdk_trace_record(FTL_TRACE_WRITE_WBUF_FILL(ftl_trace_io_source(io)), io->trace,
258 			  0, 0, ftl_io_current_lba(io));
259 }
260 
261 void
262 ftl_trace_wbuf_pop(struct spdk_ftl_dev *dev, const struct ftl_wbuf_entry *entry)
263 {
264 	uint16_t tpoint_id;
265 
266 	assert(entry->trace != FTL_TRACE_INVALID_ID);
267 
268 	if (entry->io_flags & FTL_IO_INTERNAL) {
269 		tpoint_id = FTL_TRACE_WBUF_POP(FTL_TRACE_SOURCE_INTERNAL);
270 	} else {
271 		tpoint_id = FTL_TRACE_WBUF_POP(FTL_TRACE_SOURCE_USER);
272 	}
273 
274 	spdk_trace_record(tpoint_id, entry->trace, 0, entry->addr.offset, entry->lba);
275 }
276 
277 void
278 ftl_trace_completion(struct spdk_ftl_dev *dev, const struct ftl_io *io,
279 		     enum ftl_trace_completion completion)
280 {
281 	uint16_t tpoint_id = 0, source;
282 
283 	assert(io->trace != FTL_TRACE_INVALID_ID);
284 	source = ftl_trace_io_source(io);
285 
286 	if (io->flags & FTL_IO_MD) {
287 		switch (io->type) {
288 		case FTL_IO_READ:
289 			tpoint_id = FTL_TRACE_MD_READ_COMPLETION(source);
290 			break;
291 		case FTL_IO_WRITE:
292 			tpoint_id = FTL_TRACE_MD_WRITE_COMPLETION(source);
293 			break;
294 		default:
295 			assert(0);
296 		}
297 	} else {
298 		switch (io->type) {
299 		case FTL_IO_READ:
300 			switch (completion) {
301 			case FTL_TRACE_COMPLETION_INVALID:
302 				tpoint_id = FTL_TRACE_READ_COMPLETION_INVALID(source);
303 				break;
304 			case FTL_TRACE_COMPLETION_CACHE:
305 				tpoint_id = FTL_TRACE_READ_COMPLETION_CACHE(source);
306 				break;
307 			case FTL_TRACE_COMPLETION_DISK:
308 				tpoint_id = FTL_TRACE_READ_COMPLETION_DISK(source);
309 				break;
310 			}
311 			break;
312 		case FTL_IO_WRITE:
313 			tpoint_id = FTL_TRACE_WRITE_COMPLETION(source);
314 			break;
315 		case FTL_IO_ERASE:
316 			tpoint_id = FTL_TRACE_ERASE_COMPLETION(source);
317 			break;
318 		default:
319 			assert(0);
320 		}
321 	}
322 
323 	spdk_trace_record(tpoint_id, io->trace, 0, 0, ftl_io_get_lba(io, io->pos - 1));
324 }
325 
326 void
327 ftl_trace_submission(struct spdk_ftl_dev *dev, const struct ftl_io *io, struct ftl_addr addr,
328 		     size_t addr_cnt)
329 {
330 	uint16_t tpoint_id = 0, source;
331 
332 	assert(io->trace != FTL_TRACE_INVALID_ID);
333 	source = ftl_trace_io_source(io);
334 
335 	if (io->flags & FTL_IO_MD) {
336 		switch (io->type) {
337 		case FTL_IO_READ:
338 			tpoint_id = FTL_TRACE_MD_READ_SUBMISSION(source);
339 			break;
340 		case FTL_IO_WRITE:
341 			tpoint_id = FTL_TRACE_MD_WRITE_SUBMISSION(source);
342 			break;
343 		default:
344 			assert(0);
345 		}
346 	} else {
347 		switch (io->type) {
348 		case FTL_IO_READ:
349 			tpoint_id = FTL_TRACE_READ_SUBMISSION(source);
350 			break;
351 		case FTL_IO_WRITE:
352 			tpoint_id = FTL_TRACE_WRITE_SUBMISSION(source);
353 			break;
354 		case FTL_IO_ERASE:
355 			tpoint_id = FTL_TRACE_ERASE_SUBMISSION(source);
356 			break;
357 		default:
358 			assert(0);
359 		}
360 	}
361 
362 	spdk_trace_record(tpoint_id, io->trace, addr_cnt, 0, addr.offset);
363 }
364 
365 void
366 ftl_trace_limits(struct spdk_ftl_dev *dev, int limit, size_t num_free)
367 {
368 	struct ftl_trace *trace = &dev->stats.trace;
369 
370 	spdk_trace_record(FTL_TRACE_LIMITS(FTL_TRACE_SOURCE_INTERNAL), ftl_trace_next_id(trace),
371 			  num_free, limit, 0);
372 }
373 
374 uint64_t
375 ftl_trace_alloc_id(struct spdk_ftl_dev *dev)
376 {
377 	struct ftl_trace *trace = &dev->stats.trace;
378 
379 	return ftl_trace_next_id(trace);
380 }
381 
382 #endif /* defined(DEBUG) */
383