FILE
debug.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/debug.c
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2/* Copyright (c) 2024 NVIDIA Corporation & Affiliates */ 3 4#include <linux/debugfs.h> 5#include <linux/kernel.h> 6#include <linux/seq_file.h> 7#include <linux/version.h> 8#include "internal.h" 9 10static int 11hws_debug_dump_matcher_template_definer(struct seq_file *f, 12 void *parent_obj, 13 struct mlx5hws_definer *definer, 14 enum mlx5hws_debug_res_type type) 15{ 16 int i; 17 18 if (!definer) 19 return 0; 20 21 seq_printf(f, "%d,0x%llx,0x%llx,%d,%d,", 22 type, 23 HWS_PTR_TO_ID(definer), 24 HWS_PTR_TO_ID(parent_obj), 25 definer->obj_id, 26 definer->type); 27 28 for (i = 0; i < DW_SELECTORS; i++) 29 seq_printf(f, "0x%x%s", definer->dw_selector[i], 30 (i == DW_SELECTORS - 1) ? "," : "-"); 31 32 for (i = 0; i < BYTE_SELECTORS; i++) 33 seq_printf(f, "0x%x%s", definer->byte_selector[i], 34 (i == BYTE_SELECTORS - 1) ? "," : "-"); 35 36 for (i = 0; i < MLX5HWS_JUMBO_TAG_SZ; i++) 37 seq_printf(f, "%02x", definer->mask.jumbo[i]); 38 39 seq_puts(f, "\n"); 40 41 return 0; 42} 43 44static int 45hws_debug_dump_matcher_match_template(struct seq_file *f, struct mlx5hws_matcher *matcher) 46{ 47 enum mlx5hws_debug_res_type type; 48 int i, ret; 49 50 for (i = 0; i < matcher->num_of_mt; i++) { 51 struct mlx5hws_match_template *mt = &matcher->mt[i]; 52 53 seq_printf(f, "%d,0x%llx,0x%llx,%d,%d,%d\n", 54 MLX5HWS_DEBUG_RES_TYPE_MATCHER_MATCH_TEMPLATE, 55 HWS_PTR_TO_ID(mt), 56 HWS_PTR_TO_ID(matcher), 57 mt->fc_sz, 58 0, 0); 59 60 type = MLX5HWS_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; 61 ret = hws_debug_dump_matcher_template_definer(f, mt, mt->definer, type); 62 if (ret) 63 return ret; 64 } 65 66 return 0; 67} 68 69static int 70hws_debug_dump_matcher_action_template(struct seq_file *f, struct mlx5hws_matcher *matcher) 71{ 72 enum mlx5hws_action_type action_type; 73 int i, j; 74 75 for (i = 0; i < matcher->num_of_at; i++) { 76 struct mlx5hws_action_template *at = &matcher->at[i]; 77 78 seq_printf(f, "%d,0x%llx,0x%llx,%d,%d,%d", 79 MLX5HWS_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE, 80 HWS_PTR_TO_ID(at), 81 HWS_PTR_TO_ID(matcher), 82 at->only_term, 83 at->num_of_action_stes, 84 at->num_actions); 85 86 for (j = 0; j < at->num_actions; j++) { 87 action_type = at->action_type_arr[j]; 88 seq_printf(f, ",%s", mlx5hws_action_type_to_str(action_type)); 89 } 90 91 seq_puts(f, "\n"); 92 } 93 94 return 0; 95} 96 97static int 98hws_debug_dump_matcher_attr(struct seq_file *f, struct mlx5hws_matcher *matcher) 99{ 100 struct mlx5hws_matcher_attr *attr = &matcher->attr; 101 102 seq_printf(f, "%d,0x%llx,%d,%d,%d,%d,%d,%d,%d,%d,-1,-1,%d,%d\n", 103 MLX5HWS_DEBUG_RES_TYPE_MATCHER_ATTR, 104 HWS_PTR_TO_ID(matcher), 105 attr->priority, 106 attr->mode, 107 attr->size[MLX5HWS_MATCHER_SIZE_TYPE_RX].table.sz_row_log, 108 attr->size[MLX5HWS_MATCHER_SIZE_TYPE_RX].table.sz_col_log, 109 attr->optimize_using_rule_idx, 110 attr->optimize_flow_src, 111 attr->insert_mode, 112 attr->distribute_mode, 113 attr->size[MLX5HWS_MATCHER_SIZE_TYPE_TX].table.sz_row_log, 114 attr->size[MLX5HWS_MATCHER_SIZE_TYPE_TX].table.sz_col_log); 115 116 return 0; 117} 118 119static int hws_debug_dump_matcher(struct seq_file *f, struct mlx5hws_matcher *matcher) 120{ 121 enum mlx5hws_table_type tbl_type = matcher->tbl->type; 122 struct mlx5hws_cmd_ft_query_attr ft_attr = {0}; 123 u64 icm_addr_0 = 0; 124 u64 icm_addr_1 = 0; 125 u32 ste_0_id = -1; 126 u32 ste_1_id = -1; 127 int ret; 128 129 seq_printf(f, "%d,0x%llx,0x%llx,%d,%d,0x%llx", 130 MLX5HWS_DEBUG_RES_TYPE_MATCHER, 131 HWS_PTR_TO_ID(matcher), 132 HWS_PTR_TO_ID(matcher->tbl), 133 matcher->num_of_mt, 134 matcher->end_ft_id, 135 matcher->col_matcher ? HWS_PTR_TO_ID(matcher->col_matcher) : 0); 136 137 ste_0_id = matcher->match_ste.ste_0_base; 138 if (tbl_type == MLX5HWS_TABLE_TYPE_FDB) 139 ste_1_id = matcher->match_ste.ste_1_base; 140 141 seq_printf(f, ",%d,%d,%d,%d", 142 matcher->match_ste.rtc_0_id, 143 (int)ste_0_id, 144 matcher->match_ste.rtc_1_id, 145 (int)ste_1_id); 146 147 ft_attr.type = matcher->tbl->fw_ft_type; 148 ret = mlx5hws_cmd_flow_table_query(matcher->tbl->ctx->mdev, 149 matcher->end_ft_id, 150 &ft_attr, 151 &icm_addr_0, 152 &icm_addr_1); 153 if (ret) 154 return ret; 155 156 seq_printf(f, ",-1,-1,-1,-1,0,0x%llx,0x%llx\n", 157 mlx5hws_debug_icm_to_idx(icm_addr_0), 158 mlx5hws_debug_icm_to_idx(icm_addr_1)); 159 160 ret = hws_debug_dump_matcher_attr(f, matcher); 161 if (ret) 162 return ret; 163 164 ret = hws_debug_dump_matcher_match_template(f, matcher); 165 if (ret) 166 return ret; 167 168 ret = hws_debug_dump_matcher_action_template(f, matcher); 169 if (ret) 170 return ret; 171 172 return 0; 173} 174 175static int hws_debug_dump_table(struct seq_file *f, struct mlx5hws_table *tbl) 176{ 177 struct mlx5hws_cmd_ft_query_attr ft_attr = {0}; 178 struct mlx5hws_matcher *matcher; 179 u64 local_icm_addr_0 = 0; 180 u64 local_icm_addr_1 = 0; 181 u64 icm_addr_0 = 0; 182 u64 icm_addr_1 = 0; 183 int ret; 184 185 seq_printf(f, "%d,0x%llx,0x%llx,%d,%d,%d,%d,%d", 186 MLX5HWS_DEBUG_RES_TYPE_TABLE, 187 HWS_PTR_TO_ID(tbl), 188 HWS_PTR_TO_ID(tbl->ctx), 189 tbl->ft_id, 190 MLX5HWS_TABLE_TYPE_BASE + tbl->type, 191 tbl->fw_ft_type, 192 tbl->level, 193 0); 194 195 ft_attr.type = tbl->fw_ft_type; 196 ret = mlx5hws_cmd_flow_table_query(tbl->ctx->mdev, 197 tbl->ft_id, 198 &ft_attr, 199 &icm_addr_0, 200 &icm_addr_1); 201 if (ret) 202 return ret; 203 204 seq_printf(f, ",0x%llx,0x%llx,0x%llx,0x%llx,0x%llx\n", 205 mlx5hws_debug_icm_to_idx(icm_addr_0), 206 mlx5hws_debug_icm_to_idx(icm_addr_1), 207 mlx5hws_debug_icm_to_idx(local_icm_addr_0), 208 mlx5hws_debug_icm_to_idx(local_icm_addr_1), 209 HWS_PTR_TO_ID(tbl->default_miss.miss_tbl)); 210 211 list_for_each_entry(matcher, &tbl->matchers_list, list_node) { 212 ret = hws_debug_dump_matcher(f, matcher); 213 if (ret) 214 return ret; 215 } 216 217 return 0; 218} 219 220static int 221hws_debug_dump_context_send_engine(struct seq_file *f, struct mlx5hws_context *ctx) 222{ 223 struct mlx5hws_send_engine *send_queue; 224 struct mlx5hws_send_ring *send_ring; 225 struct mlx5hws_send_ring_cq *cq; 226 struct mlx5hws_send_ring_sq *sq; 227 int i; 228 229 for (i = 0; i < (int)ctx->queues; i++) { 230 send_queue = &ctx->send_queue[i]; 231 seq_printf(f, "%d,0x%llx,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", 232 MLX5HWS_DEBUG_RES_TYPE_CONTEXT_SEND_ENGINE, 233 HWS_PTR_TO_ID(ctx), 234 i, 235 send_queue->used_entries, 236 send_queue->num_entries, 237 1, /* one send ring per queue */ 238 send_queue->num_entries, 239 send_queue->err, 240 send_queue->completed.ci, 241 send_queue->completed.pi, 242 send_queue->completed.mask); 243 244 send_ring = &send_queue->send_ring; 245 cq = &send_ring->send_cq; 246 sq = &send_ring->send_sq; 247 248 seq_printf(f, "%d,0x%llx,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", 249 MLX5HWS_DEBUG_RES_TYPE_CONTEXT_SEND_RING, 250 HWS_PTR_TO_ID(ctx), 251 0, /* one send ring per send queue */ 252 i, 253 cq->mcq.cqn, 254 0, 255 0, 256 0, 257 0, 258 0, 259 0, 260 cq->mcq.cqe_sz, 261 sq->sqn, 262 0, 263 0, 264 0); 265 } 266 267 return 0; 268} 269 270static int hws_debug_dump_context_caps(struct seq_file *f, struct mlx5hws_context *ctx) 271{ 272 struct mlx5hws_cmd_query_caps *caps = ctx->caps; 273 274 seq_printf(f, "%d,0x%llx,%s,%d,%d,%d,%d,", 275 MLX5HWS_DEBUG_RES_TYPE_CONTEXT_CAPS, 276 HWS_PTR_TO_ID(ctx), 277 caps->fw_ver, 278 caps->wqe_based_update, 279 caps->ste_format, 280 caps->ste_alloc_log_max, 281 caps->log_header_modify_argument_max_alloc); 282 283 seq_printf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%s\n", 284 caps->flex_protocols, 285 caps->rtc_reparse_mode, 286 caps->rtc_index_mode, 287 caps->ste_alloc_log_gran, 288 caps->stc_alloc_log_max, 289 caps->stc_alloc_log_gran, 290 caps->rtc_log_depth_max, 291 caps->format_select_gtpu_dw_0, 292 caps->format_select_gtpu_dw_1, 293 caps->format_select_gtpu_dw_2, 294 caps->format_select_gtpu_ext_dw_0, 295 caps->nic_ft.max_level, 296 caps->nic_ft.reparse, 297 caps->fdb_ft.max_level, 298 caps->fdb_ft.reparse, 299 caps->log_header_modify_argument_granularity, 300 caps->linear_match_definer, 301 "regc_3"); 302 303 return 0; 304} 305 306static int hws_debug_dump_context_attr(struct seq_file *f, struct mlx5hws_context *ctx) 307{ 308 seq_printf(f, "%u,0x%llx,%d,%zu,%d,%s,%d,%d\n", 309 MLX5HWS_DEBUG_RES_TYPE_CONTEXT_ATTR, 310 HWS_PTR_TO_ID(ctx), 311 ctx->pd_num, 312 ctx->queues, 313 ctx->send_queue->num_entries, 314 "None", /* no shared gvmi */ 315 ctx->caps->vhca_id, 316 0xffff); /* no shared gvmi */ 317 318 return 0; 319} 320 321static int hws_debug_dump_context_info(struct seq_file *f, struct mlx5hws_context *ctx) 322{ 323 struct mlx5_core_dev *dev = ctx->mdev; 324 int ret; 325 326 seq_printf(f, "%d,0x%llx,%d,%s,%s.KERNEL_%u_%u_%u\n", 327 MLX5HWS_DEBUG_RES_TYPE_CONTEXT, 328 HWS_PTR_TO_ID(ctx), 329 ctx->flags & MLX5HWS_CONTEXT_FLAG_HWS_SUPPORT, 330 pci_name(dev->pdev), 331 HWS_DEBUG_FORMAT_VERSION, 332 LINUX_VERSION_MAJOR, 333 LINUX_VERSION_PATCHLEVEL, 334 LINUX_VERSION_SUBLEVEL); 335 336 ret = hws_debug_dump_context_attr(f, ctx); 337 if (ret) 338 return ret; 339 340 ret = hws_debug_dump_context_caps(f, ctx); 341 if (ret) 342 return ret; 343 344 return 0; 345} 346 347static int hws_debug_dump_context_stc_resource(struct seq_file *f, 348 struct mlx5hws_context *ctx, 349 struct mlx5hws_pool_resource *resource) 350{ 351 u32 tbl_type = MLX5HWS_TABLE_TYPE_BASE + MLX5HWS_TABLE_TYPE_FDB; 352 353 seq_printf(f, "%d,0x%llx,%u,%u\n", 354 MLX5HWS_DEBUG_RES_TYPE_CONTEXT_STC, 355 HWS_PTR_TO_ID(ctx), 356 tbl_type, 357 resource->base_id); 358 359 return 0; 360} 361 362static int hws_debug_dump_context_stc(struct seq_file *f, struct mlx5hws_context *ctx) 363{ 364 struct mlx5hws_pool *stc_pool = ctx->stc_pool; 365 int ret; 366 367 if (!stc_pool) 368 return 0; 369 370 if (stc_pool->resource) { 371 ret = hws_debug_dump_context_stc_resource(f, ctx, 372 stc_pool->resource); 373 if (ret) 374 return ret; 375 } 376 377 if (stc_pool->mirror_resource) { 378 struct mlx5hws_pool_resource *res = stc_pool->mirror_resource; 379 380 ret = hws_debug_dump_context_stc_resource(f, ctx, res); 381 if (ret) 382 return ret; 383 } 384 385 return 0; 386} 387 388static void 389hws_debug_dump_action_ste_table(struct seq_file *f, 390 struct mlx5hws_action_ste_table *action_tbl) 391{ 392 int ste_0_id = mlx5hws_pool_get_base_id(action_tbl->pool); 393 int ste_1_id = mlx5hws_pool_get_base_mirror_id(action_tbl->pool); 394 395 seq_printf(f, "%d,0x%llx,%d,%d,%d,%d\n", 396 MLX5HWS_DEBUG_RES_TYPE_ACTION_STE_TABLE, 397 HWS_PTR_TO_ID(action_tbl), 398 action_tbl->rtc_0_id, ste_0_id, 399 action_tbl->rtc_1_id, ste_1_id); 400} 401 402static void hws_debug_dump_action_ste_pool(struct seq_file *f, 403 struct mlx5hws_action_ste_pool *pool) 404{ 405 struct mlx5hws_action_ste_table *action_tbl; 406 enum mlx5hws_pool_optimize opt; 407 408 mutex_lock(&pool->lock); 409 for (opt = MLX5HWS_POOL_OPTIMIZE_NONE; opt < MLX5HWS_POOL_OPTIMIZE_MAX; 410 opt++) { 411 list_for_each_entry(action_tbl, &pool->elems[opt].available, 412 list_node) { 413 hws_debug_dump_action_ste_table(f, action_tbl); 414 } 415 } 416 mutex_unlock(&pool->lock); 417} 418 419static int hws_debug_dump_context(struct seq_file *f, struct mlx5hws_context *ctx) 420{ 421 struct mlx5hws_table *tbl; 422 int ret, i; 423 424 ret = hws_debug_dump_context_info(f, ctx); 425 if (ret) 426 return ret; 427 428 ret = hws_debug_dump_context_send_engine(f, ctx); 429 if (ret) 430 return ret; 431 432 ret = hws_debug_dump_context_stc(f, ctx); 433 if (ret) 434 return ret; 435 436 list_for_each_entry(tbl, &ctx->tbl_list, tbl_list_node) { 437 ret = hws_debug_dump_table(f, tbl); 438 if (ret) 439 return ret; 440 } 441 442 for (i = 0; i < ctx->queues; i++) 443 hws_debug_dump_action_ste_pool(f, &ctx->action_ste_pool[i]); 444 445 return 0; 446} 447 448static int 449hws_debug_dump(struct seq_file *f, struct mlx5hws_context *ctx) 450{ 451 int ret; 452 453 if (!f || !ctx) 454 return -EINVAL; 455 456 mutex_lock(&ctx->ctrl_lock); 457 ret = hws_debug_dump_context(f, ctx); 458 mutex_unlock(&ctx->ctrl_lock); 459 460 return ret; 461} 462 463static int hws_dump_show(struct seq_file *file, void *priv) 464{ 465 return hws_debug_dump(file, file->private); 466} 467DEFINE_SHOW_ATTRIBUTE(hws_dump); 468 469void mlx5hws_debug_init_dump(struct mlx5hws_context *ctx) 470{ 471 struct mlx5_core_dev *dev = ctx->mdev; 472 char file_name[128]; 473 474 ctx->debug_info.steering_debugfs = 475 debugfs_create_dir("steering", mlx5_debugfs_get_dev_root(dev)); 476 ctx->debug_info.fdb_debugfs = 477 debugfs_create_dir("fdb", ctx->debug_info.steering_debugfs); 478 479 sprintf(file_name, "ctx_%p", ctx); 480 debugfs_create_file(file_name, 0444, ctx->debug_info.fdb_debugfs, 481 ctx, &hws_dump_fops); 482} 483 484void mlx5hws_debug_uninit_dump(struct mlx5hws_context *ctx) 485{ 486 debugfs_remove_recursive(ctx->debug_info.steering_debugfs); 487}
~/
Read-only file preview.