net/sfc: fix xstats query by unsorted list of IDs
authorIvan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Fri, 23 Jul 2021 13:15:10 +0000 (16:15 +0300)
committerThomas Monjalon <thomas@monjalon.net>
Fri, 23 Jul 2021 21:05:19 +0000 (23:05 +0200)
Device may support only some MAC stats. Add mapping from ids to subset
of supported MAC stats for each port.

Fixes: 73280c1e4ff ("net/sfc: support xstats retrieval by ID")
Cc: stable@dpdk.org
Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
drivers/net/sfc/sfc.h
drivers/net/sfc/sfc_ethdev.c
drivers/net/sfc/sfc_port.c

index c7b0e5a..972d326 100644 (file)
@@ -141,6 +141,8 @@ struct sfc_port {
 
        uint32_t                mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES];
 
+       unsigned int                    mac_stats_by_id[EFX_MAC_NSTATS];
+
        uint64_t                        ipackets;
 };
 
index fca3f52..ae9304f 100644 (file)
@@ -788,8 +788,6 @@ sfc_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
        struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
        struct sfc_port *port = &sa->port;
        uint64_t *mac_stats;
-       unsigned int nb_supported = 0;
-       unsigned int nb_written = 0;
        unsigned int i;
        int ret;
        int rc;
@@ -808,17 +806,19 @@ sfc_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 
        mac_stats = port->mac_stats_buf;
 
-       for (i = 0; (i < EFX_MAC_NSTATS) && (nb_written < n); ++i) {
-               if (!EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i))
-                       continue;
-
-               if (ids[nb_written] == nb_supported)
-                       values[nb_written++] = mac_stats[i];
+       SFC_ASSERT(port->mac_stats_nb_supported <=
+                  RTE_DIM(port->mac_stats_by_id));
 
-               ++nb_supported;
+       for (i = 0; i < n; i++) {
+               if (ids[i] < port->mac_stats_nb_supported) {
+                       values[i] = mac_stats[port->mac_stats_by_id[ids[i]]];
+               } else {
+                       ret = i;
+                       goto unlock;
+               }
        }
 
-       ret = nb_written;
+       ret = n;
 
 unlock:
        sfc_adapter_unlock(sa);
@@ -833,8 +833,7 @@ sfc_xstats_get_names_by_id(struct rte_eth_dev *dev,
 {
        struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
        struct sfc_port *port = &sa->port;
-       unsigned int nb_supported = 0;
-       unsigned int nb_written = 0;
+       unsigned int nb_supported;
        unsigned int i;
 
        if (unlikely(xstats_names == NULL && ids != NULL) ||
@@ -849,23 +848,24 @@ sfc_xstats_get_names_by_id(struct rte_eth_dev *dev,
                return nb_supported;
        }
 
-       for (i = 0; (i < EFX_MAC_NSTATS) && (nb_written < size); ++i) {
-               if (!EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i))
-                       continue;
-
-               if (ids[nb_written] == nb_supported) {
-                       char *name = xstats_names[nb_written++].name;
+       SFC_ASSERT(port->mac_stats_nb_supported <=
+                  RTE_DIM(port->mac_stats_by_id));
 
-                       strlcpy(name, efx_mac_stat_name(sa->nic, i),
+       for (i = 0; i < size; i++) {
+               if (ids[i] < port->mac_stats_nb_supported) {
+                       strlcpy(xstats_names[i].name,
+                               efx_mac_stat_name(sa->nic,
+                                                port->mac_stats_by_id[ids[i]]),
                                sizeof(xstats_names[0].name));
+               } else {
+                       sfc_adapter_unlock(sa);
+                       return i;
                }
-
-               ++nb_supported;
        }
 
        sfc_adapter_unlock(sa);
 
-       return nb_written;
+       return size;
 }
 
 static int
index cdc0f94..bb9e01d 100644 (file)
@@ -157,6 +157,27 @@ sfc_port_phy_caps_to_max_link_speed(uint32_t phy_caps)
 
 #endif
 
+static void
+sfc_port_fill_mac_stats_info(struct sfc_adapter *sa)
+{
+       unsigned int mac_stats_nb_supported = 0;
+       struct sfc_port *port = &sa->port;
+       unsigned int stat_idx;
+
+       efx_mac_stats_get_mask(sa->nic, port->mac_stats_mask,
+                              sizeof(port->mac_stats_mask));
+
+       for (stat_idx = 0; stat_idx < EFX_MAC_NSTATS; ++stat_idx) {
+               if (!EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, stat_idx))
+                       continue;
+
+               port->mac_stats_by_id[mac_stats_nb_supported] = stat_idx;
+               mac_stats_nb_supported++;
+       }
+
+       port->mac_stats_nb_supported = mac_stats_nb_supported;
+}
+
 int
 sfc_port_start(struct sfc_adapter *sa)
 {
@@ -165,7 +186,6 @@ sfc_port_start(struct sfc_adapter *sa)
        uint32_t phy_adv_cap;
        const uint32_t phy_pause_caps =
                ((1u << EFX_PHY_CAP_PAUSE) | (1u << EFX_PHY_CAP_ASYM));
-       unsigned int i;
 
        sfc_log_init(sa, "entry");
 
@@ -259,12 +279,7 @@ sfc_port_start(struct sfc_adapter *sa)
                port->mac_stats_reset_pending = B_FALSE;
        }
 
-       efx_mac_stats_get_mask(sa->nic, port->mac_stats_mask,
-                              sizeof(port->mac_stats_mask));
-
-       for (i = 0, port->mac_stats_nb_supported = 0; i < EFX_MAC_NSTATS; ++i)
-               if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i))
-                       port->mac_stats_nb_supported++;
+       sfc_port_fill_mac_stats_info(sa);
 
        port->mac_stats_update_generation = 0;