In a ptp unaware network (like the telecom profile for frequency sync
G.8265.1), both the RTD and the PDV can be substantially higher than
in a ptp aware network. To achieve more accurate measurements, the
rate may need to be configured higher to get more data and increase
the chance of lucky packets.
In a combination of a high configured rate of delay_req and high
RTD/PDV in network, the risk that the response from the previously
sent delay_req have not been received before a new delay_req is sent
also become high. In that case, the need of storing more than the
latest sent delay_req arise.

This patch adds a queue for sent delay requests so several request can
be ongoing in parallel. When a delay response is received, a matching
request will be searched for in the queue and after processed removed
from the queue.
The stored delay_req will be removed if older than 5 seconds or sequence
id older than a just processed delay_resp

Signed-off-by: Anders Selhammer <anders.selham...@est.tech>
---
 msg.c  |  2 ++
 port.c | 63 ++++++++++++++++++++++++++++++++++++++++++---------------------
 2 files changed, 44 insertions(+), 21 deletions(-)

diff --git a/msg.c b/msg.c
index a36d4d0..4589374 100644
--- a/msg.c
+++ b/msg.c
@@ -368,6 +368,7 @@ int msg_post_recv(struct ptp_message *m, int cnt)
                break;
        case DELAY_RESP:
                timestamp_post_recv(m, &m->delay_resp.receiveTimestamp);
+               port_id_post_recv(&m->delay_resp.requestingPortIdentity);
                suffix = m->delay_resp.suffix;
                break;
        case PDELAY_RESP_FOLLOW_UP:
@@ -413,6 +414,7 @@ int msg_pre_send(struct ptp_message *m)
        case SYNC:
                break;
        case DELAY_REQ:
+               clock_gettime(CLOCK_MONOTONIC, &m->ts.host);
                break;
        case PDELAY_REQ:
                break;
diff --git a/port.c b/port.c
index 635676d..63780c2 100644
--- a/port.c
+++ b/port.c
@@ -86,7 +86,7 @@ struct port {
        struct foreign_clock *best;
        enum syfu_state syfu;
        struct ptp_message *last_syncfup;
-       struct ptp_message *delay_req;
+       TAILQ_HEAD(delay_req, ptp_message) delay_req;
        struct ptp_message *peer_delay_req;
        struct ptp_message *peer_delay_resp;
        struct ptp_message *peer_delay_fup;
@@ -146,6 +146,7 @@ struct port {
 static int port_capable(struct port *p);
 static int port_is_ieee8021as(struct port *p);
 static void port_nrate_initialize(struct port *p);
+static void flush_delay_req(struct port *p);
 
 static int announce_compare(struct ptp_message *m1, struct ptp_message *m2)
 {
@@ -1167,10 +1168,7 @@ static void port_synchronize(struct port *p,
                break;
        case SERVO_JUMP:
                port_dispatch(p, EV_SYNCHRONIZATION_FAULT, 0);
-               if (p->delay_req) {
-                       msg_put(p->delay_req);
-                       p->delay_req = NULL;
-               }
+               flush_delay_req(p);
                if (p->peer_delay_req) {
                        msg_put(p->peer_delay_req);
                        p->peer_delay_req = NULL;
@@ -1317,9 +1315,17 @@ out:
        return -1;
 }
 
+static int port_outdated_delay_req(struct timespec host)
+{
+       struct timespec now;
+       clock_gettime(CLOCK_MONOTONIC, &now);
+       now.tv_sec -= 5;
+       return timespec_to_tmv(now).ns > timespec_to_tmv(host).ns ? 1 : 0;
+}
+
 static int port_delay_request(struct port *p)
 {
-       struct ptp_message *msg;
+       struct ptp_message *msg, *tmp;
 
        /* Time to send a new request, forget current pdelay resp and fup */
        if (p->peer_delay_resp) {
@@ -1367,10 +1373,16 @@ static int port_delay_request(struct port *p)
                goto out;
        }
 
-       if (p->delay_req)
-               msg_put(p->delay_req);
+       TAILQ_INSERT_HEAD(&p->delay_req, msg, list);
+
+       while ((tmp = TAILQ_LAST(&p->delay_req, delay_req)) != NULL) {
+               if (!port_outdated_delay_req(tmp->ts.host)) {
+                       break;
+               }
+               TAILQ_REMOVE(&p->delay_req, tmp, list);
+               msg_put(tmp);
+       }
 
-       p->delay_req = msg;
        return 0;
 out:
        msg_put(msg);
@@ -1543,9 +1555,10 @@ static void flush_last_sync(struct port *p)
 
 static void flush_delay_req(struct port *p)
 {
-       if (p->delay_req) {
-               msg_put(p->delay_req);
-               p->delay_req = NULL;
+       struct ptp_message *m;
+       while ((m = TAILQ_FIRST(&p->delay_req)) != NULL) {
+               TAILQ_REMOVE(&p->delay_req, m, list);
+               msg_put(m);
        }
 }
 
@@ -1816,37 +1829,45 @@ out:
 
 static void process_delay_resp(struct port *p, struct ptp_message *m)
 {
-       struct delay_req_msg *req;
        struct delay_resp_msg *rsp = &m->delay_resp;
+       struct ptp_message *req, *tmp;
        struct PortIdentity master;
        tmv_t c3, t3, t4, t4c;
 
-       if (!p->delay_req)
-               return;
-
        master = clock_parent_identity(p->clock);
-       req = &p->delay_req->delay_req;
 
        if (p->state != PS_UNCALIBRATED && p->state != PS_SLAVE) {
                return;
        }
-       if (!pid_eq(&rsp->requestingPortIdentity, 
&req->hdr.sourcePortIdentity)) {
+       if (!pid_eq(&rsp->requestingPortIdentity, &p->portIdentity)) {
                return;
        }
-       if (rsp->hdr.sequenceId != ntohs(req->hdr.sequenceId)) {
+       if (!pid_eq(&master, &m->header.sourcePortIdentity)) {
                return;
        }
-       if (!pid_eq(&master, &m->header.sourcePortIdentity)) {
+       TAILQ_FOREACH(req, &p->delay_req, list) {
+               if (rsp->hdr.sequenceId == 
ntohs(req->delay_req.hdr.sequenceId)) {
+                       break;
+               }
+       }
+       if (!req) {
                return;
        }
 
        c3 = correction_to_tmv(m->header.correction);
-       t3 = p->delay_req->hwts.ts;
+       t3 = req->hwts.ts;
        t4 = timestamp_to_tmv(m->ts.pdu);
        t4c = tmv_sub(t4, c3);
 
        clock_path_delay(p->clock, t3, t4c);
 
+       while ((tmp = TAILQ_NEXT(req, list)) != NULL) {
+               TAILQ_REMOVE(&p->delay_req, tmp, list);
+               msg_put(tmp);
+       }
+       TAILQ_REMOVE(&p->delay_req, req, list);
+       msg_put(req);
+
        if (p->logMinDelayReqInterval == rsp->hdr.logMessageInterval) {
                return;
        }
-- 
1.8.3.1


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to