1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 2022 NVIDIA Corporation & Affiliates 3 */ 4 5 #include "mlx5dr_internal.h" 6 7 const char *mlx5dr_debug_action_type_str[] = { 8 [MLX5DR_ACTION_TYP_LAST] = "LAST", 9 [MLX5DR_ACTION_TYP_TNL_L2_TO_L2] = "TNL_L2_TO_L2", 10 [MLX5DR_ACTION_TYP_L2_TO_TNL_L2] = "L2_TO_TNL_L2", 11 [MLX5DR_ACTION_TYP_TNL_L3_TO_L2] = "TNL_L3_TO_L2", 12 [MLX5DR_ACTION_TYP_L2_TO_TNL_L3] = "L2_TO_TNL_L3", 13 [MLX5DR_ACTION_TYP_DROP] = "DROP", 14 [MLX5DR_ACTION_TYP_TIR] = "TIR", 15 [MLX5DR_ACTION_TYP_FT] = "FT", 16 [MLX5DR_ACTION_TYP_CTR] = "CTR", 17 [MLX5DR_ACTION_TYP_TAG] = "TAG", 18 [MLX5DR_ACTION_TYP_MODIFY_HDR] = "MODIFY_HDR", 19 [MLX5DR_ACTION_TYP_VPORT] = "VPORT", 20 [MLX5DR_ACTION_TYP_MISS] = "DEFAULT_MISS", 21 [MLX5DR_ACTION_TYP_POP_VLAN] = "POP_VLAN", 22 [MLX5DR_ACTION_TYP_PUSH_VLAN] = "PUSH_VLAN", 23 [MLX5DR_ACTION_TYP_ASO_METER] = "ASO_METER", 24 [MLX5DR_ACTION_TYP_ASO_CT] = "ASO_CT", 25 }; 26 27 static_assert(ARRAY_SIZE(mlx5dr_debug_action_type_str) == MLX5DR_ACTION_TYP_MAX, 28 "Missing mlx5dr_debug_action_type_str"); 29 30 const char *mlx5dr_debug_action_type_to_str(enum mlx5dr_action_type action_type) 31 { 32 return mlx5dr_debug_action_type_str[action_type]; 33 } 34 35 static int 36 mlx5dr_debug_dump_matcher_template_definer(FILE *f, 37 struct mlx5dr_match_template *mt) 38 { 39 struct mlx5dr_definer *definer = mt->definer; 40 int i, ret; 41 42 ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,", 43 MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_DEFINER, 44 (uint64_t)(uintptr_t)definer, 45 (uint64_t)(uintptr_t)mt, 46 definer->obj->id, 47 definer->type); 48 if (ret < 0) { 49 rte_errno = EINVAL; 50 return rte_errno; 51 } 52 53 for (i = 0; i < DW_SELECTORS; i++) { 54 ret = fprintf(f, "0x%x%s", definer->dw_selector[i], 55 (i == DW_SELECTORS - 1) ? "," : "-"); 56 if (ret < 0) { 57 rte_errno = EINVAL; 58 return rte_errno; 59 } 60 } 61 62 for (i = 0; i < BYTE_SELECTORS; i++) { 63 ret = fprintf(f, "0x%x%s", definer->byte_selector[i], 64 (i == BYTE_SELECTORS - 1) ? "," : "-"); 65 if (ret < 0) { 66 rte_errno = EINVAL; 67 return rte_errno; 68 } 69 } 70 71 for (i = 0; i < MLX5DR_JUMBO_TAG_SZ; i++) { 72 ret = fprintf(f, "%02x", definer->mask.jumbo[i]); 73 if (ret < 0) { 74 rte_errno = EINVAL; 75 return rte_errno; 76 } 77 } 78 79 ret = fprintf(f, "\n"); 80 if (ret < 0) { 81 rte_errno = EINVAL; 82 return rte_errno; 83 } 84 85 return 0; 86 } 87 88 static int 89 mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher) 90 { 91 bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL; 92 int i, ret; 93 94 for (i = 0; i < matcher->num_of_mt; i++) { 95 struct mlx5dr_match_template *mt = matcher->mt[i]; 96 97 ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d\n", 98 MLX5DR_DEBUG_RES_TYPE_MATCHER_MATCH_TEMPLATE, 99 (uint64_t)(uintptr_t)mt, 100 (uint64_t)(uintptr_t)matcher, 101 is_root ? 0 : mt->fc_sz, 102 mt->flags); 103 if (ret < 0) { 104 rte_errno = EINVAL; 105 return rte_errno; 106 } 107 108 if (!is_root) { 109 ret = mlx5dr_debug_dump_matcher_template_definer(f, mt); 110 if (ret) 111 return ret; 112 } 113 } 114 115 return 0; 116 } 117 118 static int 119 mlx5dr_debug_dump_matcher_action_template(FILE *f, struct mlx5dr_matcher *matcher) 120 { 121 bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL; 122 enum mlx5dr_action_type action_type; 123 int i, j, ret; 124 125 for (i = 0; i < matcher->num_of_at; i++) { 126 struct mlx5dr_action_template *at = matcher->at[i]; 127 128 ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,%d", 129 MLX5DR_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE, 130 (uint64_t)(uintptr_t)at, 131 (uint64_t)(uintptr_t)matcher, 132 at->only_term ? 0 : 1, 133 is_root ? 0 : at->num_of_action_stes, 134 at->num_actions); 135 if (ret < 0) { 136 rte_errno = EINVAL; 137 return rte_errno; 138 } 139 140 for (j = 0; j < at->num_actions; j++) { 141 action_type = at->action_type_arr[j]; 142 ret = fprintf(f, ",%s", mlx5dr_debug_action_type_to_str(action_type)); 143 if (ret < 0) { 144 rte_errno = EINVAL; 145 return rte_errno; 146 } 147 } 148 149 fprintf(f, "\n"); 150 } 151 152 return 0; 153 } 154 155 static int 156 mlx5dr_debug_dump_matcher_attr(FILE *f, struct mlx5dr_matcher *matcher) 157 { 158 struct mlx5dr_matcher_attr *attr = &matcher->attr; 159 int ret; 160 161 ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d\n", 162 MLX5DR_DEBUG_RES_TYPE_MATCHER_ATTR, 163 (uint64_t)(uintptr_t)matcher, 164 attr->priority, 165 attr->mode, 166 attr->table.sz_row_log, 167 attr->table.sz_col_log, 168 attr->optimize_using_rule_idx, 169 attr->optimize_flow_src); 170 if (ret < 0) { 171 rte_errno = EINVAL; 172 return rte_errno; 173 } 174 175 return 0; 176 } 177 178 static int mlx5dr_debug_dump_matcher(FILE *f, struct mlx5dr_matcher *matcher) 179 { 180 bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL; 181 enum mlx5dr_table_type tbl_type = matcher->tbl->type; 182 struct mlx5dr_devx_obj *ste_0, *ste_1 = NULL; 183 struct mlx5dr_pool_chunk *ste; 184 struct mlx5dr_pool *ste_pool; 185 int ret; 186 187 ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,0x%" PRIx64, 188 MLX5DR_DEBUG_RES_TYPE_MATCHER, 189 (uint64_t)(uintptr_t)matcher, 190 (uint64_t)(uintptr_t)matcher->tbl, 191 matcher->num_of_mt, 192 is_root ? 0 : matcher->end_ft->id, 193 matcher->col_matcher ? (uint64_t)(uintptr_t)matcher->col_matcher : 0); 194 if (ret < 0) 195 goto out_err; 196 197 ste = &matcher->match_ste.ste; 198 ste_pool = matcher->match_ste.pool; 199 if (ste_pool) { 200 ste_0 = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste); 201 if (tbl_type == MLX5DR_TABLE_TYPE_FDB) 202 ste_1 = mlx5dr_pool_chunk_get_base_devx_obj_mirror(ste_pool, ste); 203 } else { 204 ste_0 = NULL; 205 ste_1 = NULL; 206 } 207 208 ret = fprintf(f, ",%d,%d,%d,%d", 209 matcher->match_ste.rtc_0 ? matcher->match_ste.rtc_0->id : 0, 210 ste_0 ? (int)ste_0->id : -1, 211 matcher->match_ste.rtc_1 ? matcher->match_ste.rtc_1->id : 0, 212 ste_1 ? (int)ste_1->id : -1); 213 if (ret < 0) 214 goto out_err; 215 216 ste = &matcher->action_ste.ste; 217 ste_pool = matcher->action_ste.pool; 218 if (ste_pool) { 219 ste_0 = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste); 220 if (tbl_type == MLX5DR_TABLE_TYPE_FDB) 221 ste_1 = mlx5dr_pool_chunk_get_base_devx_obj_mirror(ste_pool, ste); 222 } else { 223 ste_0 = NULL; 224 ste_1 = NULL; 225 } 226 227 ret = fprintf(f, ",%d,%d,%d,%d\n", 228 matcher->action_ste.rtc_0 ? matcher->action_ste.rtc_0->id : 0, 229 ste_0 ? (int)ste_0->id : -1, 230 matcher->action_ste.rtc_1 ? matcher->action_ste.rtc_1->id : 0, 231 ste_1 ? (int)ste_1->id : -1); 232 if (ret < 0) 233 goto out_err; 234 235 ret = mlx5dr_debug_dump_matcher_attr(f, matcher); 236 if (ret) 237 return ret; 238 239 ret = mlx5dr_debug_dump_matcher_match_template(f, matcher); 240 if (ret) 241 return ret; 242 243 ret = mlx5dr_debug_dump_matcher_action_template(f, matcher); 244 if (ret) 245 return ret; 246 247 return 0; 248 249 out_err: 250 rte_errno = EINVAL; 251 return rte_errno; 252 } 253 254 static int mlx5dr_debug_dump_table(FILE *f, struct mlx5dr_table *tbl) 255 { 256 bool is_root = tbl->level == MLX5DR_ROOT_LEVEL; 257 struct mlx5dr_matcher *matcher; 258 int ret; 259 260 ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,%d,%d\n", 261 MLX5DR_DEBUG_RES_TYPE_TABLE, 262 (uint64_t)(uintptr_t)tbl, 263 (uint64_t)(uintptr_t)tbl->ctx, 264 is_root ? 0 : tbl->ft->id, 265 tbl->type, 266 is_root ? 0 : tbl->fw_ft_type, 267 tbl->level); 268 if (ret < 0) { 269 rte_errno = EINVAL; 270 return rte_errno; 271 } 272 273 LIST_FOREACH(matcher, &tbl->head, next) { 274 ret = mlx5dr_debug_dump_matcher(f, matcher); 275 if (ret) 276 return ret; 277 } 278 279 return 0; 280 } 281 282 static int 283 mlx5dr_debug_dump_context_send_engine(FILE *f, struct mlx5dr_context *ctx) 284 { 285 struct mlx5dr_send_engine *send_queue; 286 int ret, i, j; 287 288 for (i = 0; i < (int)ctx->queues; i++) { 289 send_queue = &ctx->send_queue[i]; 290 ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d,%d\n", 291 MLX5DR_DEBUG_RES_TYPE_CONTEXT_SEND_ENGINE, 292 (uint64_t)(uintptr_t)ctx, 293 i, 294 send_queue->used_entries, 295 send_queue->th_entries, 296 send_queue->rings, 297 send_queue->num_entries, 298 send_queue->err, 299 send_queue->completed.ci, 300 send_queue->completed.pi, 301 send_queue->completed.mask); 302 if (ret < 0) { 303 rte_errno = EINVAL; 304 return rte_errno; 305 } 306 307 for (j = 0; j < MLX5DR_NUM_SEND_RINGS; j++) { 308 struct mlx5dr_send_ring *send_ring = &send_queue->send_ring[j]; 309 struct mlx5dr_send_ring_cq *cq = &send_ring->send_cq; 310 struct mlx5dr_send_ring_sq *sq = &send_ring->send_sq; 311 312 ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", 313 MLX5DR_DEBUG_RES_TYPE_CONTEXT_SEND_RING, 314 (uint64_t)(uintptr_t)ctx, 315 j, 316 i, 317 cq->cqn, 318 cq->cons_index, 319 cq->ncqe_mask, 320 cq->buf_sz, 321 cq->ncqe, 322 cq->cqe_log_sz, 323 cq->poll_wqe, 324 cq->cqe_sz, 325 sq->sqn, 326 sq->obj->id, 327 sq->cur_post, 328 sq->buf_mask); 329 if (ret < 0) { 330 rte_errno = EINVAL; 331 return rte_errno; 332 } 333 } 334 } 335 336 return 0; 337 } 338 339 static int mlx5dr_debug_dump_context_caps(FILE *f, struct mlx5dr_context *ctx) 340 { 341 struct mlx5dr_cmd_query_caps *caps = ctx->caps; 342 int ret; 343 344 ret = fprintf(f, "%d,0x%" PRIx64 ",%s,%d,%d,%d,%d,", 345 MLX5DR_DEBUG_RES_TYPE_CONTEXT_CAPS, 346 (uint64_t)(uintptr_t)ctx, 347 caps->fw_ver, 348 caps->wqe_based_update, 349 caps->ste_format, 350 caps->ste_alloc_log_max, 351 caps->log_header_modify_argument_max_alloc); 352 if (ret < 0) { 353 rte_errno = EINVAL; 354 return rte_errno; 355 } 356 357 ret = fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", 358 caps->flex_protocols, 359 caps->rtc_reparse_mode, 360 caps->rtc_index_mode, 361 caps->ste_alloc_log_gran, 362 caps->stc_alloc_log_max, 363 caps->stc_alloc_log_gran, 364 caps->rtc_log_depth_max, 365 caps->format_select_gtpu_dw_0, 366 caps->format_select_gtpu_dw_1, 367 caps->format_select_gtpu_dw_2, 368 caps->format_select_gtpu_ext_dw_0, 369 caps->nic_ft.max_level, 370 caps->nic_ft.reparse, 371 caps->fdb_ft.max_level, 372 caps->fdb_ft.reparse, 373 caps->log_header_modify_argument_granularity); 374 if (ret < 0) { 375 rte_errno = EINVAL; 376 return rte_errno; 377 } 378 379 return 0; 380 } 381 382 static int mlx5dr_debug_dump_context_attr(FILE *f, struct mlx5dr_context *ctx) 383 { 384 int ret; 385 386 ret = fprintf(f, "%u,0x%" PRIx64 ",%d,%zu,%d\n", 387 MLX5DR_DEBUG_RES_TYPE_CONTEXT_ATTR, 388 (uint64_t)(uintptr_t)ctx, 389 ctx->pd_num, 390 ctx->queues, 391 ctx->send_queue->num_entries); 392 if (ret < 0) { 393 rte_errno = EINVAL; 394 return rte_errno; 395 } 396 397 return 0; 398 } 399 400 static int mlx5dr_debug_dump_context_info(FILE *f, struct mlx5dr_context *ctx) 401 { 402 int ret; 403 404 ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%s,%s\n", 405 MLX5DR_DEBUG_RES_TYPE_CONTEXT, 406 (uint64_t)(uintptr_t)ctx, 407 ctx->flags & MLX5DR_CONTEXT_FLAG_HWS_SUPPORT, 408 mlx5_glue->get_device_name(ctx->ibv_ctx->device), 409 DEBUG_VERSION); 410 if (ret < 0) { 411 rte_errno = EINVAL; 412 return rte_errno; 413 } 414 415 ret = mlx5dr_debug_dump_context_attr(f, ctx); 416 if (ret) 417 return ret; 418 419 ret = mlx5dr_debug_dump_context_caps(f, ctx); 420 if (ret) 421 return ret; 422 423 return 0; 424 } 425 426 static int mlx5dr_debug_dump_context(FILE *f, struct mlx5dr_context *ctx) 427 { 428 struct mlx5dr_table *tbl; 429 int ret; 430 431 ret = mlx5dr_debug_dump_context_info(f, ctx); 432 if (ret) 433 return ret; 434 435 ret = mlx5dr_debug_dump_context_send_engine(f, ctx); 436 if (ret) 437 return ret; 438 439 LIST_FOREACH(tbl, &ctx->head, next) { 440 ret = mlx5dr_debug_dump_table(f, tbl); 441 if (ret) 442 return ret; 443 } 444 445 return 0; 446 } 447 448 int mlx5dr_debug_dump(struct mlx5dr_context *ctx, FILE *f) 449 { 450 int ret; 451 452 if (!f || !ctx) { 453 rte_errno = EINVAL; 454 return -rte_errno; 455 } 456 457 pthread_spin_lock(&ctx->ctrl_lock); 458 ret = mlx5dr_debug_dump_context(f, ctx); 459 pthread_spin_unlock(&ctx->ctrl_lock); 460 461 return -ret; 462 } 463