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