We'd like to monitor the service quality of unicast PTPv2 in the DCs.
This change adds counters for various timeouts and events
happening in the client code, and exposes them as a new
management TLV.

Signed-off-by: Alexander Bulimov <abuli...@fb.com>
---
 ddt.h          | 13 ++++++++++++
 pmc.c          | 27 +++++++++++++++++++++++++
 pmc_common.c   |  1 +
 port.c         | 23 +++++++++++++++++++++
 port_private.h |  1 +
 tlv.c          | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tlv.h          |  6 ++++++
 7 files changed, 126 insertions(+)

diff --git a/ddt.h b/ddt.h
index 56449a3..ef30f73 100644
--- a/ddt.h
+++ b/ddt.h
@@ -107,4 +107,17 @@ struct PortStats {
        uint64_t txMsgType[MAX_MESSAGE_TYPES];
 };
 
+struct PortServiceStats {
+       uint64_t announce_timeout;
+       uint64_t sync_timeout;
+       uint64_t delay_timeout;
+       uint64_t unicast_service_timeout;
+       uint64_t unicast_request_timeout;
+       uint64_t master_announce_timeout;
+       uint64_t master_sync_timeout;
+       uint64_t qualification_timeout;
+       uint64_t sync_mismatch;
+       uint64_t followup_mismatch;
+};
+
 #endif
diff --git a/pmc.c b/pmc.c
index a1ee787..2e5e93e 100644
--- a/pmc.c
+++ b/pmc.c
@@ -148,6 +148,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
        struct management_tlv *mgt;
        struct time_status_np *tsn;
        struct port_stats_np *pcp;
+       struct port_service_stats_np *pssp;
        struct tlv_extra *extra;
        struct port_ds_np *pnp;
        struct defaultDS *dds;
@@ -495,6 +496,32 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
                        pcp->stats.txMsgType[SIGNALING],
                        pcp->stats.txMsgType[MANAGEMENT]);
                break;
