xref: /dpdk/drivers/net/mlx5/hws/mlx5dr_debug.c (revision 665b49c51639a10c553433bc2bcd85c7331c631e)
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 					   void *parent_obj,
38 					   struct mlx5dr_definer *definer,
39 					   enum mlx5dr_debug_res_type type)
40 {
41 	int i, ret;
42 
43 	if (!definer)
44 		return 0;
45 
46 	ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,",
47 		      type,
48 		      (uint64_t)(uintptr_t)definer,
49 		      (uint64_t)(uintptr_t)parent_obj,
50 		      definer->obj->id,
51 		      definer->type);
52 	if (ret < 0) {
53 		rte_errno = EINVAL;
54 		return rte_errno;
55 	}
56 
57 	for (i = 0; i < DW_SELECTORS; i++) {
58 		ret = fprintf(f, "0x%x%s", definer->dw_selector[i],
59 			      (i == DW_SELECTORS - 1) ? "," : "-");
60 		if (ret < 0) {
61 			rte_errno = EINVAL;
62 			return rte_errno;
63 		}
64 	}
65 
66 	for (i = 0; i < BYTE_SELECTORS; i++) {
67 		ret = fprintf(f, "0x%x%s", definer->byte_selector[i],
68 			      (i == BYTE_SELECTORS - 1) ? "," : "-");
69 		if (ret < 0) {
70 			rte_errno = EINVAL;
71 			return rte_errno;
72 		}
73 	}
74 
75 	for (i = 0; i < MLX5DR_JUMBO_TAG_SZ; i++) {
76 		ret = fprintf(f, "%02x", definer->mask.jumbo[i]);
77 		if (ret < 0) {
78 			rte_errno = EINVAL;
79 			return rte_errno;
80 		}
81 	}
82 
83 	ret = fprintf(f, "\n");
84 	if (ret < 0) {
85 		rte_errno = EINVAL;
86 		return rte_errno;
87 	}
88 
89 	return 0;
90 }
91 
92 static int
93 mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher)
94 {
95 	bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL;
96 	enum mlx5dr_debug_res_type type;
97 	int i, ret;
98 
99 	for (i = 0; i < matcher->num_of_mt; i++) {
100 		struct mlx5dr_match_template *mt = &matcher->mt[i];
101 
102 		ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,%d\n",
103 			      MLX5DR_DEBUG_RES_TYPE_MATCHER_MATCH_TEMPLATE,
104 			      (uint64_t)(uintptr_t)mt,
105 			      (uint64_t)(uintptr_t)matcher,
106 			      is_root ? 0 : mt->fc_sz,
107 			      mt->flags,
108 			      is_root ? 0 : mt->fcr_sz);
109 		if (ret < 0) {
110 			rte_errno = EINVAL;
111 			return rte_errno;
112 		}
113 
114 		type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER;
115 		ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt->definer, type);
116 		if (ret)
117 			return ret;
118 
119 		type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_RANGE_DEFINER;
120 		ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt->range_definer, type);
121 		if (ret)
122 			return ret;
123 	}
124 
125 	type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_HASH_DEFINER;
126 	ret = mlx5dr_debug_dump_matcher_template_definer(f, matcher, matcher->hash_definer, type);
127 	if (ret)
128 		return ret;
129 
130 	return 0;
131 }
132 
133 static int
134 mlx5dr_debug_dump_matcher_action_template(FILE *f, struct mlx5dr_matcher *matcher)
135 {
136 	bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL;
137 	enum mlx5dr_action_type action_type;
138 	int i, j, ret;
139 
140 	for (i = 0; i < matcher->num_of_at; i++) {
141 		struct mlx5dr_action_template *at = &matcher->at[i];
142 
143 		ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,%d",
144 			      MLX5DR_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE,
145 			      (uint64_t)(uintptr_t)at,
146 			      (uint64_t)(uintptr_t)matcher,
147 			      at->only_term ? 0 : 1,
148 			      is_root ? 0 : at->num_of_action_stes,
149 			      at->num_actions);
150 		if (ret < 0) {
151 			rte_errno = EINVAL;
152 			return rte_errno;
153 		}
154 
155 		for (j = 0; j < at->num_actions; j++) {
156 			action_type = at->action_type_arr[j];
157 			ret = fprintf(f, ",%s", mlx5dr_debug_action_type_to_str(action_type));
158 			if (ret < 0) {
159 				rte_errno = EINVAL;
160 				return rte_errno;
161 			}
162 		}
163 
164 		fprintf(f, "\n");
165 	}
166 
167 	return 0;
168 }
169 
170 static int
171 mlx5dr_debug_dump_matcher_attr(FILE *f, struct mlx5dr_matcher *matcher)
172 {
173 	struct mlx5dr_matcher_attr *attr = &matcher->attr;
174 	int ret;
175 
176 	ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d\n",
177 		      MLX5DR_DEBUG_RES_TYPE_MATCHER_ATTR,
178 		      (uint64_t)(uintptr_t)matcher,
179 		      attr->priority,
180 		      attr->mode,
181 		      attr->table.sz_row_log,
182 		      attr->table.sz_col_log,
183 		      attr->optimize_using_rule_idx,
184 		      attr->optimize_flow_src,
185 		      attr->insert_mode,
186 		      attr->distribute_mode);
187 	if (ret < 0) {
188 		rte_errno = EINVAL;
189 		return rte_errno;
190 	}
191 
192 	return 0;
193 }
194 
195 static int mlx5dr_debug_dump_matcher(FILE *f, struct mlx5dr_matcher *matcher)
196 {
197 	bool is_shared = mlx5dr_context_shared_gvmi_used(matcher->tbl->ctx);
198 	bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL;
199 	enum mlx5dr_table_type tbl_type = matcher->tbl->type;
200 	struct mlx5dr_devx_obj *ste_0, *ste_1 = NULL;
201 	struct mlx5dr_pool_chunk *ste;
202 	struct mlx5dr_pool *ste_pool;
203 	int ret;
204 
205 	ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,0x%" PRIx64,
206 		      MLX5DR_DEBUG_RES_TYPE_MATCHER,
207 		      (uint64_t)(uintptr_t)matcher,
208 		      (uint64_t)(uintptr_t)matcher->tbl,
209 		      matcher->num_of_mt,
210 		      is_root ? 0 : matcher->end_ft->id,
211 		      matcher->col_matcher ? (uint64_t)(uintptr_t)matcher->col_matcher : 0);
212 	if (ret < 0)
213 		goto out_err;
214 
215 	ste = &matcher->match_ste.ste;
216 	ste_pool = matcher->match_ste.pool;
217 	if (ste_pool) {
218 		ste_0 = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste);
219 		if (tbl_type == MLX5DR_TABLE_TYPE_FDB)
220 			ste_1 = mlx5dr_pool_chunk_get_base_devx_obj_mirror(ste_pool, ste);
221 	} else {
222 		ste_0 = NULL;
223 		ste_1 = NULL;
224 	}
225 
226 	ret = fprintf(f, ",%d,%d,%d,%d",
227 		      matcher->match_ste.rtc_0 ? matcher->match_ste.rtc_0->id : 0,
228 		      ste_0 ? (int)ste_0->id : -1,
229 		      matcher->match_ste.rtc_1 ? matcher->match_ste.rtc_1->id : 0,
230 		      ste_1 ? (int)ste_1->id : -1);
231 	if (ret < 0)
232 		goto out_err;
233 
234 	ste = &matcher->action_ste.ste;
235 	ste_pool = matcher->action_ste.pool;
236 	if (ste_pool) {
237 		ste_0 = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste);
238 		if (tbl_type == MLX5DR_TABLE_TYPE_FDB)
239 			ste_1 = mlx5dr_pool_chunk_get_base_devx_obj_mirror(ste_pool, ste);
240 	} else {
241 		ste_0 = NULL;
242 		ste_1 = NULL;
243 	}
244 
245 	ret = fprintf(f, ",%d,%d,%d,%d,%d\n",
246 		      matcher->action_ste.rtc_0 ? matcher->action_ste.rtc_0->id : 0,
247 		      ste_0 ? (int)ste_0->id : -1,
248 		      matcher->action_ste.rtc_1 ? matcher->action_ste.rtc_1->id : 0,
249 		      ste_1 ? (int)ste_1->id : -1,
250 		      is_shared && !is_root ?
251 		      matcher->match_ste.aliased_rtc_0->id : 0);
252 	if (ret < 0)
253 		goto out_err;
254 
255 	ret = mlx5dr_debug_dump_matcher_attr(f, matcher);
256 	if (ret)
257 		return ret;
258 
259 	ret = mlx5dr_debug_dump_matcher_match_template(f, matcher);
260 	if (ret)
261 		return ret;
262 
263 	ret = mlx5dr_debug_dump_matcher_action_template(f, matcher);
264 	if (ret)
265 		return ret;
266 
267 	return 0;
268 
269 out_err:
270 	rte_errno = EINVAL;
271 	return rte_errno;
272 }
273 
274 static int mlx5dr_debug_dump_table(FILE *f, struct mlx5dr_table *tbl)
275 {
276 	bool is_shared = mlx5dr_context_shared_gvmi_used(tbl->ctx);
277 	bool is_root = tbl->level == MLX5DR_ROOT_LEVEL;
278 	struct mlx5dr_matcher *matcher;
279 	int ret;
280 
281 	ret = fprintf(f, "%d,0x%" PRIx64 ",0x%" PRIx64 ",%d,%d,%d,%d,%d\n",
282 		      MLX5DR_DEBUG_RES_TYPE_TABLE,
283 		      (uint64_t)(uintptr_t)tbl,
284 		      (uint64_t)(uintptr_t)tbl->ctx,
285 		      is_root ? 0 : tbl->ft->id,
286 		      tbl->type,
287 		      is_root ? 0 : tbl->fw_ft_type,
288 		      tbl->level,
289 		      is_shared && !is_root ? tbl->local_ft->id : 0);
290 	if (ret < 0) {
291 		rte_errno = EINVAL;
292 		return rte_errno;
293 	}
294 
295 	LIST_FOREACH(matcher, &tbl->head, next) {
296 		ret = mlx5dr_debug_dump_matcher(f, matcher);
297 		if (ret)
298 			return ret;
299 	}
300 
301 	return 0;
302 }
303 
304 static int
305 mlx5dr_debug_dump_context_send_engine(FILE *f, struct mlx5dr_context *ctx)
306 {
307 	struct mlx5dr_send_engine *send_queue;
308 	int ret, i, j;
309 
310 	for (i = 0; i < (int)ctx->queues; i++) {
311 		send_queue = &ctx->send_queue[i];
312 		ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
313 			      MLX5DR_DEBUG_RES_TYPE_CONTEXT_SEND_ENGINE,
314 			      (uint64_t)(uintptr_t)ctx,
315 			      i,
316 			      send_queue->used_entries,
317 			      send_queue->th_entries,
318 			      send_queue->rings,
319 			      send_queue->num_entries,
320 			      send_queue->err,
321 			      send_queue->completed.ci,
322 			      send_queue->completed.pi,
323 			      send_queue->completed.mask);
324 		if (ret < 0) {
325 			rte_errno = EINVAL;
326 			return rte_errno;
327 		}
328 
329 		for (j = 0; j < MLX5DR_NUM_SEND_RINGS; j++) {
330 			struct mlx5dr_send_ring *send_ring = &send_queue->send_ring[j];
331 			struct mlx5dr_send_ring_cq *cq = &send_ring->send_cq;
332 			struct mlx5dr_send_ring_sq *sq = &send_ring->send_sq;
333 
334 			ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
335 				      MLX5DR_DEBUG_RES_TYPE_CONTEXT_SEND_RING,
336 				      (uint64_t)(uintptr_t)ctx,
337 				      j,
338 				      i,
339 				      cq->cqn,
340 				      cq->cons_index,
341 				      cq->ncqe_mask,
342 				      cq->buf_sz,
343 				      cq->ncqe,
344 				      cq->cqe_log_sz,
345 				      cq->poll_wqe,
346 				      cq->cqe_sz,
347 				      sq->sqn,
348 				      sq->obj->id,
349 				      sq->cur_post,
350 				      sq->buf_mask);
351 			if (ret < 0) {
352 				rte_errno = EINVAL;
353 				return rte_errno;
354 			}
355 		}
356 	}
357 
358 	return 0;
359 }
360 
361 static int mlx5dr_debug_dump_context_caps(FILE *f, struct mlx5dr_context *ctx)
362 {
363 	struct mlx5dr_cmd_query_caps *caps = ctx->caps;
364 	int ret;
365 
366 	ret = fprintf(f, "%d,0x%" PRIx64 ",%s,%d,%d,%d,%d,",
367 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT_CAPS,
368 		      (uint64_t)(uintptr_t)ctx,
369 		      caps->fw_ver,
370 		      caps->wqe_based_update,
371 		      caps->ste_format,
372 		      caps->ste_alloc_log_max,
373 		      caps->log_header_modify_argument_max_alloc);
374 	if (ret < 0) {
375 		rte_errno = EINVAL;
376 		return rte_errno;
377 	}
378 
379 	ret = fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
380 		      caps->flex_protocols,
381 		      caps->rtc_reparse_mode,
382 		      caps->rtc_index_mode,
383 		      caps->ste_alloc_log_gran,
384 		      caps->stc_alloc_log_max,
385 		      caps->stc_alloc_log_gran,
386 		      caps->rtc_log_depth_max,
387 		      caps->format_select_gtpu_dw_0,
388 		      caps->format_select_gtpu_dw_1,
389 		      caps->format_select_gtpu_dw_2,
390 		      caps->format_select_gtpu_ext_dw_0,
391 		      caps->nic_ft.max_level,
392 		      caps->nic_ft.reparse,
393 		      caps->fdb_ft.max_level,
394 		      caps->fdb_ft.reparse,
395 		      caps->log_header_modify_argument_granularity);
396 	if (ret < 0) {
397 		rte_errno = EINVAL;
398 		return rte_errno;
399 	}
400 
401 	return 0;
402 }
403 
404 static int mlx5dr_debug_dump_context_attr(FILE *f, struct mlx5dr_context *ctx)
405 {
406 	int ret;
407 
408 	ret = fprintf(f, "%u,0x%" PRIx64 ",%d,%zu,%d,%s,%d,%d\n",
409 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT_ATTR,
410 		      (uint64_t)(uintptr_t)ctx,
411 		      ctx->pd_num,
412 		      ctx->queues,
413 		      ctx->send_queue->num_entries,
414 		      mlx5dr_context_shared_gvmi_used(ctx) ?
415 		      mlx5_glue->get_device_name(ctx->ibv_ctx->device) : "None",
416 		      ctx->caps->vhca_id,
417 		      mlx5dr_context_shared_gvmi_used(ctx) ?
418 		      ctx->caps->shared_vhca_id : 0xffff);
419 	if (ret < 0) {
420 		rte_errno = EINVAL;
421 		return rte_errno;
422 	}
423 
424 	return 0;
425 }
426 
427 static int mlx5dr_debug_dump_context_info(FILE *f, struct mlx5dr_context *ctx)
428 {
429 	int ret;
430 
431 	ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%s,%s\n",
432 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT,
433 		      (uint64_t)(uintptr_t)ctx,
434 		      ctx->flags & MLX5DR_CONTEXT_FLAG_HWS_SUPPORT,
435 		      mlx5_glue->get_device_name(mlx5dr_context_get_local_ibv(ctx)->device),
436 		      DEBUG_VERSION);
437 	if (ret < 0) {
438 		rte_errno = EINVAL;
439 		return rte_errno;
440 	}
441 
442 	ret = mlx5dr_debug_dump_context_attr(f, ctx);
443 	if (ret)
444 		return ret;
445 
446 	ret = mlx5dr_debug_dump_context_caps(f, ctx);
447 	if (ret)
448 		return ret;
449 
450 	return 0;
451 }
452 
453 static int
454 mlx5dr_debug_dump_context_stc_resource(FILE *f,
455 				       struct mlx5dr_context *ctx,
456 				       uint32_t tbl_type,
457 				       struct mlx5dr_pool_resource *resource)
458 {
459 	int ret;
460 
461 	ret = fprintf(f, "%d,0x%" PRIx64 ",%u,%u\n",
462 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT_STC,
463 		      (uint64_t)(uintptr_t)ctx,
464 		      tbl_type,
465 		      resource->base_id);
466 	if (ret < 0) {
467 		rte_errno = EINVAL;
468 		return rte_errno;
469 	}
470 
471 	return 0;
472 }
473 
474 static int mlx5dr_debug_dump_context_stc(FILE *f, struct mlx5dr_context *ctx)
475 {
476 	struct mlx5dr_pool *stc_pool;
477 	int ret;
478 	int i;
479 
480 	for (i = 0; i < MLX5DR_TABLE_TYPE_MAX; i++) {
481 		stc_pool = ctx->stc_pool[i];
482 
483 		if (!stc_pool)
484 			continue;
485 
486 		if (stc_pool->resource[0] != NULL) {
487 			ret = mlx5dr_debug_dump_context_stc_resource(f, ctx, i,
488 								     stc_pool->resource[0]);
489 			if (ret)
490 				return ret;
491 		}
492 
493 		if (i == MLX5DR_TABLE_TYPE_FDB && stc_pool->mirror_resource[0] != NULL) {
494 			ret = mlx5dr_debug_dump_context_stc_resource(f, ctx, i,
495 								     stc_pool->mirror_resource[0]);
496 			if (ret)
497 				return ret;
498 		}
499 	}
500 
501 	return 0;
502 }
503 
504 static int mlx5dr_debug_dump_context(FILE *f, struct mlx5dr_context *ctx)
505 {
506 	struct mlx5dr_table *tbl;
507 	int ret;
508 
509 	ret = mlx5dr_debug_dump_context_info(f, ctx);
510 	if (ret)
511 		return ret;
512 
513 	ret = mlx5dr_debug_dump_context_send_engine(f, ctx);
514 	if (ret)
515 		return ret;
516 
517 	ret = mlx5dr_debug_dump_context_stc(f, ctx);
518 	if (ret)
519 		return ret;
520 
521 	LIST_FOREACH(tbl, &ctx->head, next) {
522 		ret = mlx5dr_debug_dump_table(f, tbl);
523 		if (ret)
524 			return ret;
525 	}
526 
527 	return 0;
528 }
529 
530 int mlx5dr_debug_dump(struct mlx5dr_context *ctx, FILE *f)
531 {
532 	int ret;
533 
534 	if (!f || !ctx) {
535 		rte_errno = EINVAL;
536 		return -rte_errno;
537 	}
538 
539 	pthread_spin_lock(&ctx->ctrl_lock);
540 	ret = mlx5dr_debug_dump_context(f, ctx);
541 	pthread_spin_unlock(&ctx->ctrl_lock);
542 
543 	return -ret;
544 }
545