aboutsummaryrefslogtreecommitdiffstats
path: root/src/vppinfra/time.c
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2020-03-10 09:01:02 -0400
committerFlorin Coras <florin.coras@gmail.com>2020-03-10 21:49:46 +0000
commit66441c4c6fa1fc32f9df510c7665886c6eb50189 (patch)
treea403c2b88a27a1443a60336448ef658035d3a52a /src/vppinfra/time.c
parentb55aec1c8e0c05520c47c3641c20684fc539f8a1 (diff)
vppinfra: improve timebase resilience
Deal with arbitrary kernel reference time changes: for example, yanking the kernel reference clock back to a time before vpp started. Best practice involves aligning the kernel reference clock with reality prior to starting apps which use 10us granularity timers. Compute change in the reference and cpu clocks. Recompute the vpp start time reference and and total cpu clock count, using the current clock tick rate. Next, compute a new clock rate sample. If the sample seems sane, factor it into the exponentially smoothed clock rate and recalculate total cpu ticks based on the new clock rate. Type: fix Signed-off-by: Dave Barach <dave@barachs.net> Change-Id: Ib6132ffbbe0e6d140725676de5e35be112a31dfe
Diffstat (limited to 'src/vppinfra/time.c')
-rw-r--r--src/vppinfra/time.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/vppinfra/time.c b/src/vppinfra/time.c
index edeca1f9c2f..0b00a11421d 100644
--- a/src/vppinfra/time.c
+++ b/src/vppinfra/time.c
@@ -251,15 +251,32 @@ void
clib_time_verify_frequency (clib_time_t * c)
{
f64 now_reference, delta_reference, delta_reference_max;
- u64 delta_clock;
+ f64 delta_clock_in_seconds;
+ u64 now_clock, delta_clock;
f64 new_clocks_per_second, delta;
/* Ask the kernel and the CPU what time it is... */
now_reference = unix_time_now ();
- c->last_cpu_time = clib_cpu_time_now ();
+ now_clock = clib_cpu_time_now ();
- /* Calculate a new clock rate sample */
+ /* Compute change in the reference clock */
delta_reference = now_reference - c->last_verify_reference_time;
+
+ /* And change in the CPU clock */
+ delta_clock_in_seconds = (f64) (now_clock - c->last_verify_cpu_time) *
+ c->seconds_per_clock;
+
+ /*
+ * Recompute vpp start time reference, and total clocks
+ * using the current clock rate
+ */
+ c->init_reference_time += (delta_reference - delta_clock_in_seconds);
+ c->total_cpu_time = (now_reference - c->init_reference_time)
+ * c->clocks_per_second;
+
+ c->last_cpu_time = now_clock;
+
+ /* Calculate a new clock rate sample */
delta_clock = c->last_cpu_time - c->last_verify_cpu_time;
c->last_verify_cpu_time = c->last_cpu_time;