+       case MID_PORT_SERVICE_STATS_NP:
+               pssp = (struct port_service_stats_np *) mgt->data;
+               fprintf(fp, "PORT_SERVICE_STATS_NP "
+               IFMT "portIdentity              %s"
+               IFMT "announce_timeout          %" PRIu64
+               IFMT "sync_timeout              %" PRIu64
+               IFMT "delay_timeout             %" PRIu64
+               IFMT "unicast_service_timeout   %" PRIu64
+               IFMT "unicast_request_timeout   %" PRIu64
+               IFMT "master_announce_timeout   %" PRIu64
+               IFMT "master_sync_timeout       %" PRIu64
+               IFMT "qualification_timeout     %" PRIu64
+               IFMT "sync_mismatch             %" PRIu64
+               IFMT "followup_mismatch         %" PRIu64,
+               pid2str(&pssp->portIdentity),
+               pssp->stats.announce_timeout,
+               pssp->stats.sync_timeout,
+               pssp->stats.delay_timeout,
+               pssp->stats.unicast_service_timeout,
+               pssp->stats.unicast_request_timeout,
+               pssp->stats.master_announce_timeout,
+               pssp->stats.master_sync_timeout,
+               pssp->stats.qualification_timeout,
+               pssp->stats.sync_mismatch,
+               pssp->stats.followup_mismatch);
+               break;
        case MID_LOG_ANNOUNCE_INTERVAL:
                mtd = (struct management_tlv_datum *) mgt->data;
                fprintf(fp, "LOG_ANNOUNCE_INTERVAL "
diff --git a/pmc_common.c b/pmc_common.c
index 7a1dbb4..b691bbb 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -131,6 +131,7 @@ struct management_id idtab[] = {
        { "LOG_MIN_PDELAY_REQ_INTERVAL", MID_LOG_MIN_PDELAY_REQ_INTERVAL, 
do_get_action },
        { "PORT_DATA_SET_NP", MID_PORT_DATA_SET_NP, do_set_action },
        { "PORT_STATS_NP", MID_PORT_STATS_NP, do_get_action },
+       { "PORT_SERVICE_STATS_NP", MID_PORT_SERVICE_STATS_NP, do_get_action },
        { "PORT_PROPERTIES_NP", MID_PORT_PROPERTIES_NP, do_get_action },
 };
 
diff --git a/port.c b/port.c
index 7e51e77..c1d0ac8 100644
--- a/port.c
+++ b/port.c
@@ -798,6 +798,7 @@ static int port_management_fill_response(struct port 
*target,
        struct clock_description *desc;
        struct port_properties_np *ppn;
        struct port_stats_np *psn;
+       struct port_service_stats_np *pssn;
        struct management_tlv *tlv;
        struct port_ds_np *pdsnp;
        struct tlv_extra *extra;
@@ -966,6 +967,12 @@ static int port_management_fill_response(struct port 
*target,
                psn->stats = target->stats;
                datalen = sizeof(*psn);
                break;
+       case MID_PORT_SERVICE_STATS_NP:
+               pssn = (struct port_service_stats_np *)tlv->data;
+               pssn->portIdentity = target->portIdentity;
+               pssn->stats = target->service_stats;
+               datalen = sizeof(*pssn);
+               break;
        default:
                /* The caller should *not* respond to this message. */
                tlv_extra_recycle(extra);
@@ -1285,6 +1292,7 @@ static void port_syfufsm(struct port *p, enum syfu_event 
event,
                        msg_put(p->last_syncfup);
                        msg_get(m);
                        p->last_syncfup = m;
+                       p->service_stats.sync_mismatch++;
                        break;
                case SYNC_MATCH:
                        break;
@@ -1294,6 +1302,7 @@ static void port_syfufsm(struct port *p, enum syfu_event 
event,
                        msg_get(m);
                        p->last_syncfup = m;
                        p->syfu = SF_HAVE_FUP;
+                       p->service_stats.followup_mismatch++;
                        break;
                case FUP_MATCH:
                        syn = p->last_syncfup;
@@ -1316,6 +1325,7 @@ static void port_syfufsm(struct port *p, enum syfu_event 
event,
                        msg_get(m);
                        p->last_syncfup = m;
                        p->syfu = SF_HAVE_SYNC;
+                       p->service_stats.sync_mismatch++;
                        break;
                case SYNC_MATCH:
                        fup = p->last_syncfup;
@@ -1332,6 +1342,7 @@ static void port_syfufsm(struct port *p, enum syfu_event 
event,
                        msg_put(p->last_syncfup);
                        msg_get(m);
                        p->last_syncfup = m;
+                       p->service_stats.followup_mismatch++;
                        break;
                case FUP_MATCH:
                        break;
@@ -2651,6 +2662,12 @@ static enum fsm_event bc_event(struct port *p, int 
fd_index)
                        fc_clear(p->best);
                }
 
+               if (fd_index == FD_SYNC_RX_TIMER) {
+                       p->service_stats.sync_timeout++;
+               } else {
+                       p->service_stats.announce_timeout++;
+               }
+
                /*
                 * Clear out the event returned by poll(). It is only cleared
                 * in port_*_transition(). But, when BMCA == 'noop', there is no
@@ -2681,6 +2698,7 @@ static enum fsm_event bc_event(struct port *p, int 
fd_index)
                pr_debug("%s: delay timeout", p->log_name);
                port_set_delay_tmo(p);
                delay_req_prune(p);
+               p->service_stats.delay_timeout++;
                if (port_delay_request(p)) {
                        return EV_FAULT_DETECTED;
                }
@@ -2697,11 +2715,13 @@ static enum fsm_event bc_event(struct port *p, int 
fd_index)
 
        case FD_QUALIFICATION_TIMER:
                pr_debug("%s: qualification timeout", p->log_name);
+               p->service_stats.qualification_timeout++;
                return EV_QUALIFICATION_TIMEOUT_EXPIRES;
 
        case FD_MANNO_TIMER:
                pr_debug("%s: master tx announce timeout", p->log_name);
                port_set_manno_tmo(p);
+               p->service_stats.master_announce_timeout++;
                clock_update_leap_status(p->clock);
                return port_tx_announce(p, NULL, p->seqnum.announce++) ?
                        EV_FAULT_DETECTED : EV_NONE;
@@ -2709,15 +2729,18 @@ static enum fsm_event bc_event(struct port *p, int 
fd_index)
        case FD_SYNC_TX_TIMER:
                pr_debug("%s: master sync timeout", p->log_name);
                port_set_sync_tx_tmo(p);
+               p->service_stats.master_sync_timeout++;
                return port_tx_sync(p, NULL, p->seqnum.sync++) ?
                        EV_FAULT_DETECTED : EV_NONE;
 
        case FD_UNICAST_SRV_TIMER:
                pr_debug("%s: unicast service timeout", p->log_name);
+               p->service_stats.unicast_service_timeout++;
                return unicast_service_timer(p) ? EV_FAULT_DETECTED : EV_NONE;
 
        case FD_UNICAST_REQ_TIMER:
                pr_debug("%s: unicast request timeout", p->log_name);
+               p->service_stats.unicast_request_timeout++;
                return unicast_client_timer(p) ? EV_FAULT_DETECTED : EV_NONE;
 
        case FD_RTNL:
diff --git a/port_private.h b/port_private.h
index 19eb944..d27dceb 100644
--- a/port_private.h
+++ b/port_private.h
@@ -146,6 +146,7 @@ struct port {
        UInteger8           delay_response_counter;
        UInteger8           delay_response_timeout;
        struct PortStats    stats;
+       struct PortServiceStats    service_stats;
        /* foreignMasterDS */
        LIST_HEAD(fm, foreign_clock) foreign_masters;
        /* TC book keeping */
diff --git a/tlv.c b/tlv.c
index cc8d507..df516be 100644
--- a/tlv.c
+++ b/tlv.c
@@ -120,6 +120,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t 
data_len,
        struct timePropertiesDS *tp;
        struct time_status_np *tsn;
        struct port_stats_np *psn;
+       struct port_service_stats_np *pssn;
        int extra_len = 0, i, len;
        struct port_ds_np *pdsnp;
        struct currentDS *cds;
@@ -331,6 +332,34 @@ static int mgt_post_recv(struct management_tlv *m, 
uint16_t data_len,
                }
                extra_len = sizeof(struct port_stats_np);
                break;
+       case MID_PORT_SERVICE_STATS_NP:
+               if (data_len < sizeof(struct port_service_stats_np))
+                       goto bad_length;
+               pssn = (struct port_service_stats_np *)m->data;
+               pssn->portIdentity.portNumber =
+                       htons(pssn->portIdentity.portNumber);
+               pssn->stats.announce_timeout =
+                       __le64_to_cpu(pssn->stats.announce_timeout);
+               pssn->stats.sync_timeout =
+                       __le64_to_cpu(pssn->stats.sync_timeout);
+               pssn->stats.delay_timeout =
+                       __le64_to_cpu(pssn->stats.delay_timeout);
+               pssn->stats.unicast_service_timeout =
+                       __le64_to_cpu(pssn->stats.unicast_service_timeout);
+               pssn->stats.unicast_request_timeout =
+                       __le64_to_cpu(pssn->stats.unicast_request_timeout);
+               pssn->stats.master_announce_timeout =
+                       __le64_to_cpu(pssn->stats.master_announce_timeout);
+               pssn->stats.master_sync_timeout =
+                       __le64_to_cpu(pssn->stats.master_sync_timeout);
+               pssn->stats.qualification_timeout =
+                       __le64_to_cpu(pssn->stats.qualification_timeout);
+               pssn->stats.sync_mismatch =
+                       __le64_to_cpu(pssn->stats.sync_mismatch);
+               pssn->stats.followup_mismatch =
+                       __le64_to_cpu(pssn->stats.followup_mismatch);
+               extra_len = sizeof(struct port_service_stats_np);
+               break;
        case MID_SAVE_IN_NON_VOLATILE_STORAGE:
        case MID_RESET_NON_VOLATILE_STORAGE:
        case MID_INITIALIZE:
@@ -361,6 +390,7 @@ static void mgt_pre_send(struct management_tlv *m, struct 
tlv_extra *extra)
        struct timePropertiesDS *tp;
        struct time_status_np *tsn;
        struct port_stats_np *psn;
+       struct port_service_stats_np *pssn;
        struct port_ds_np *pdsnp;
        struct defaultDS *dds;
        struct currentDS *cds;
@@ -448,6 +478,31 @@ static void mgt_pre_send(struct management_tlv *m, struct 
tlv_extra *extra)
                        psn->stats.txMsgType[i] = 
__cpu_to_le64(psn->stats.txMsgType[i]);
                }
                break;
+       case MID_PORT_SERVICE_STATS_NP:
+               pssn = (struct port_service_stats_np *)m->data;
+               pssn->portIdentity.portNumber =
+                       htons(pssn->portIdentity.portNumber);
+               pssn->stats.announce_timeout =
+                       __cpu_to_le64(pssn->stats.announce_timeout);
+               pssn->stats.sync_timeout =
+                       __cpu_to_le64(pssn->stats.sync_timeout);
+               pssn->stats.delay_timeout =
+                       __cpu_to_le64(pssn->stats.delay_timeout);
+               pssn->stats.unicast_service_timeout =
+                       __cpu_to_le64(pssn->stats.unicast_service_timeout);
+               pssn->stats.unicast_request_timeout =
+                       __cpu_to_le64(pssn->stats.unicast_request_timeout);
+               pssn->stats.master_announce_timeout =
+                       __cpu_to_le64(pssn->stats.master_announce_timeout);
+               pssn->stats.master_sync_timeout =
+                       __cpu_to_le64(pssn->stats.master_sync_timeout);
+               pssn->stats.qualification_timeout =
+                       __cpu_to_le64(pssn->stats.qualification_timeout);
+               pssn->stats.sync_mismatch =
+                       __cpu_to_le64(pssn->stats.sync_mismatch);
+               pssn->stats.followup_mismatch =
+                       __cpu_to_le64(pssn->stats.followup_mismatch);
+               break;
        }
 }
 
diff --git a/tlv.h b/tlv.h
index 97615fd..408c22c 100644
--- a/tlv.h
+++ b/tlv.h
@@ -125,6 +125,7 @@ enum management_action {
 #define MID_PORT_DATA_SET_NP                           0xC002
 #define MID_PORT_PROPERTIES_NP                         0xC004
 #define MID_PORT_STATS_NP                              0xC005
+#define MID_PORT_SERVICE_STATS_NP                      0xC007
 
 /* Management error ID values */
 #define MID_RESPONSE_TOO_BIG                           0x0001
@@ -349,6 +350,11 @@ struct port_stats_np {
        struct PortStats stats;
 } PACKED;
 
+struct port_service_stats_np {
+       struct PortIdentity portIdentity;
+       struct PortServiceStats stats;
+} PACKED;
+
 #define PROFILE_ID_LEN 6
 
 struct mgmt_clock_description {
-- 
2.30.2



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to