Re: [Linuxptp-devel] [PATCHv2 3/6] tsproc: add raw and weighting modes.

2015-03-26 Thread Richard Cochran
On Tue, Mar 17, 2015 at 11:28:22AM +0100, Miroslav Lichvar wrote:
 Add new time stamp processing modes to return raw delay and offset based
 on the raw delay instead of the long-term filtered delay, and to return
 also a weight of the sample. The weight is set to the ratio between the
 two delays. This gives smaller weight to samples where the sync and/or
 delay messages were delayed significantly in the network and possibly
 include a large error.
 
 Signed-off-by: Miroslav Lichvar mlich...@redhat.com
 ---

Patches 3 to 6 all look good to me.

Thanks,
Richard

--
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] how to measure frequency offset without correcting?

2015-03-26 Thread Keller, Jacob E
Hey,

I am attempting to use phc2sys and debug some new hardware, and I want
to be able to sort of free-running mode measure the difference clock
offset and frequency offset, but without actually passing corrections.

Is there a way to do this? The reason for this is that I believe that my
adjfreq function is not correct, so I don't want it to be run, and I
would like to be able to see if software can get some sort of measure of
how fast my clock is running. I think it's possible my base frequency is
incorrect right now.

Regards,
Jake
--
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] how to measure frequency offset without correcting?

2015-03-26 Thread Gary E. Miller
Yo Jacob E!

On Thu, 26 Mar 2015 22:28:58 +
Keller, Jacob E jacob.e.kel...@intel.com wrote:

 I am attempting to use phc2sys and debug some new hardware, and I want
 to be able to sort of free-running mode measure the difference clock
 offset and frequency offset, but without actually passing corrections.

You can try to set the ntpd refclock as noselect.  I find ntpd will still
select the clock sometimes.  So I'll add a huge fudge, like 1000, but
even that does not always work if this refclock is the only one sane.

If you are masochistic you can send phc2sys to a SHM, but not tell ntpd
it is a refclock.  Pull the raw SHM data using a program like ntpshmmon
from the gpsd package.  It is not to hard to parse after that.

RGDS
GARY
---
Gary E. Miller Rellim 109 NW Wilmington Ave., Suite E, Bend, OR 97701
g...@rellim.com  Tel:+1(541)382-8588

--
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCHv3 3/6] tsproc: add raw and weighting modes.

2015-03-26 Thread Miroslav Lichvar
Add new time stamp processing modes to return raw delay and offset based
on the raw delay instead of the long-term filtered delay, and to return
also a weight of the sample. The weight is set to the ratio between the
two delays. This gives smaller weight to samples where the sync and/or
delay messages were delayed significantly in the network and possibly
include a large error.

Signed-off-by: Miroslav Lichvar mlich...@redhat.com
---
 clock.c |  5 +++--
 config.c| 24 
 config.h|  1 +
 default.cfg |  1 +
 ds.h|  2 ++
 gPTP.cfg|  1 +
 port.c  |  3 ++-
 ptp4l.8 |  8 
 ptp4l.c |  1 +
 tsproc.c| 51 ++-
 tsproc.h| 17 +++--
 11 files changed, 104 insertions(+), 10 deletions(-)

