dpdk: xstats as symlinks 68/41168/10
authorOle Troan <[email protected]>
Thu, 20 Jun 2024 20:33:19 +0000 (22:33 +0200)
committerDamjan Marion <[email protected]>
Wed, 9 Oct 2024 16:59:53 +0000 (16:59 +0000)
Type: improvement
Change-Id: I0df26e5a4d486b694ec90ba27b485a75bf264b20
Signed-off-by: Ole Troan <[email protected]>
src/plugins/dpdk/device/dpdk.h
src/plugins/dpdk/device/dpdk_priv.h
src/plugins/dpdk/device/init.c

index a069fbe..2440439 100644 (file)
@@ -131,7 +131,6 @@ typedef struct
   u32 interface_number_from_port_id : 1;
   u32 use_intel_phdr_cksum : 1;
   u32 int_unmaskable : 1;
-  vlib_simple_counter_main_t *xstats_counters;
 } dpdk_driver_t;
 
 dpdk_driver_t *dpdk_driver_find (const char *name, const char **desc);
@@ -211,6 +210,8 @@ typedef struct
   struct rte_eth_stats last_stats;
   struct rte_eth_xstat *xstats;
   f64 time_last_stats_update;
+  vlib_simple_counter_main_t xstats_counters;
+  u32 *xstats_symlinks;
 
   /* mac address */
   u8 *default_mac_address;
index e5b5a35..794953d 100644 (file)
@@ -54,39 +54,28 @@ dpdk_get_xstats (dpdk_device_t *xd, u32 thread_index)
 {
   int ret;
   int i;
-  int len;
   if (!(xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP))
     return;
-  if (xd->driver == 0)
-    return;
-  len = rte_eth_xstats_get (xd->port_id, NULL, 0);
-  if (len < 0)
-    return;
-
-  vec_validate (xd->xstats, len - 1);
 
-  ret = rte_eth_xstats_get (xd->port_id, xd->xstats, len);
-  if (ret < 0 || ret > len)
+  ret = rte_eth_xstats_get (xd->port_id, xd->xstats, vec_len (xd->xstats));
+  if (ret < 0)
     {
-      /* Failed, expand vector and try again on next time around the track. */
-      vec_validate (xd->xstats, ret - 1);
-      vec_set_len (xd->xstats, 0);
       dpdk_log_warn ("rte_eth_xstats_get(%d) failed: %d", xd->port_id, ret);
       return;
     }
-  if (len == vec_len (xd->driver->xstats_counters))
+  else if (ret != vec_len (xd->xstats))
     {
-      vec_foreach_index (i, xd->xstats)
-       {
-         vlib_set_simple_counter (&xd->driver->xstats_counters[i],
-                                  thread_index, xd->sw_if_index,
-                                  xd->xstats[i].value);
-       }
+      dpdk_log_warn (
+       "rte_eth_xstats_get(%d) returned %d/%d stats. Resetting counters.",
+       xd->port_id, ret, vec_len (xd->xstats));
+      dpdk_counters_xstats_init (xd);
+      return;
     }
-  else
+
+  vec_foreach_index (i, xd->xstats)
     {
-      dpdk_log_warn ("rte_eth_xstats_get vector size mismatch (%d/%d", len,
-                    vec_len (xd->driver->xstats_counters));
+      vlib_set_simple_counter (&xd->xstats_counters, thread_index, i,
+                              xd->xstats[i].value);
     }
 }
 
