dpdk: correct waiting times 07/40407/2
authorGeorgy Borodin <bor1-go@yandex-team.ru>
Wed, 28 Feb 2024 16:04:44 +0000 (17:04 +0100)
committerDamjan Marion <dmarion@0xa5.net>
Tue, 5 Mar 2024 18:53:01 +0000 (18:53 +0000)
When link state interval is 3 and stats interval is 10, updates
for stats will be made every 12 seconds (next number after 10,
that divisible by 3). And if you get counters every 30 secs, you
will get ideal "saw"-line instead of real smooth chart.

This commit makes smooth line on stats intervals that are divisors
of the charts update interval (regardless of link state interval),
and makes it possible to configure them.

Type: fix
Fixes: cb9cadad578297ffd78fa8a33670bdf1ab669e7e
Change-Id: Ia4350467be2b0ec0c1be37c7fda63f43b3330f44
Signed-off-by: Georgy Borodin <bor1-go@yandex-team.ru>
src/plugins/dpdk/device/dpdk.h
src/plugins/dpdk/device/init.c

index 2864791..c22a67a 100644 (file)
@@ -222,11 +222,13 @@ typedef struct
   dpdk_port_conf_t conf;
 } dpdk_device_t;
 
+#define DPDK_MIN_POLL_INTERVAL (0.001) /* 1msec */
+
 #define DPDK_STATS_POLL_INTERVAL      (10.0)
-#define DPDK_MIN_STATS_POLL_INTERVAL  (0.001)  /* 1msec */
+#define DPDK_MIN_STATS_POLL_INTERVAL  DPDK_MIN_POLL_INTERVAL
 
 #define DPDK_LINK_POLL_INTERVAL       (3.0)
-#define DPDK_MIN_LINK_POLL_INTERVAL   (0.001)  /* 1msec */
+#define DPDK_MIN_LINK_POLL_INTERVAL   DPDK_MIN_POLL_INTERVAL
 
 #define foreach_dpdk_device_config_item                                       \
   _ (num_rx_queues)                                                           \
index 789add5..2da0258 100644 (file)
@@ -1009,6 +1009,26 @@ dpdk_log_read_ready (clib_file_t * uf)
   return 0;
 }
 
+static clib_error_t *
+dpdk_set_stat_poll_interval (f64 interval)
+{
+  if (interval < DPDK_MIN_STATS_POLL_INTERVAL)
+    return clib_error_return (0, "wrong stats-poll-interval value");
+
+  dpdk_main.stat_poll_interval = interval;
+  return 0;
+}
+
+static clib_error_t *
+dpdk_set_link_state_poll_interval (f64 interval)
+{
+  if (interval < DPDK_MIN_LINK_POLL_INTERVAL)
+    return clib_error_return (0, "wrong link-state-poll-interval value");
+
+  dpdk_main.link_state_poll_interval = interval;
+  return 0;
+}
+
 static clib_error_t *
 dpdk_config (vlib_main_t * vm, unformat_input_t * input)
 {
@@ -1033,6 +1053,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
   u32 vendor, device, domain, bus, func;
   void *fmt_func;
   void *fmt_addr;
+  f64 poll_interval;
 
   huge_dir_path =
     format (0, "%s/hugepages%c", vlib_unix_get_runtime_dir (), 0);
@@ -1071,6 +1092,18 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
       else if (unformat (input, "max-simd-bitwidth %U",
                         unformat_max_simd_bitwidth, &conf->max_simd_bitwidth))
        ;
+      else if (unformat (input, "link-state-poll-interval %f", &poll_interval))
+       {
+         error = dpdk_set_link_state_poll_interval (poll_interval);
+         if (error != 0)
+           return error;
+       }
+      else if (unformat (input, "stats-poll-interval %f", &poll_interval))
+       {
+         error = dpdk_set_stat_poll_interval (poll_interval);
+         if (error != 0)
+           return error;
+       }
       else if (unformat (input, "dev default %U", unformat_vlib_cli_sub_input,
                         &sub_input))
        {
@@ -1499,16 +1532,17 @@ dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
     dpdk_update_link_state (xd, now);
   }
 
+  f64 timeout =
+    clib_min (dm->link_state_poll_interval, dm->stat_poll_interval);
+
   while (1)
     {
-      /*
-       * check each time through the loop in case intervals are changed
-       */
-      f64 min_wait = dm->link_state_poll_interval < dm->stat_poll_interval ?
-       dm->link_state_poll_interval : dm->stat_poll_interval;
-
+      f64 min_wait = clib_max (timeout, DPDK_MIN_POLL_INTERVAL);
       vlib_process_wait_for_event_or_clock (vm, min_wait);
 
+      timeout =
+       clib_min (dm->link_state_poll_interval, dm->stat_poll_interval);
+
       if (dm->admin_up_down_in_progress)
        /* skip the poll if an admin up down is in progress (on any interface) */
        continue;
@@ -1522,8 +1556,16 @@ dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
          dpdk_update_link_state (xd, now);
 
       }
-    }
 
+      now = vlib_time_now (vm);
+      vec_foreach (xd, dm->devices)
+       {
+         timeout = clib_min (timeout, xd->time_last_stats_update +
+                                        dm->stat_poll_interval - now);
+         timeout = clib_min (timeout, xd->time_last_link_update +
+                                        dm->link_state_poll_interval - now);
+       }
+    }
   return 0;
 }