1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/trace.h" 7 #include "spdk_internal/trace_defs.h" 8 9 #include "ftl_core.h" 10 #include "ftl_trace.h" 11 #include "ftl_io.h" 12 #include "ftl_band.h" 13 14 #if defined(DEBUG) 15 16 enum ftl_trace_source { 17 FTL_TRACE_SOURCE_INTERNAL, 18 FTL_TRACE_SOURCE_USER, 19 FTL_TRACE_SOURCE_MAX, 20 }; 21 22 #define FTL_TPOINT_ID(id, src) SPDK_TPOINT_ID(TRACE_GROUP_FTL, (((id) << 1) | (!!(src)))) 23 24 #define FTL_TRACE_BAND_RELOC(src) FTL_TPOINT_ID(0, src) 25 #define FTL_TRACE_BAND_WRITE(src) FTL_TPOINT_ID(1, src) 26 #define FTL_TRACE_LIMITS(src) FTL_TPOINT_ID(2, src) 27 #define FTL_TRACE_WBUF_POP(src) FTL_TPOINT_ID(3, src) 28 29 #define FTL_TRACE_READ_SCHEDULE(src) FTL_TPOINT_ID(4, src) 30 #define FTL_TRACE_READ_SUBMISSION(src) FTL_TPOINT_ID(5, src) 31 #define FTL_TRACE_READ_COMPLETION_INVALID(src) FTL_TPOINT_ID(6, src) 32 #define FTL_TRACE_READ_COMPLETION_CACHE(src) FTL_TPOINT_ID(7, src) 33 #define FTL_TRACE_READ_COMPLETION_DISK(src) FTL_TPOINT_ID(8, src) 34 35 #define FTL_TRACE_MD_READ_SCHEDULE(src) FTL_TPOINT_ID(9, src) 36 #define FTL_TRACE_MD_READ_SUBMISSION(src) FTL_TPOINT_ID(10, src) 37 #define FTL_TRACE_MD_READ_COMPLETION(src) FTL_TPOINT_ID(11, src) 38 39 #define FTL_TRACE_WRITE_SCHEDULE(src) FTL_TPOINT_ID(12, src) 40 #define FTL_TRACE_WRITE_WBUF_FILL(src) FTL_TPOINT_ID(13, src) 41 #define FTL_TRACE_WRITE_SUBMISSION(src) FTL_TPOINT_ID(14, src) 42 #define FTL_TRACE_WRITE_COMPLETION(src) FTL_TPOINT_ID(15, src) 43 44 #define FTL_TRACE_MD_WRITE_SCHEDULE(src) FTL_TPOINT_ID(16, src) 45 #define FTL_TRACE_MD_WRITE_SUBMISSION(src) FTL_TPOINT_ID(17, src) 46 #define FTL_TRACE_MD_WRITE_COMPLETION(src) FTL_TPOINT_ID(18, src) 47 48 #define FTL_TRACE_UNMAP_SCHEDULE(src) FTL_TPOINT_ID(19, src) 49 #define FTL_TRACE_UNMAP_SUBMISSION(src) FTL_TPOINT_ID(20, src) 50 #define FTL_TRACE_UNMAP_COMPLETION(src) FTL_TPOINT_ID(21, src) 51 52 SPDK_TRACE_REGISTER_FN(ftl_trace_func, "ftl", TRACE_GROUP_FTL) 53 { 54 const char source[] = { 'i', 'u' }; 55 char descbuf[128]; 56 int i; 57 58 spdk_trace_register_owner(OWNER_FTL, 'f'); 59 60 for (i = 0; i < FTL_TRACE_SOURCE_MAX; ++i) { 61 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "band_reloc"); 62 spdk_trace_register_description(descbuf, FTL_TRACE_BAND_RELOC(i), OWNER_FTL, OBJECT_NONE, 0, 0, 63 "band: "); 64 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "band_write"); 65 spdk_trace_register_description(descbuf, FTL_TRACE_BAND_WRITE(i), OWNER_FTL, OBJECT_NONE, 0, 0, 66 "band: "); 67 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "limits"); 68 spdk_trace_register_description(descbuf, FTL_TRACE_LIMITS(i), OWNER_FTL, OBJECT_NONE, 0, 0, 69 "limits: "); 70 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "rwb_pop"); 71 spdk_trace_register_description(descbuf, FTL_TRACE_WBUF_POP(i), OWNER_FTL, OBJECT_NONE, 0, 0, 72 "lba: "); 73 74 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_sched"); 75 spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_SCHEDULE(i), OWNER_FTL, OBJECT_NONE, 0, 76 0, "addr: "); 77 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_submit"); 78 spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_SUBMISSION(i), OWNER_FTL, OBJECT_NONE, 0, 79 0, "addr: "); 80 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_cmpl"); 81 spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_COMPLETION(i), OWNER_FTL, OBJECT_NONE, 0, 82 0, "lba: "); 83 84 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_sched"); 85 spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_SCHEDULE(i), OWNER_FTL, OBJECT_NONE, 0, 86 0, "addr: "); 87 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_submit"); 88 spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_SUBMISSION(i), OWNER_FTL, OBJECT_NONE, 89 0, 0, "addr: "); 90 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_cmpl"); 91 spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_COMPLETION(i), OWNER_FTL, OBJECT_NONE, 92 0, 0, "lba: "); 93 94 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_sched"); 95 spdk_trace_register_description(descbuf, FTL_TRACE_READ_SCHEDULE(i), OWNER_FTL, OBJECT_NONE, 0, 0, 96 "lba: "); 97 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_submit"); 98 spdk_trace_register_description(descbuf, FTL_TRACE_READ_SUBMISSION(i), OWNER_FTL, OBJECT_NONE, 0, 0, 99 "addr: "); 100 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_cmpl_invld"); 101 spdk_trace_register_description(descbuf, FTL_TRACE_READ_COMPLETION_INVALID(i), OWNER_FTL, 102 OBJECT_NONE, 0, 0, "lba: "); 103 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_cmpl_cache"); 104 spdk_trace_register_description(descbuf, FTL_TRACE_READ_COMPLETION_CACHE(i), OWNER_FTL, OBJECT_NONE, 105 0, 0, "lba: "); 106 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_cmpl_ssd"); 107 spdk_trace_register_description(descbuf, FTL_TRACE_READ_COMPLETION_DISK(i), OWNER_FTL, OBJECT_NONE, 108 0, 0, "lba: "); 109 110 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "write_sched"); 111 spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_SCHEDULE(i), OWNER_FTL, OBJECT_NONE, 0, 0, 112 "lba: "); 113 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "rwb_fill"); 114 spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_WBUF_FILL(i), OWNER_FTL, OBJECT_NONE, 0, 0, 115 "lba: "); 116 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "write_submit"); 117 spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_SUBMISSION(i), OWNER_FTL, OBJECT_NONE, 0, 118 0, "addr: "); 119 snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "write_cmpl"); 120 spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_COMPLETION(i), OWNER_FTL, OBJECT_NONE, 0, 121 0, "lba: "); 122 } 123 } 124 125 static uint64_t 126 ftl_trace_next_id(struct ftl_trace *trace) 127 { 128 assert(trace->id != FTL_TRACE_INVALID_ID); 129 return __atomic_fetch_add(&trace->id, 1, __ATOMIC_SEQ_CST); 130 } 131 132 void 133 ftl_trace_reloc_band(struct spdk_ftl_dev *dev, const struct ftl_band *band) 134 { 135 struct ftl_trace *trace = &dev->trace; 136 137 spdk_trace_record(FTL_TRACE_BAND_RELOC(FTL_TRACE_SOURCE_INTERNAL), ftl_trace_next_id(trace), 0, 138 band->p2l_map.num_valid, band->id); 139 } 140 141 void 142 ftl_trace_write_band(struct spdk_ftl_dev *dev, const struct ftl_band *band) 143 { 144 struct ftl_trace *trace = &dev->trace; 145 146 spdk_trace_record(FTL_TRACE_BAND_WRITE(FTL_TRACE_SOURCE_INTERNAL), ftl_trace_next_id(trace), 0, 0, 147 band->id); 148 } 149 150 void 151 ftl_trace_lba_io_init(struct spdk_ftl_dev *dev, const struct ftl_io *io) 152 { 153 uint16_t tpoint_id = 0, source; 154 155 assert(io->trace != FTL_TRACE_INVALID_ID); 156 source = FTL_TRACE_SOURCE_USER; 157 158 switch (io->type) { 159 case FTL_IO_READ: 160 tpoint_id = FTL_TRACE_READ_SCHEDULE(source); 161 break; 162 case FTL_IO_WRITE: 163 tpoint_id = FTL_TRACE_WRITE_SCHEDULE(source); 164 break; 165 case FTL_IO_UNMAP: 166 tpoint_id = FTL_TRACE_UNMAP_SCHEDULE(source); 167 break; 168 default: 169 assert(0); 170 } 171 172 spdk_trace_record(tpoint_id, io->trace, io->num_blocks, 0, ftl_io_get_lba(io, 0)); 173 } 174 175 void 176 ftl_trace_completion(struct spdk_ftl_dev *dev, const struct ftl_io *io, 177 enum ftl_trace_completion completion) 178 { 179 uint16_t tpoint_id = 0, source; 180 181 assert(io->trace != FTL_TRACE_INVALID_ID); 182 source = FTL_TRACE_SOURCE_USER; 183 184 switch (io->type) { 185 case FTL_IO_READ: 186 switch (completion) { 187 case FTL_TRACE_COMPLETION_INVALID: 188 tpoint_id = FTL_TRACE_READ_COMPLETION_INVALID(source); 189 break; 190 case FTL_TRACE_COMPLETION_CACHE: 191 tpoint_id = FTL_TRACE_READ_COMPLETION_CACHE(source); 192 break; 193 case FTL_TRACE_COMPLETION_DISK: 194 tpoint_id = FTL_TRACE_READ_COMPLETION_DISK(source); 195 break; 196 } 197 break; 198 case FTL_IO_WRITE: 199 tpoint_id = FTL_TRACE_WRITE_COMPLETION(source); 200 break; 201 case FTL_IO_UNMAP: 202 tpoint_id = FTL_TRACE_UNMAP_COMPLETION(source); 203 break; 204 default: 205 assert(0); 206 } 207 208 spdk_trace_record(tpoint_id, io->trace, 0, 0, ftl_io_get_lba(io, io->pos - 1)); 209 } 210 211 void 212 ftl_trace_submission(struct spdk_ftl_dev *dev, const struct ftl_io *io, ftl_addr addr, 213 size_t addr_cnt) 214 { 215 uint16_t tpoint_id = 0, source; 216 217 assert(io->trace != FTL_TRACE_INVALID_ID); 218 source = FTL_TRACE_SOURCE_USER; 219 220 switch (io->type) { 221 case FTL_IO_READ: 222 tpoint_id = FTL_TRACE_READ_SUBMISSION(source); 223 break; 224 case FTL_IO_WRITE: 225 tpoint_id = FTL_TRACE_WRITE_SUBMISSION(source); 226 break; 227 case FTL_IO_UNMAP: 228 tpoint_id = FTL_TRACE_UNMAP_SUBMISSION(source); 229 break; 230 default: 231 assert(0); 232 } 233 234 spdk_trace_record(tpoint_id, io->trace, addr_cnt, 0, addr); 235 } 236 237 void 238 ftl_trace_limits(struct spdk_ftl_dev *dev, int limit, size_t num_free) 239 { 240 struct ftl_trace *trace = &dev->trace; 241 242 spdk_trace_record(FTL_TRACE_LIMITS(FTL_TRACE_SOURCE_INTERNAL), ftl_trace_next_id(trace), num_free, 243 limit, 0); 244 } 245 246 uint64_t 247 ftl_trace_alloc_id(struct spdk_ftl_dev *dev) 248 { 249 struct ftl_trace *trace = &dev->trace; 250 251 return ftl_trace_next_id(trace); 252 } 253 254 #endif /* defined(DEBUG) */ 255