diff --git a/clock.c b/clock.c
index 9735fbd..71fda50 100644
--- a/clock.c
+++ b/clock.c
@@ -852,7 +852,8 @@ struct clock *clock_create(int phc_index, struct 
interfaces_head *ifaces,
}
c-servo_state = SERVO_UNLOCKED;
c-servo_type = servo;
-   c-tsproc = tsproc_create(dds-delay_filter, dds-delay_filter_length);
+   c-tsproc = tsproc_create(dds-tsproc_mode, dds-delay_filter,
+ dds-delay_filter_length);
if (!c-tsproc) {
pr_err(Failed to create time stamp processor);
return NULL;
@@ -1357,7 +1358,7 @@ enum servo_state clock_synchronize(struct clock *c, tmv_t 
ingress, tmv_t origin)
 
tsproc_down_ts(c-tsproc, origin, ingress);
 
-   if (tsproc_update_offset(c-tsproc, c-master_offset))
+   if (tsproc_update_offset(c-tsproc, c-master_offset, NULL))
return state;
 
if (clock_utc_correct(c, ingress))
diff --git a/config.c b/config.c
index ec8c538..ee0f302 100644
--- a/config.c
+++ b/config.c
@@ -203,6 +203,18 @@ static enum parser_result parse_port_setting(const char 
*option,
else
return BAD_VALUE;
 
+   } else if (!strcmp(option, tsproc_mode)) {
+   if (!strcasecmp(filter, value))
+   iface-tsproc_mode = TSPROC_FILTER;
+   else if (!strcasecmp(raw, value))
+   iface-tsproc_mode = TSPROC_RAW;
+   else if (!strcasecmp(filter_weight, value))
+   iface-tsproc_mode = TSPROC_FILTER_WEIGHT;
+   else if (!strcasecmp(raw_weight, value))
+   iface-tsproc_mode = TSPROC_RAW_WEIGHT;
+   else
+   return BAD_VALUE;
+
} else if (!strcmp(option, delay_filter)) {
if (!strcasecmp(moving_average, value))
iface-delay_filter = FILTER_MOVING_AVERAGE;
@@ -566,6 +578,18 @@ static enum parser_result parse_global_setting(const char 
*option,
return r;
cfg-dds.time_source = val;
 
+   } else if (!strcmp(option, tsproc_mode)) {
+   if (!strcasecmp(filter, value))
+   cfg-dds.tsproc_mode = TSPROC_FILTER;
+   else if (!strcasecmp(raw, value))
+   cfg-dds.tsproc_mode = TSPROC_RAW;
+   else if (!strcasecmp(filter_weight, value))
+   cfg-dds.tsproc_mode = TSPROC_FILTER_WEIGHT;
+   else if (!strcasecmp(raw_weight, value))
+   cfg-dds.tsproc_mode = TSPROC_RAW_WEIGHT;
+   else
+   return BAD_VALUE;
+
} else if (!strcmp(option, delay_filter)) {
if (!strcasecmp(moving_average, value))
cfg-dds.delay_filter = FILTER_MOVING_AVERAGE;
diff --git a/config.h b/config.h
index c870e42..7bff11f 100644
--- a/config.h
+++ b/config.h
@@ -39,6 +39,7 @@ struct interface {
enum transport_type transport;
struct port_defaults pod;
struct sk_ts_info ts_info;
+   enum tsproc_mode tsproc_mode;
enum filter_type delay_filter;
int delay_filter_length;
int boundary_clock_jbod;
diff --git a/default.cfg b/default.cfg
index ec2ce58..b46c0f6 100644
--- a/default.cfg
+++ b/default.cfg
@@ -68,6 +68,7 @@ uds_address   /var/run/ptp4l
 network_transport  UDPv4
 delay_mechanismE2E
 time_stamping  hardware
+tsproc_modefilter
 delay_filter   moving_median
 delay_filter_length10
 egressLatency  0
diff --git a/ds.h b/ds.h
index 8f44c3b..162687a 100644
--- a/ds.h
+++ b/ds.h
@@ -23,6 +23,7 @@
 #include ddt.h
 #include fault.h
 #include filter.h
+#include tsproc.h
 
 /* clock data sets */
 
@@ -59,6 +60,7 @@ struct default_ds {
int sanity_freq_limit;
int time_source;
struct clock_description clock_desc;
+   enum tsproc_mode tsproc_mode;
enum filter_type delay_filter;
int delay_filter_length;
int boundary_clock_jbod;
diff --git a/gPTP.cfg b/gPTP.cfg
index d917bd7..34fa238 100644
--- 

[Linuxptp-devel] [PATCHv3 5/6] linreg: use sample weight.

2015-03-26 Thread Miroslav Lichvar
Signed-off-by: Miroslav Lichvar mlich...@redhat.com
---
 linreg.c | 48 
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/linreg.c b/linreg.c
index 3f7fe9a..8f354f4 100644
--- a/linreg.c
+++ b/linreg.c
@@ -42,6 +42,7 @@
 struct point {
uint64_t x;
uint64_t y;
+   double w;
 };
 
 struct result {
@@ -70,6 +71,8 @@ struct linreg_servo {
uint64_t last_update;
/* Regression results for all sizes */
struct result results[MAX_SIZE - MIN_SIZE + 1];
+   /* Selected size */
+   unsigned int size;
/* Current frequency offset of the clock */
double clock_freq;
/* Expected interval between updates */
@@ -120,12 +123,13 @@ static void update_reference(struct linreg_servo *s, 
uint64_t local_ts)
s-last_update = local_ts;
 }
 
-static void add_sample(struct linreg_servo *s, int64_t offset)
+static void add_sample(struct linreg_servo *s, int64_t offset, double weight)
 {
s-last_point = (s-last_point + 1) % MAX_POINTS;
 
s-points[s-last_point].x = s-reference.x;
s-points[s-last_point].y = s-reference.y - offset;
+   s-points[s-last_point].w = weight;
 
if (s-num_points  MAX_POINTS)
s-num_points++;
@@ -133,11 +137,11 @@ static void add_sample(struct linreg_servo *s, int64_t 
offset)
 
 static void regress(struct linreg_servo *s)
 {
-   double x, y, y0, e, x_sum, y_sum, xy_sum, x2_sum;
+   double x, y, y0, e, x_sum, y_sum, xy_sum, x2_sum, w, w_sum;
unsigned int i, l, n, size;
struct result *res;
 
-   x_sum = 0.0, y_sum = 0.0, xy_sum = 0.0, x2_sum = 0.0;
+   x_sum = 0.0, y_sum = 0.0, xy_sum = 0.0, x2_sum = 0.0; w_sum = 0.0;
i = 0;
 
y0 = (int64_t)(s-points[s-last_point].y - s-reference.y);
@@ -169,27 +173,30 @@ static void regress(struct linreg_servo *s)
 
x = (int64_t)(s-points[l].x - s-reference.x);
y = (int64_t)(s-points[l].y - s-reference.y);
+   w = s-points[l].w;
 
-   x_sum += x;
-   y_sum += y;
-   xy_sum += x * y;
-   x2_sum += x * x;
+   x_sum += x * w;
+   y_sum += y * w;
+   xy_sum += x * y * w;
+   x2_sum += x * x * w;
+   w_sum += w;
}
 
/* Get new intercept and slope */
-   res-slope = (xy_sum - x_sum * y_sum / n) /
-   (x2_sum - x_sum * x_sum / n);
-   res-intercept = (y_sum - res-slope * x_sum) / n;
+   res-slope = (xy_sum - x_sum * y_sum / w_sum) /
+   (x2_sum - x_sum * x_sum / w_sum);
+   res-intercept = (y_sum - res-slope * x_sum) / w_sum;
}
 }
 
-/* Return largest size with smallest prediction error */
-static int get_best_size(struct linreg_servo *s)
+static void update_size(struct linreg_servo *s)
 {
struct result *res;
double best_err;
int size, best_size;
 
+   /* Find largest size with smallest prediction error */
+
best_size = 0;
best_err = 0.0;
 
@@ -203,7 +210,7 @@ static int get_best_size(struct linreg_servo *s)
}
}
 
-   return best_size;
+   s-size = best_size;
 }
 
 static double linreg_sample(struct servo *servo,
@@ -214,7 +221,7 @@ static double linreg_sample(struct servo *servo,
 {
struct linreg_servo *s = container_of(servo, struct linreg_servo, 
servo);
struct result *res;
-   int size, corr_interval;
+   int corr_interval;
 
/*
 * The current time and the time when will be the frequency of the
@@ -225,21 +232,21 @@ static double linreg_sample(struct servo *servo,
 */
 
update_reference(s, local_ts);
-   add_sample(s, offset);
+   add_sample(s, offset, weight);
regress(s);
 
-   size = get_best_size(s);
+   update_size(s);
 
-   if (size  MIN_SIZE) {
+   if (s-size  MIN_SIZE) {
/* Not enough points, wait for more */
*state = SERVO_UNLOCKED;
return -s-clock_freq;
}
 
-   res = s-results[size - MIN_SIZE];
+   res = s-results[s-size - MIN_SIZE];
 
pr_debug(linreg: points %d slope %.9f intercept %.0f err %.0f,
-   1  size, res-slope, res-intercept, res-err);
+1  s-size, res-slope, res-intercept, res-err);
 
if ((servo-first_update 
 servo-first_step_threshold 
@@ -265,7 +272,7 @@ static double linreg_sample(struct servo *servo,
 * correction slowing down the clock will result in an overshoot. With
 * the system clock's maximum adjustment of 10% that's acceptable.
 */
-   corr_interval = size = 4 ? 1 : size / 2;
+   corr_interval = s-size = 4 ? 1 

[Linuxptp-devel] [PATCHv3 0/6] Improve accuracy with software timestamping

2015-03-26 Thread Miroslav Lichvar
Changes since v2:
- fix swapped origin/ingress timestamps in port_nrate_calculate()
- use one field per line in tsproc struct
- use tmv_is_zero()
- don't allow NULL offset in tsproc_update_offset()

Changes since v1:
- include the changes to refactor time stamp processing
- raw and weighting modes are configurable (disabled by default)

This adds new time stamp processing modes that are suitable with
software time stamping.

The idea is to give smaller weights to samples where the sync and/or
delay messages were delayed significantly in the network and possibly
include a large error. The sample offset is based directly on the
sample delay instead of the long-term filtered delay and the sample
weight is set to the ratio of the sample delay to the long-term
average. E.g. if the measured delay is normally 1 ms and the new
sample has 10ms delay, the sample weight (and the clock adjustment
that will be made) will be 10 times smaller.

Miroslav Lichvar (6):
  Convert and correct time stamps early.
  Refactor time stamp processing.
  tsproc: add raw and weighting modes.
  servo: add support for weighted samples.
  linreg: use sample weight.
  pi: use sample weight.

 clock.c | 143 ---
 clock.h |  24 +++
 config.c|  24 +++
 config.h|   1 +
 default.cfg |   1 +
 ds.h|   2 +
 gPTP.cfg|   1 +
 linreg.c|  49 --
 makefile|   2 +-
 ntpshm.c|   1 +
 phc2sys.c   |   2 +-
 pi.c|   5 +-
 port.c  |  82 +--
 ptp4l.8 |   8 +++
 ptp4l.c |   1 +
 servo.c |   3 +-
 servo.h |   3 +
 servo_private.h |   2 +-
 tsproc.c| 204 
 tsproc.h| 110 ++
 20 files changed, 491 insertions(+), 177 deletions(-)
 create mode 100644 tsproc.c
 create mode 100644 tsproc.h

-- 
2.1.0


--
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCHv3 6/6] pi: use sample weight.

2015-03-26 Thread Miroslav Lichvar
Signed-off-by: Miroslav Lichvar mlich...@redhat.com
---
 pi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pi.c b/pi.c
index 9c7b148..e0116fe 100644
--- a/pi.c
+++ b/pi.c
@@ -137,8 +137,8 @@ static double pi_sample(struct servo *servo,
break;
}
 
-   ki_term = s-ki * offset;
-   ppb = s-kp * offset + s-drift + ki_term;
+   ki_term = s-ki * offset * weight;
+   ppb = s-kp * offset * weight + s-drift + ki_term;
if (ppb  -servo-max_frequency) {
ppb = -servo-max_frequency;
} else if (ppb  servo-max_frequency) {
-- 
2.1.0


--
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCHv3 4/6] servo: add support for weighted samples.

2015-03-26 Thread Miroslav Lichvar
Add weight parameter to the sample function. Samples with smaller weight
are less reliable, they can be ignored by the servo or the adjustments
of the clock can be smaller.

Signed-off-by: Miroslav Lichvar mlich...@redhat.com
---
 clock.c | 6 +++---
 linreg.c| 1 +
 ntpshm.c| 1 +
 phc2sys.c   | 2 +-
 pi.c| 1 +
 servo.c | 3 ++-
 servo.h | 3 +++
 servo_private.h | 2 +-
 8 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/clock.c b/clock.c
index 71fda50..3350b3d 100644
--- a/clock.c
+++ b/clock.c
@@ -1351,14 +1351,14 @@ int clock_switch_phc(struct clock *c, int phc_index)
 
 enum servo_state clock_synchronize(struct clock *c, tmv_t ingress, tmv_t 
origin)
 {
-   double adj;
+   double adj, weight;
enum servo_state state = SERVO_UNLOCKED;
 
c-ingress_ts = ingress;
 
tsproc_down_ts(c-tsproc, origin, ingress);
 
-   if (tsproc_update_offset(c-tsproc, c-master_offset, NULL))
+   if (tsproc_update_offset(c-tsproc, c-master_offset, weight))
return state;
 
if (clock_utc_correct(c, ingress))
@@ -1370,7 +1370,7 @@ enum servo_state clock_synchronize(struct clock *c, tmv_t 
ingress, tmv_t origin)
return clock_no_adjust(c, ingress, origin);
 
adj = servo_sample(c-servo, tmv_to_nanoseconds(c-master_offset),
-  tmv_to_nanoseconds(ingress), state);
+  tmv_to_nanoseconds(ingress), weight, state);
c-servo_state = state;
 
if (c-stats.max_count  1) {
diff --git a/linreg.c b/linreg.c
index fde604d..3f7fe9a 100644
--- a/linreg.c
+++ b/linreg.c
@@ -209,6 +209,7 @@ static int get_best_size(struct linreg_servo *s)
 static double linreg_sample(struct servo *servo,
int64_t offset,
uint64_t local_ts,
+   double weight,
enum servo_state *state)
 {
struct linreg_servo *s = container_of(servo, struct linreg_servo, 
servo);
diff --git a/ntpshm.c b/ntpshm.c
index 21a11cf..8b18e2d 100644
--- a/ntpshm.c
+++ b/ntpshm.c
@@ -80,6 +80,7 @@ static void ntpshm_destroy(struct servo *servo)
 static double ntpshm_sample(struct servo *servo,
int64_t offset,
uint64_t local_ts,
+   double weight,
enum servo_state *state)
 {
struct ntpshm_servo *s = container_of(servo, struct ntpshm_servo, 
servo);
diff --git a/phc2sys.c b/phc2sys.c
index 23993ac..9ff5bf9 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -469,7 +469,7 @@ static void update_clock(struct node *node, struct clock 
*clock,
if (clock-sanity_check  clockcheck_sample(clock-sanity_check, ts))
servo_reset(clock-servo);
 
-   ppb = servo_sample(clock-servo, offset, ts, state);
+   ppb = servo_sample(clock-servo, offset, ts, 1.0, state);
clock-servo_state = state;
 
switch (state) {
diff --git a/pi.c b/pi.c
index c8b8587..9c7b148 100644
--- a/pi.c
+++ b/pi.c
@@ -64,6 +64,7 @@ static void pi_destroy(struct servo *servo)
 static double pi_sample(struct servo *servo,
int64_t offset,
uint64_t local_ts,
+   double weight,
enum servo_state *state)
 {
struct pi_servo *s = container_of(servo, struct pi_servo, servo);
diff --git a/servo.c b/servo.c
index f200f75..2739ebd 100644
--- a/servo.c
+++ b/servo.c
@@ -78,11 +78,12 @@ void servo_destroy(struct servo *servo)
 double servo_sample(struct servo *servo,
int64_t offset,
uint64_t local_ts,
+   double weight,
enum servo_state *state)
 {
double r;
 
-   r = servo-sample(servo, offset, local_ts, state);
+   r = servo-sample(servo, offset, local_ts, weight, state);
 
if (*state != SERVO_UNLOCKED)
servo-first_update = 0;
diff --git a/servo.h b/servo.h
index e054501..4be8c23 100644
--- a/servo.h
+++ b/servo.h
@@ -104,12 +104,15 @@ void servo_destroy(struct servo *servo);
  * @param servo Pointer to a servo obtained via @ref servo_create().
  * @param offsetThe estimated clock offset in nanoseconds.
  * @param local_ts  The local time stamp of the sample in nanoseconds.
+ * @param weightThe weight of the sample, larger if more reliable,
+ *  1.0 is the maximum value.
  * @param state Returns the servo's state.
  * @return The clock adjustment in parts per billion.
  */
 double servo_sample(struct servo *servo,
int64_t offset,
uint64_t local_ts,
+   double weight,
enum servo_state *state);
 
 /**
diff --git a/servo_private.h b/servo_private.h
index 9a1a459..b8c3c98 100644
--- a/servo_private.h
+++ b/servo_private.h
@@ -30,7 +30,7 @@ struct servo {
void 

[Linuxptp-devel] [PATCHv3 2/6] Refactor time stamp processing.

2015-03-26 Thread Miroslav Lichvar
Introduce a time stamp processor for offset/delay calculations and use
it in the clock and port modules.

Signed-off-by: Miroslav Lichvar mlich...@redhat.com
---
 clock.c  | 100 ++-
 clock.h  |   5 +-
 makefile |   2 +-
 port.c   |  39 ---
 tsproc.c | 163 +++
 tsproc.h |  97 +
 6 files changed, 320 insertions(+), 86 deletions(-)
 create mode 100644 tsproc.c
 create mode 100644 tsproc.h

diff --git a/clock.c b/clock.c
index f5349b9..9735fbd 100644
--- a/clock.c
+++ b/clock.c
@@ -38,6 +38,7 @@
 #include stats.h
 #include print.h
 #include tlv.h
+#include tsproc.h
 #include uds.h
 #include util.h
 
@@ -102,12 +103,11 @@ struct clock {
enum servo_state servo_state;
tmv_t master_offset;
tmv_t path_delay;
-   struct filter *delay_filter;
+   tmv_t ingress_ts;
+   struct tsproc *tsproc;
struct freq_estimator fest;
struct time_status_np status;
double nrr;
-   tmv_t t1;
-   tmv_t t2;
struct clock_description desc;
struct clock_stats stats;
int stats_interval;
@@ -271,7 +271,7 @@ void clock_destroy(struct clock *c)
phc_close(c-clkid);
}
servo_destroy(c-servo);
-   filter_destroy(c-delay_filter);
+   tsproc_destroy(c-tsproc);
stats_destroy(c-stats.offset);
stats_destroy(c-stats.freq);
stats_destroy(c-stats.delay);
@@ -413,7 +413,7 @@ static int clock_management_fill_response(struct clock *c, 
struct port *p,
case TLV_TIME_STATUS_NP:
tsn = (struct time_status_np *) tlv-data;
tsn-master_offset = c-master_offset;
-   tsn-ingress_time = tmv_to_nanoseconds(c-t2);
+   tsn-ingress_time = tmv_to_nanoseconds(c-ingress_ts);
tsn-cumulativeScaledRateOffset =
(Integer32) (c-status.cumulativeScaledRateOffset +
  c-nrr * POW2_41 - POW2_41);
@@ -543,7 +543,8 @@ static void clock_stats_update(struct clock_stats *s,
stats_reset(s-delay);
 }
 
-static enum servo_state clock_no_adjust(struct clock *c)
+static enum servo_state clock_no_adjust(struct clock *c, tmv_t ingress,
+   tmv_t origin)
 {
double fui;
double ratio, freq;
@@ -561,21 +562,21 @@ static enum servo_state clock_no_adjust(struct clock *c)
 * error caused by our imperfect path delay measurement.
 */
if (!f-ingress1) {
-   f-ingress1 = c-t2;
-   f-origin1 = c-t1;
+   f-ingress1 = ingress;
+   f-origin1 = origin;
return state;
}
f-count++;
if (f-count  f-max_count) {
return state;
}
-   if (tmv_eq(c-t2, f-ingress1)) {
+   if (tmv_eq(ingress, f-ingress1)) {
pr_warning(bad timestamps in rate ratio calculation);
return state;
}
 
-   ratio = tmv_dbl(tmv_sub(c-t1, f-origin1)) /
-   tmv_dbl(tmv_sub(c-t2, f-ingress1));
+   ratio = tmv_dbl(tmv_sub(origin, f-origin1)) /
+   tmv_dbl(tmv_sub(ingress, f-ingress1));
freq = (1.0 - ratio) * 1e9;
 
if (c-stats.max_count  1) {
@@ -597,8 +598,8 @@ static enum servo_state clock_no_adjust(struct clock *c)
pr_debug(master/local  %.9f, ratio);
pr_debug(diff %+.9f, ratio - (fui + c-nrr - 1.0));
 
-   f-ingress1 = c-t2;
-   f-origin1 = c-t1;
+   f-ingress1 = ingress;
+   f-origin1 = origin;
f-count = 0;
 
return state;
@@ -851,10 +852,9 @@ struct clock *clock_create(int phc_index, struct 
interfaces_head *ifaces,
}
c-servo_state = SERVO_UNLOCKED;
c-servo_type = servo;
-   c-delay_filter = filter_create(dds-delay_filter,
-   dds-delay_filter_length);
-   if (!c-delay_filter) {
-   pr_err(Failed to create delay filter);
+   c-tsproc = tsproc_create(dds-delay_filter, dds-delay_filter_length);
+   if (!c-tsproc) {
+   pr_err(Failed to create time stamp processor);
return NULL;
}
c-nrr = 1.0;
@@ -1278,52 +1278,27 @@ int clock_poll(struct clock *c)
 
 void clock_path_delay(struct clock *c, tmv_t req, tmv_t rx)
 {
-   tmv_t pd, t1, t2, t3, t4;
-   double rr;
+   tsproc_up_ts(c-tsproc, req, rx);
 
-   if (tmv_is_zero(c-t1))
+   if (tsproc_update_delay(c-tsproc, c-path_delay))
return;
 
-   t1 = c-t1;
-   t2 = c-t2;
-   t3 = req;
-   t4 = rx;
-   rr = clock_rate_ratio(c);
-
-   /*
-* c-path_delay = (t2 - t3) * rr + (t4 - t1);
-* c-path_delay /= 2.0;
-*/
-
-   pd = tmv_sub(t2, t3);
-   if (rr != 1.0)
-   pd = dbl_tmv(tmv_dbl(pd) * rr);
-   pd =