index fa1b234..e63a281 100644 (file)
@@ -227,71 +227,71 @@ dpdk_find_startup_config (struct rte_eth_dev_info *di)
 }
 
 /*
- * Initialise or refresh the xstats counters for a device
+ * Initialise the xstats counters for a device
  */
 void
 dpdk_counters_xstats_init (dpdk_device_t *xd)
 {
   int len, ret, i;
   struct rte_eth_xstat_name *xstats_names = 0;
-  char *name;
-  dpdk_driver_t *dr = xd->driver;
 
-  /* Only support xstats for supported drivers */
-  if (!dr)
-    return;
+  if (vec_len (xd->xstats_symlinks) > 0)
+    {
+      /* xstats already initialized. Reset counters */
+      vec_foreach_index (i, xd->xstats_symlinks)
+       {
+         vlib_stats_remove_entry (xd->xstats_symlinks[i]);
+       }
+    }
+  else
+    {
+      xd->xstats_counters.stat_segment_name =
+       (char *) format (0, "/if/xstats/%d%c", xd->sw_if_index, 0);
+      xd->xstats_counters.counters = 0;
+    }
 
   len = rte_eth_xstats_get_names (xd->port_id, 0, 0);
   if (len < 0)
     {
-      dpdk_log_err ("[%u] rte_eth_xstats_get_names failed: %d", xd->port_id,
-                   len);
-      return;
-    }
-  /* Counters for this driver is already initialised */
-  if (vec_len (dr->xstats_counters) == len)
-    {
-      vec_foreach_index (i, dr->xstats_counters)
-       {
-         vlib_validate_simple_counter (&dr->xstats_counters[i],
-                                       xd->sw_if_index);
-         vlib_zero_simple_counter (&dr->xstats_counters[i], xd->sw_if_index);
-       }
+      dpdk_log_err ("[%u] rte_eth_xstats_get_names failed: %d. DPDK xstats "
+                   "not configured.",
+                   xd->port_id, len);
       return;
     }
 
-  /* Same driver, different interface, different length of counter array. */
-  ASSERT (vec_len (dr->xstats_counters) == 0);
+  vlib_validate_simple_counter (&xd->xstats_counters, len);
+  vlib_zero_simple_counter (&xd->xstats_counters, len);
 
   vec_validate (xstats_names, len - 1);
+  vec_validate (xd->xstats, len - 1);
+  vec_validate (xd->xstats_symlinks, len - 1);
 
   ret = rte_eth_xstats_get_names (xd->port_id, xstats_names, len);
   if (ret >= 0 && ret <= len)
     {
-      vec_validate (dr->xstats_counters, len - 1);
       vec_foreach_index (i, xstats_names)
        {
-         name = (char *) format (0, "/if/%s/%s%c", dr->drivers->name,
-                                 xstats_names[i].name, 0);
-
          /* There is a bug in the ENA driver where the xstats names are not
           * unique. */
-         if (vlib_stats_find_entry_index (name) != STAT_SEGMENT_INDEX_INVALID)
+         xd->xstats_symlinks[i] = vlib_stats_add_symlink (
+           xd->xstats_counters.stats_entry_index, i, "/interfaces/%U/%s%c",
+           format_vnet_sw_if_index_name, vnet_get_main (), xd->sw_if_index,
+           xstats_names[i].name, 0);
+         if (xd->xstats_symlinks[i] == STAT_SEGMENT_INDEX_INVALID)
            {
-             vec_free (name);
-             name = (char *) format (0, "/if/%s/%s_%d%c", dr->drivers->name,
-                                     xstats_names[i].name, i, 0);
+             xd->xstats_symlinks[i] = vlib_stats_add_symlink (
+               xd->xstats_counters.stats_entry_index, i,
+               "/interfaces/%U/%s_%d%c", format_vnet_sw_if_index_name,
+               vnet_get_main (), xd->sw_if_index, xstats_names[i].name, i, 0);
            }
-
-         dr->xstats_counters[i].name = name;
-         dr->xstats_counters[i].stat_segment_name = name;
-         dr->xstats_counters[i].counters = 0;
-         vlib_validate_simple_counter (&dr->xstats_counters[i],
-                                       xd->sw_if_index);
-         vlib_zero_simple_counter (&dr->xstats_counters[i], xd->sw_if_index);
-         vec_free (name);
        }
     }
+  else
+    {
+      dpdk_log_err ("[%u] rte_eth_xstats_get_names failed: %d. DPDK xstats "
+                   "not configured.",
+                   xd->port_id, ret);
+    }
   vec_free (xstats_names);
 }