Blob Blame History Raw
From 07a8062a47609a58c67692635e99ae6275207dee Mon Sep 17 00:00:00 2001
From: Vadim Fedorenko <vadfed@meta.com>
Date: Wed, 11 Jan 2023 06:58:36 -0800
Subject: [PATCH 2/2] filter: treat negative path_delay as a spike

There should be no negative path delay during normal operation. Let's
filter such values out. And with that fix there is no need to use
"best" frequency in case of holdover - just use the latest mean from
the filter.

Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
---
 clock.c   |  4 ++--
 mmedian.c | 21 ++++++++++++++++-----
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/clock.c b/clock.c
index 3787ec7..6c9c12c 100644
--- a/clock.c
+++ b/clock.c
@@ -1973,9 +1973,9 @@ enum servo_state clock_synchronize(struct clock *c, tmv_t ingress, tmv_t origin)
 
 			bool is_spike = llabs(offset) > llabs(max_func(c->max_offset_locked, c->min_offset_locked));
 			if (is_spike) {
-				adj = c->min_offset_freq_mean;
+				adj = c->freq_mean;
 				c->master_offset = nanoseconds_to_tmv(c->max_offset_locked);
-				pr_notice("spike detected => max_offset_locked: %ld, setting offset to min_offset_freq_mean: %lf", c->max_offset_locked, adj);
+				pr_notice("spike detected => max_offset_locked: %ld, setting freq to freq_mean: %lf", c->max_offset_locked, adj);
 				clock_synchronize_locked(c, adj);
 				if (c->offset_skipped_count < c->max_offset_skipped_count) {
 					c->offset_skipped_count++;
diff --git a/mmedian.c b/mmedian.c
index 2383467..50d8b90 100644
--- a/mmedian.c
+++ b/mmedian.c
@@ -21,6 +21,7 @@
 
 #include "mmedian.h"
 #include "filter_private.h"
+#include "print.h"
 
 struct mmedian {
 	struct filter filter;
@@ -41,11 +42,25 @@ static void mmedian_destroy(struct filter *filter)
 	free(m);
 }
 
+static inline tmv_t mmedian_calc_pdelay(const struct mmedian *m)
+{
+	if (m->cnt % 2)
+		return m->samples[m->order[m->cnt / 2]];
+	else
+		return tmv_div(tmv_add(m->samples[m->order[m->cnt / 2 - 1]],
+				       m->samples[m->order[m->cnt / 2]]), 2);
+}
+
 static tmv_t mmedian_sample(struct filter *filter, tmv_t sample)
 {
 	struct mmedian *m = container_of(filter, struct mmedian, filter);
 	int i;
 
+	if (m->cnt && tmv_to_nanoseconds(sample) < 2000) {
+		pr_info("skipping path delay sample %ld", tmv_to_nanoseconds(sample));
+		return mmedian_calc_pdelay(m);
+	}
+
 	m->samples[m->index] = sample;
 	if (m->cnt < m->len) {
 		m->cnt++;
@@ -69,11 +84,7 @@ static tmv_t mmedian_sample(struct filter *filter, tmv_t sample)
 
 	m->index = (1 + m->index) % m->len;
 
-	if (m->cnt % 2)
-		return m->samples[m->order[m->cnt / 2]];
-	else
-		return tmv_div(tmv_add(m->samples[m->order[m->cnt / 2 - 1]],
-				       m->samples[m->order[m->cnt / 2]]), 2);
+	return mmedian_calc_pdelay(m);
 }
 
 static void mmedian_reset(struct filter *filter)
-- 
2.30.2