xref: /dpdk/drivers/net/mlx5/hws/mlx5dr_debug.c (revision af0785a2447b307965377b62f46a5f39457a85a3)
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