On 14 Sep 2024, at 7:26, Jun Wang wrote:

> For many network cards, xstat statistics cannot be queried in the
> ovs interface. A new interface is added to retrieve all xstat
> information of the network card.
Hi Jun,

Isn’t this already handled with netdev_dpdk_get_custom_stats()? I think you can 
see them with ‘ovs-vsctl get Interface <port> statistics.

If this is not the case this is what we should enhance.

//Eelco

> Reported-by: Jun Wang <[email protected]>
>
> Signed-off-by: Jun Wang <[email protected]>
> ---
>  lib/netdev-dpdk.c | 100 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 100 insertions(+)
>
> diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
> index a3878d2..59292e3 100644
> --- a/lib/netdev-dpdk.c
> +++ b/lib/netdev-dpdk.c
> @@ -4692,6 +4692,102 @@ out:
>      netdev_close(netdev);
>  }
>
> +static void
> +netdev_dpdk_show_port_xstats(struct unixctl_conn *conn,
> +                           uint16_t port_id, struct ds * ports_xstats)
> +{
> +    char *response = NULL;
> +    struct rte_eth_xstat_name *xstats_names;
> +    uint64_t *values;
> +    int len, ret, j;
> +    static const char *nic_stats_border = "########################";
> +
> +    if (!rte_eth_dev_is_valid_port(port_id)) {
> +        return;
> +    }
> +
> +    len = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
> +    if (len < 0) {
> +        response = xasprintf("Cannot get xstats count\n");
> +        goto err;
> +    }
> +    values = xmalloc(sizeof(*values) * len);
> +    if (values == NULL) {
> +        response = xasprintf("Cannot allocate memory for xstats\n");
> +        goto err;
> +    }
> +
> +    xstats_names = xmalloc(sizeof(struct rte_eth_xstat_name) * len);
> +    if (xstats_names == NULL) {
> +        response = xasprintf("Cannot allocate memory for xstat"
> +                             " names\n");
> +        free(values);
> +        goto err;
> +    }
> +    if (len != rte_eth_xstats_get_names_by_id(port_id, xstats_names,
> +                                              len, NULL)) {
> +        response = xasprintf("Cannot get xstat names\n");
> +        free(values);
> +        free(xstats_names);
> +        goto err;
> +    }
> +
> +    ds_put_format(ports_xstats, "###### NIC extended statistics for"
> +                  " port %-2d #########\n", port_id);
> +    ds_put_format(ports_xstats, "%s############################\n",
> +                  nic_stats_border);
> +    ret = rte_eth_xstats_get_by_id(port_id, NULL, values, len);
> +    if (ret < 0 || ret > len) {
> +        response = xasprintf("Cannot get xstats\n");
> +        free(values);
> +        free(xstats_names);
> +        goto err;
> +    }
> +
> +    for (j = 0; j < len; j++) {
> +        ds_put_format(ports_xstats, "%s: %"PRIu64"\n",
> +                      xstats_names[j].name, values[j]);
> +    }
> +
> +    ds_put_format(ports_xstats, "%s############################\n",
> +                  nic_stats_border);
> +
> +    free(values);
> +    free(xstats_names);
> +    return;
> +err:
> +    unixctl_command_reply_error(conn, response);
> +    free(response);
> +}
> +
> +static void
> +netdev_dpdk_show_xstats(struct unixctl_conn *conn, int argc,
> +                   const char *argv[], void *aux OVS_UNUSED)
> +{
> +    int i;
> +    struct ds ports_xstats = DS_EMPTY_INITIALIZER;
> +    struct netdev *netdev = NULL;
> +
> +    if (argc == 2) {
> +        netdev = netdev_from_name(argv[1]);
> +        if (!netdev || !is_dpdk_class(netdev->netdev_class)) {
> +            unixctl_command_reply_error(conn, "Not a DPDK Interface");
> +            goto xstats;
> +        }
> +        struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
> +        netdev_dpdk_show_port_xstats(conn, dev->port_id,
> +                                     &ports_xstats);
> +    } else {
> +        for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
> +            netdev_dpdk_show_port_xstats(conn, i, &ports_xstats);
> +        }
> +    }
> +    unixctl_command_reply(conn, ds_cstr(&ports_xstats));
> +xstats:
> +    ds_destroy(&ports_xstats);
> +    netdev_close(netdev);
> +}
> +
>  /*
>   * Set virtqueue flags so that we do not receive interrupts.
>   */
> @@ -5164,6 +5260,10 @@ netdev_dpdk_class_init(void)
>                                   "[netdev]", 0, 1,
>                                   netdev_dpdk_get_mempool_info, NULL);
>
> +        unixctl_command_register("netdev-dpdk/show-xstats",
> +                                 "[netdev]", 0, 1,
> +                                 netdev_dpdk_show_xstats, NULL);
> +
>          netdev_dpdk_reset_seq = seq_create();
>          netdev_dpdk_last_reset_seq = seq_read(netdev_dpdk_reset_seq);
>          ret = rte_eth_dev_callback_register(RTE_ETH_ALL,
> -- 
> 1.8.3.1
>
>
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to