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