diff options
Diffstat (limited to 'src/plugins/rdma/format.c')
-rw-r--r-- | src/plugins/rdma/format.c | 168 |
1 files changed, 167 insertions, 1 deletions
diff --git a/src/plugins/rdma/format.c b/src/plugins/rdma/format.c index c9553b21e41..89a2a7ca0a5 100644 --- a/src/plugins/rdma/format.c +++ b/src/plugins/rdma/format.c @@ -49,6 +49,30 @@ t = format (t, "%s%s", t ? " ":"", c); } u8 * +format_rdma_bit_flag (u8 * s, va_list * args) +{ + u64 flags = va_arg (*args, u64); + char **strs = va_arg (*args, char **); + u32 n_strs = va_arg (*args, u32); + int i = 0; + + while (flags) + { + if ((flags & (1 << i))) + { + if (i < n_strs && strs[i] != 0) + s = format (s, " %s", strs[i]); + else + s = format (s, " unknown(%u)", i); + flags ^= 1 << i; + } + i++; + } + + return s; +} + +u8 * format_rdma_device (u8 * s, va_list * args) { u32 i = va_arg (*args, u32); @@ -56,13 +80,33 @@ format_rdma_device (u8 * s, va_list * args) rdma_device_t *rd = vec_elt_at_index (rm->devices, i); u32 indent = format_get_indent (s); - s = format (s, "netdev: %v\n", rd->linux_ifname); + s = format (s, "netdev %v pci-addr %U\n", rd->linux_ifname, + format_vlib_pci_addr, &rd->pci->addr); s = format (s, "%Uflags: %U", format_white_space, indent, format_rdma_device_flags, rd); if (rd->error) s = format (s, "\n%Uerror %U", format_white_space, indent, format_clib_error, rd->error); + if (rd->flags & RDMA_DEVICE_F_MLX5DV) + { + struct mlx5dv_context c = { }; + const char *str_flags[7] = { "cqe-v1", "obsolete", "mpw-allowed", + "enhanced-mpw", "cqe-128b-comp", "cqe-128b-pad", + "packet-based-credit-mode" + }; + + if (mlx5dv_query_device (rd->ctx, &c) != 0) + return s; + + s = format (s, "\n%Umlx5: version %u", format_white_space, indent, + c.version); + s = format (s, "\n%Udevice flags: %U", + format_white_space, indent + 2, + format_rdma_bit_flag, c.flags, str_flags, + ARRAY_LEN (str_flags)); + } + return s; } @@ -74,11 +118,133 @@ format_rdma_input_trace (u8 * s, va_list * args) rdma_input_trace_t *t = va_arg (*args, rdma_input_trace_t *); vnet_main_t *vnm = vnet_get_main (); vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, t->hw_if_index); + char *l4_hdr_types[8] = + { 0, "tcp", "udp", "tcp-empty-ack", "tcp-with-acl" }; + char *l3_hdr_types[4] = { 0, "ip6", "ip4" }; + u8 l3_hdr_type = CQE_FLAG_L3_HDR_TYPE (t->cqe_flags); + u8 l4_hdr_type = CQE_FLAG_L4_HDR_TYPE (t->cqe_flags); s = format (s, "rdma: %v (%d) next-node %U", hi->name, t->hw_if_index, format_vlib_next_node_name, vm, node->index, t->next_index); + if (t->cqe_flags & CQE_FLAG_L2_OK) + s = format (s, " l2-ok"); + + if (t->cqe_flags & CQE_FLAG_L3_OK) + s = format (s, " l3-ok"); + + if (t->cqe_flags & CQE_FLAG_L4_OK) + s = format (s, " l4-ok"); + + if (t->cqe_flags & CQE_FLAG_IP_FRAG) + s = format (s, " ip-frag"); + + if (l3_hdr_type) + s = format (s, " %s", l3_hdr_types[l3_hdr_type]); + + if (l4_hdr_type) + s = format (s, " %s", l4_hdr_types[l4_hdr_type]); + + if ((t->cqe_flags & CQE_FLAG_IP_EXT_OPTS)) + { + if (l3_hdr_type == CQE_FLAG_L3_HDR_TYPE_IP6) + s = format (s, " ip4-ext-hdr"); + if (l3_hdr_type == CQE_FLAG_L3_HDR_TYPE_IP4) + s = format (s, " ip4-opt"); + } + + return s; +} + +static u8 * +format_mlx5_bits (u8 * s, va_list * args) +{ + void *ptr = va_arg (*args, void *); + u32 offset = va_arg (*args, u32); + u32 sb = va_arg (*args, u32); + u32 eb = va_arg (*args, u32); + + if (sb == 63 && eb == 0) + { + u64 x = mlx5_get_u64 (ptr, offset); + return format (s, "0x%lx", x); + } + + u32 x = mlx5_get_bits (ptr, offset, sb, eb); + s = format (s, "%d", x); + if (x > 9) + s = format (s, " (0x%x)", x); + return s; +} + +static u8 * +format_mlx5_field (u8 * s, va_list * args) +{ + void *ptr = va_arg (*args, void *); + u32 offset = va_arg (*args, u32); + u32 sb = va_arg (*args, u32); + u32 eb = va_arg (*args, u32); + char *name = va_arg (*args, char *); + + u8 *tmp = 0; + + tmp = format (0, "0x%02x %s ", offset, name); + if (sb == eb) + tmp = format (tmp, "[%u]", sb); + else + tmp = format (tmp, "[%u:%u]", sb, eb); + s = format (s, "%-45v = %U", tmp, format_mlx5_bits, ptr, offset, sb, eb); + vec_free (tmp); + + return s; +} + +u8 * +format_mlx5_cqe_rx (u8 * s, va_list * args) +{ + void *cqe = va_arg (*args, void *); + uword indent = format_get_indent (s); + int line = 0; + +#define _(a, b, c, d) \ + if (mlx5_get_bits (cqe, a, b, c)) \ + s = format (s, "%U%U\n", \ + format_white_space, line++ ? indent : 0, \ + format_mlx5_field, cqe, a, b, c, #d); + foreach_cqe_rx_field; +#undef _ + return s; +} + +u8 * +format_rdma_rxq (u8 * s, va_list * args) +{ + rdma_device_t *rd = va_arg (*args, rdma_device_t *); + u32 queue_index = va_arg (*args, u32); + rdma_rxq_t *rxq = vec_elt_at_index (rd->rxqs, queue_index); + u32 indent = format_get_indent (s); + + s = format (s, "size %u head %u tail %u", rxq->size, rxq->head, rxq->tail); + + if (rd->flags & RDMA_DEVICE_F_MLX5DV) + { + u32 next_cqe_index = rxq->cq_ci & (rxq->size - 1); + s = format (s, "\n%Uwq: stride %u wqe-cnt %u", + format_white_space, indent + 2, rxq->wq_stride, + rxq->wqe_cnt); + s = format (s, "\n%Ucq: cqn %u cqe-cnt %u ci %u", + format_white_space, indent + 2, rxq->cqn, + 1 << rxq->log2_cq_size, rxq->cq_ci); + s = format (s, "\n%Unext-cqe(%u):", format_white_space, indent + 4, + next_cqe_index); + s = format (s, "\n%U%U", format_white_space, indent + 6, + format_mlx5_cqe_rx, rxq->cqes + next_cqe_index); + s = format (s, "\n%U%U", format_white_space, indent + 6, + format_hexdump, rxq->cqes + next_cqe_index, + sizeof (mlx5dv_cqe_t)); + } + return s; } |