4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 #include "spdk/trace.h"
37 #include "ftl_trace.h"
43 #define OWNER_FTL 0x20
44 #define TRACE_GROUP_FTL 0x6
46 enum ftl_trace_source
{
47 FTL_TRACE_SOURCE_INTERNAL
,
48 FTL_TRACE_SOURCE_USER
,
52 #define FTL_TPOINT_ID(id, src) SPDK_TPOINT_ID(TRACE_GROUP_FTL, (((id) << 1) | (!!(src))))
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)
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)
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)
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)
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)
78 #define FTL_TRACE_ERASE_SUBMISSION(src) FTL_TPOINT_ID(19, src)
79 #define FTL_TRACE_ERASE_COMPLETION(src) FTL_TPOINT_ID(20, src)
81 SPDK_TRACE_REGISTER_FN(ftl_trace_func
, "ftl", TRACE_GROUP_FTL
)
83 const char source
[] = { 'i', 'u' };
87 spdk_trace_register_owner(OWNER_FTL
, 'f');
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: ");
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: ");
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: ");
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: ");
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: ");
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: ");
162 ftl_trace_io_source(const struct ftl_io
*io
)
164 if (io
->flags
& FTL_IO_INTERNAL
) {
165 return FTL_TRACE_SOURCE_INTERNAL
;
167 return FTL_TRACE_SOURCE_USER
;
172 ftl_trace_next_id(struct ftl_trace
*trace
)
174 assert(trace
->id
!= FTL_TRACE_INVALID_ID
);
175 return __atomic_fetch_add(&trace
->id
, 1, __ATOMIC_SEQ_CST
);
179 ftl_trace_defrag_band(struct spdk_ftl_dev
*dev
, const struct ftl_band
*band
)
181 struct ftl_trace
*trace
= &dev
->stats
.trace
;
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
);
188 ftl_trace_write_band(struct spdk_ftl_dev
*dev
, const struct ftl_band
*band
)
190 struct ftl_trace
*trace
= &dev
->stats
.trace
;
192 spdk_trace_record(FTL_TRACE_BAND_WRITE(FTL_TRACE_SOURCE_INTERNAL
),
193 ftl_trace_next_id(trace
), 0, 0, band
->id
);
197 ftl_trace_lba_io_init(struct spdk_ftl_dev
*dev
, const struct ftl_io
*io
)
199 uint16_t tpoint_id
= 0, source
;
201 assert(io
->trace
!= FTL_TRACE_INVALID_ID
);
202 source
= ftl_trace_io_source(io
);
204 if (io
->flags
& FTL_IO_MD
) {
207 tpoint_id
= FTL_TRACE_MD_READ_SCHEDULE(source
);
210 tpoint_id
= FTL_TRACE_MD_WRITE_SCHEDULE(source
);
218 tpoint_id
= FTL_TRACE_READ_SCHEDULE(source
);
221 tpoint_id
= FTL_TRACE_WRITE_SCHEDULE(source
);
228 spdk_trace_record(tpoint_id
, io
->trace
, io
->num_blocks
, 0, ftl_io_get_lba(io
, 0));
232 ftl_trace_wbuf_fill(struct spdk_ftl_dev
*dev
, const struct ftl_io
*io
)
234 assert(io
->trace
!= FTL_TRACE_INVALID_ID
);
236 spdk_trace_record(FTL_TRACE_WRITE_WBUF_FILL(ftl_trace_io_source(io
)), io
->trace
,
237 0, 0, ftl_io_current_lba(io
));
241 ftl_trace_wbuf_pop(struct spdk_ftl_dev
*dev
, const struct ftl_wbuf_entry
*entry
)
245 assert(entry
->trace
!= FTL_TRACE_INVALID_ID
);
247 if (entry
->io_flags
& FTL_IO_INTERNAL
) {
248 tpoint_id
= FTL_TRACE_WBUF_POP(FTL_TRACE_SOURCE_INTERNAL
);
250 tpoint_id
= FTL_TRACE_WBUF_POP(FTL_TRACE_SOURCE_USER
);
253 spdk_trace_record(tpoint_id
, entry
->trace
, 0, entry
->addr
.offset
, entry
->lba
);
257 ftl_trace_completion(struct spdk_ftl_dev
*dev
, const struct ftl_io
*io
,
258 enum ftl_trace_completion completion
)
260 uint16_t tpoint_id
= 0, source
;
262 assert(io
->trace
!= FTL_TRACE_INVALID_ID
);
263 source
= ftl_trace_io_source(io
);
265 if (io
->flags
& FTL_IO_MD
) {
268 tpoint_id
= FTL_TRACE_MD_READ_COMPLETION(source
);
271 tpoint_id
= FTL_TRACE_MD_WRITE_COMPLETION(source
);
279 switch (completion
) {
280 case FTL_TRACE_COMPLETION_INVALID
:
281 tpoint_id
= FTL_TRACE_READ_COMPLETION_INVALID(source
);
283 case FTL_TRACE_COMPLETION_CACHE
:
284 tpoint_id
= FTL_TRACE_READ_COMPLETION_CACHE(source
);
286 case FTL_TRACE_COMPLETION_DISK
:
287 tpoint_id
= FTL_TRACE_READ_COMPLETION_DISK(source
);
292 tpoint_id
= FTL_TRACE_WRITE_COMPLETION(source
);
295 tpoint_id
= FTL_TRACE_ERASE_COMPLETION(source
);
302 spdk_trace_record(tpoint_id
, io
->trace
, 0, 0, ftl_io_get_lba(io
, io
->pos
- 1));
306 ftl_trace_submission(struct spdk_ftl_dev
*dev
, const struct ftl_io
*io
, struct ftl_addr addr
,
309 uint16_t tpoint_id
= 0, source
;
311 assert(io
->trace
!= FTL_TRACE_INVALID_ID
);
312 source
= ftl_trace_io_source(io
);
314 if (io
->flags
& FTL_IO_MD
) {
317 tpoint_id
= FTL_TRACE_MD_READ_SUBMISSION(source
);
320 tpoint_id
= FTL_TRACE_MD_WRITE_SUBMISSION(source
);
328 tpoint_id
= FTL_TRACE_READ_SUBMISSION(source
);
331 tpoint_id
= FTL_TRACE_WRITE_SUBMISSION(source
);
334 tpoint_id
= FTL_TRACE_ERASE_SUBMISSION(source
);
341 spdk_trace_record(tpoint_id
, io
->trace
, addr_cnt
, 0, addr
.offset
);
345 ftl_trace_limits(struct spdk_ftl_dev
*dev
, int limit
, size_t num_free
)
347 struct ftl_trace
*trace
= &dev
->stats
.trace
;
349 spdk_trace_record(FTL_TRACE_LIMITS(FTL_TRACE_SOURCE_INTERNAL
), ftl_trace_next_id(trace
),
354 ftl_trace_alloc_id(struct spdk_ftl_dev
*dev
)
356 struct ftl_trace
*trace
= &dev
->stats
.trace
;
358 return ftl_trace_next_id(trace
);
361 #endif /* defined(DEBUG) */