The PORTS_STATS_2_NP carries all the PORTS_STATS_NP RX/TX counters
adding room for extra counters (up to 16 counters for RX and TX).
Not all counters are filled yet.
The PORTS_STATS_2_NP TLV has the following definition:
struct port_stats_2_np {
struct PortIdentity portIdentity; // As PORT_STATS_NP
struct PortStats stats; // As PORT_STATS_NP
struct PortStats extraStats; // Extra room
} PACKED;
The proposed implementation add the following counters:
Offset Dir Description
0 RX Bad Message
1 RX Bad Protocol
2 RX Fail on Receive
3 RX Missing Timestamp
4 RX Announce from Foreign Masters (used by 1588-2019 Annex J)
5 RX Announce from current Master
2 TX Fail on Transmit
3 TX Missing Timestamp
The counters are properly updated by runtime when required.
---
ddt.h | 10 +++++
pmc.c | 115 +++++++++++++++++++++++++++++++------------------
pmc_common.c | 4 ++
port.c | 21 +++++++++
port_private.h | 1 +
tlv.c | 28 ++++++++++++
tlv.h | 7 +++
7 files changed, 143 insertions(+), 43 deletions(-)
diff --git a/ddt.h b/ddt.h
index 5dc5530..cad90e7 100644
--- a/ddt.h
+++ b/ddt.h
@@ -107,6 +107,16 @@ struct PortStats {
uint64_t txMsgType[MAX_MESSAGE_TYPES];
};
+#define RX_BAD_MESSAGE 0
+#define RX_BAD_PROTOCOL 1
+#define RX_FAIL_RECEIVE 2
+#define RX_MISSING_TIMESTAMP 3
+#define RX_ANNOUNCE_FOREIGN_MASTER 4
+#define RX_ANNOUNCE_CURRENT_MASTER 5
+
+#define TX_FAIL_TRANSMIT 2
+#define TX_MISSING_TIMESTAMP 3
+
struct PortServiceStats {
uint64_t announce_timeout;
uint64_t sync_timeout;
diff --git a/pmc.c b/pmc.c
index bc87058..24a9183 100644
--- a/pmc.c
+++ b/pmc.c
@@ -155,6 +155,53 @@ static void pmc_show_signaling(struct ptp_message *msg,
FILE *fp)
fflush(fp);
}
+static inline void pmc_show_stats(struct PortIdentity pid, struct PortStats
stats, FILE *fp)
+{
+ fprintf(fp,
+ IFMT "portIdentity %s"
+ IFMT "rx_Sync %" PRIu64
+ IFMT "rx_Delay_Req %" PRIu64
+ IFMT "rx_Pdelay_Req %" PRIu64
+ IFMT "rx_Pdelay_Resp %" PRIu64
+ IFMT "rx_Follow_Up %" PRIu64
+ IFMT "rx_Delay_Resp %" PRIu64
+ IFMT "rx_Pdelay_Resp_Follow_Up %" PRIu64
+ IFMT "rx_Announce %" PRIu64
+ IFMT "rx_Signaling %" PRIu64
+ IFMT "rx_Management %" PRIu64
+ IFMT "tx_Sync %" PRIu64
+ IFMT "tx_Delay_Req %" PRIu64
+ IFMT "tx_Pdelay_Req %" PRIu64
+ IFMT "tx_Pdelay_Resp %" PRIu64
+ IFMT "tx_Follow_Up %" PRIu64
+ IFMT "tx_Delay_Resp %" PRIu64
+ IFMT "tx_Pdelay_Resp_Follow_Up %" PRIu64
+ IFMT "tx_Announce %" PRIu64
+ IFMT "tx_Signaling %" PRIu64
+ IFMT "tx_Management %" PRIu64,
+ pid2str(&pid),
+ stats.rxMsgType[SYNC],
+ stats.rxMsgType[DELAY_REQ],
+ stats.rxMsgType[PDELAY_REQ],
+ stats.rxMsgType[PDELAY_RESP],
+ stats.rxMsgType[FOLLOW_UP],
+ stats.rxMsgType[DELAY_RESP],
+ stats.rxMsgType[PDELAY_RESP_FOLLOW_UP],
+ stats.rxMsgType[ANNOUNCE],
+ stats.rxMsgType[SIGNALING],
+ stats.rxMsgType[MANAGEMENT],
+ stats.txMsgType[SYNC],
+ stats.txMsgType[DELAY_REQ],
+ stats.txMsgType[PDELAY_REQ],
+ stats.txMsgType[PDELAY_RESP],
+ stats.txMsgType[FOLLOW_UP],
+ stats.txMsgType[DELAY_RESP],
+ stats.txMsgType[PDELAY_RESP_FOLLOW_UP],
+ stats.txMsgType[ANNOUNCE],
+ stats.txMsgType[SIGNALING],
+ stats.txMsgType[MANAGEMENT]);
+}
+
static void pmc_show(struct ptp_message *msg, FILE *fp)
{
struct alternate_time_offset_properties *atop;
@@ -168,6 +215,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
struct unicast_master_entry *ume;
struct subscribe_events_np *sen;
struct port_properties_np *ppn;
+ struct port_stats_2_np *ps2n;
struct port_hwclock_np *phn;
struct timePropertiesDS *tp;
struct management_tlv *mgt;
@@ -509,49 +557,8 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
break;
case MID_PORT_STATS_NP:
pcp = (struct port_stats_np *) mgt->data;
- fprintf(fp, "PORT_STATS_NP "
- IFMT "portIdentity %s"
- IFMT "rx_Sync %" PRIu64
- IFMT "rx_Delay_Req %" PRIu64
- IFMT "rx_Pdelay_Req %" PRIu64
- IFMT "rx_Pdelay_Resp %" PRIu64
- IFMT "rx_Follow_Up %" PRIu64
- IFMT "rx_Delay_Resp %" PRIu64
- IFMT "rx_Pdelay_Resp_Follow_Up %" PRIu64
- IFMT "rx_Announce %" PRIu64
- IFMT "rx_Signaling %" PRIu64
- IFMT "rx_Management %" PRIu64
- IFMT "tx_Sync %" PRIu64
- IFMT "tx_Delay_Req %" PRIu64
- IFMT "tx_Pdelay_Req %" PRIu64
- IFMT "tx_Pdelay_Resp %" PRIu64
- IFMT "tx_Follow_Up %" PRIu64
- IFMT "tx_Delay_Resp %" PRIu64
- IFMT "tx_Pdelay_Resp_Follow_Up %" PRIu64
- IFMT "tx_Announce %" PRIu64
- IFMT "tx_Signaling %" PRIu64
- IFMT "tx_Management %" PRIu64,
- pid2str(&pcp->portIdentity),
- pcp->stats.rxMsgType[SYNC],
- pcp->stats.rxMsgType[DELAY_REQ],
- pcp->stats.rxMsgType[PDELAY_REQ],
- pcp->stats.rxMsgType[PDELAY_RESP],
- pcp->stats.rxMsgType[FOLLOW_UP],
- pcp->stats.rxMsgType[DELAY_RESP],
- pcp->stats.rxMsgType[PDELAY_RESP_FOLLOW_UP],
- pcp->stats.rxMsgType[ANNOUNCE],
- pcp->stats.rxMsgType[SIGNALING],
- pcp->stats.rxMsgType[MANAGEMENT],
- pcp->stats.txMsgType[SYNC],
- pcp->stats.txMsgType[DELAY_REQ],
- pcp->stats.txMsgType[PDELAY_REQ],
- pcp->stats.txMsgType[PDELAY_RESP],
- pcp->stats.txMsgType[FOLLOW_UP],
- pcp->stats.txMsgType[DELAY_RESP],
- pcp->stats.txMsgType[PDELAY_RESP_FOLLOW_UP],
- pcp->stats.txMsgType[ANNOUNCE],
- pcp->stats.txMsgType[SIGNALING],
- pcp->stats.txMsgType[MANAGEMENT]);
+ fprintf(fp, "PORT_STATS_NP ");
+ pmc_show_stats(pcp->portIdentity, pcp->stats, fp);
break;
case MID_PORT_SERVICE_STATS_NP:
pssp = (struct port_service_stats_np *) mgt->data;
@@ -651,6 +658,28 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
fprintf(fp, "LOG_MIN_PDELAY_REQ_INTERVAL "
IFMT "logMinPdelayReqInterval %hhd", mtd->val);
break;
+ case MID_PORT_STATS_2_NP:
+ ps2n = (struct port_stats_2_np *) mgt->data;
+ fprintf(fp, "PORT_STATS_2_NP ");
+ pmc_show_stats(ps2n->portIdentity, ps2n->stats, fp);
+ fprintf(fp,
+ IFMT "rx_Bad_Message %" PRIu64
+ IFMT "rx_Bad_Protocol %" PRIu64
+ IFMT "rx_Fail %" PRIu64
+ IFMT "rx_Missing_Timestamp %" PRIu64
+ IFMT "rx_Announce_For_Master %" PRIu64
+ IFMT "rx_Announce_Cur_Master %" PRIu64
+ IFMT "tx_Fail %" PRIu64
+ IFMT "tx_Missing_Timestamp %" PRIu64,
+ ps2n->extraStats.rxMsgType[RX_BAD_MESSAGE],
+ ps2n->extraStats.rxMsgType[RX_BAD_PROTOCOL],
+ ps2n->extraStats.rxMsgType[RX_FAIL_RECEIVE],
+ ps2n->extraStats.rxMsgType[RX_MISSING_TIMESTAMP],
+ ps2n->extraStats.rxMsgType[RX_ANNOUNCE_FOREIGN_MASTER],
+ ps2n->extraStats.rxMsgType[RX_ANNOUNCE_CURRENT_MASTER],
+ ps2n->extraStats.txMsgType[TX_FAIL_TRANSMIT],
+ ps2n->extraStats.txMsgType[TX_MISSING_TIMESTAMP]);
+ break;
}
out:
fprintf(fp, "\n");
diff --git a/pmc_common.c b/pmc_common.c
index 9e251c4..77b2cd2 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -156,6 +156,7 @@ struct management_id idtab[] = {
{ "UNICAST_MASTER_TABLE_NP", MID_UNICAST_MASTER_TABLE_NP, do_get_action
},
{ "PORT_HWCLOCK_NP", MID_PORT_HWCLOCK_NP, do_get_action },
{ "POWER_PROFILE_SETTINGS_NP", MID_POWER_PROFILE_SETTINGS_NP,
do_set_action },
+ { "PORT_STATS_2_NP", MID_PORT_STATS_2_NP, do_get_action },
};
static void do_get_action(struct pmc *pmc, int action, int index, char *str)
@@ -675,6 +676,9 @@ static int pmc_tlv_datalen(struct pmc *pmc, int id)
case MID_LOG_MIN_PDELAY_REQ_INTERVAL:
len += sizeof(struct management_tlv_datum);
break;
+ case MID_PORT_STATS_2_NP:
+ len += sizeof(struct port_stats_2_np);
+ break;
}
return len + len % 2;
}
diff --git a/port.c b/port.c
index 5803cd3..5854bef 100644
--- a/port.c
+++ b/port.c
@@ -381,6 +381,8 @@ static int add_foreign_master(struct port *p, struct
ptp_message *m)
struct ptp_message *tmp;
int broke_threshold = 0, diff = 0;
+ p->extra_stats.rxMsgType[RX_ANNOUNCE_FOREIGN_MASTER]++;
+
LIST_FOREACH(fc, &p->foreign_masters, list) {
if (msg_source_equal(m, fc)) {
break;
@@ -886,6 +888,7 @@ static int port_management_fill_response(struct port
*target,
struct unicast_master_entry *ume;
struct clock_description *desc;
struct port_properties_np *ppn;
+ struct port_stats_2_np *ps2n;
struct port_hwclock_np *phn;
struct management_tlv *tlv;
struct port_stats_np *psn;
@@ -1129,6 +1132,13 @@ static int port_management_fill_response(struct port
*target,
memcpy(pwr, &target->pwr, sizeof(*pwr));
datalen = sizeof(*pwr);
break;
+ case MID_PORT_STATS_2_NP:
+ ps2n = (struct port_stats_2_np *)tlv->data;
+ ps2n->portIdentity = target->portIdentity;
+ ps2n->stats = target->stats;
+ ps2n->extraStats = target->extra_stats;
+ datalen = sizeof(*ps2n);
+ break;
default:
/* The caller should *not* respond to this message. */
tlv_extra_recycle(extra);
@@ -1558,6 +1568,7 @@ static int port_pdelay_request(struct port *p)
goto out;
}
if (msg_sots_missing(msg)) {
+ p->extra_stats.txMsgType[TX_MISSING_TIMESTAMP]++;
pr_err("missing timestamp on transmitted peer delay request");
goto out;
}
@@ -1620,6 +1631,7 @@ int port_delay_request(struct port *p)
goto out;
}
if (msg_sots_missing(msg)) {
+ p->extra_stats.txMsgType[TX_MISSING_TIMESTAMP]++;
pr_err("missing timestamp on transmitted delay request");
goto out;
}
@@ -1759,6 +1771,7 @@ int port_tx_sync(struct port *p, struct address *dst,
uint16_t sequence_id)
if (p->timestamping == TS_ONESTEP || p->timestamping == TS_P2P1STEP) {
goto out;
} else if (msg_sots_missing(msg)) {
+ p->extra_stats.txMsgType[TX_MISSING_TIMESTAMP]++;
pr_err("missing timestamp on transmitted sync");
err = -1;
goto out;
@@ -2025,6 +2038,8 @@ static int update_current_master(struct port *p, struct
ptp_message *m)
if (!msg_source_equal(m, fc))
return add_foreign_master(p, m);
+ p->extra_stats.rxMsgType[RX_ANNOUNCE_CURRENT_MASTER]++;
+
if (p->state != PS_PASSIVE) {
tds.currentUtcOffset = m->announce.currentUtcOffset;
tds.flags = m->header.flagField[1];
@@ -2345,6 +2360,7 @@ int process_pdelay_req(struct port *p, struct ptp_message
*m)
if (p->timestamping == TS_P2P1STEP) {
goto out;
} else if (msg_sots_missing(rsp)) {
+ p->extra_stats.txMsgType[TX_MISSING_TIMESTAMP]++;
pr_err("missing timestamp on transmitted peer delay response");
err = -1;
goto out;
@@ -2957,6 +2973,7 @@ static enum fsm_event bc_event(struct port *p, int
fd_index)
cnt = transport_recv(p->trp, fd, msg);
if (cnt < 0) {
+ p->extra_stats.rxMsgType[RX_FAIL_RECEIVE]++;
pr_err("%s: recv message failed", p->log_name);
msg_put(msg);
return EV_FAULT_DETECTED;
@@ -2965,9 +2982,11 @@ static enum fsm_event bc_event(struct port *p, int
fd_index)
if (err) {
switch (err) {
case -EBADMSG:
+ p->extra_stats.rxMsgType[RX_BAD_MESSAGE]++;
pr_err("%s: bad message", p->log_name);
break;
case -EPROTO:
+ p->extra_stats.rxMsgType[RX_BAD_PROTOCOL]++;
pr_debug("%s: ignoring message", p->log_name);
break;
}
@@ -2983,6 +3002,7 @@ static enum fsm_event bc_event(struct port *p, int
fd_index)
!(p->timestamping == TS_P2P1STEP && msg_type(msg) == PDELAY_REQ)) {
pr_err("%s: received %s without timestamp",
p->log_name, msg_type_string(msg_type(msg)));
+ p->extra_stats.rxMsgType[RX_MISSING_TIMESTAMP]++;
msg_put(msg);
return EV_NONE;
}
@@ -3076,6 +3096,7 @@ int port_prepare_and_send(struct port *p, struct
ptp_message *msg,
cnt = transport_send(p->trp, &p->fda, event, msg);
}
if (cnt <= 0) {
+ p->extra_stats.txMsgType[TX_FAIL_TRANSMIT]++;
return -1;
}
port_stats_inc_tx(p, msg);
diff --git a/port_private.h b/port_private.h
index 3b02d2f..8825b3c 100644
--- a/port_private.h
+++ b/port_private.h
@@ -149,6 +149,7 @@ struct port {
bool iface_rate_tlv;
Integer64 portAsymmetry;
struct PortStats stats;
+ struct PortStats extra_stats;
struct PortServiceStats service_stats;
/* foreignMasterDS */
LIST_HEAD(fm, foreign_clock) foreign_masters;
diff --git a/tlv.c b/tlv.c
index 9b82bd9..e4d720f 100644
--- a/tlv.c
+++ b/tlv.c
@@ -174,6 +174,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t
data_len,
struct unicast_master_entry *ume;
struct subscribe_events_np *sen;
struct port_properties_np *ppn;
+ struct port_stats_2_np *ps2n;
struct port_hwclock_np *phn;
struct timePropertiesDS *tp;
struct time_status_np *tsn;
@@ -490,6 +491,21 @@ static int mgt_post_recv(struct management_tlv *m,
uint16_t data_len,
if (data_len != 0)
goto bad_length;
break;
+ case MID_PORT_STATS_2_NP:
+ if (data_len < sizeof(struct port_stats_2_np))
+ goto bad_length;
+ ps2n = (struct port_stats_2_np *)m->data;
+ ps2n->portIdentity.portNumber =
+ ntohs(ps2n->portIdentity.portNumber);
+ for (i = 0 ; i < MAX_MESSAGE_TYPES; i++) {
+ ps2n->stats.rxMsgType[i] =
__le64_to_cpu(ps2n->stats.rxMsgType[i]);
+ ps2n->stats.txMsgType[i] =
__le64_to_cpu(ps2n->stats.txMsgType[i]);
+ ps2n->extraStats.rxMsgType[i] =
__le64_to_cpu(ps2n->extraStats.rxMsgType[i]);
+ ps2n->extraStats.txMsgType[i] =
__le64_to_cpu(ps2n->extraStats.txMsgType[i]);
+ }
+ extra_len = sizeof(struct port_stats_2_np);
+ break;
+
}
if (extra_len) {
if (extra_len % 2)
@@ -513,6 +529,7 @@ static void mgt_pre_send(struct management_tlv *m, struct
tlv_extra *extra)
struct unicast_master_entry *ume;
struct subscribe_events_np *sen;
struct port_properties_np *ppn;
+ struct port_stats_2_np *ps2n;
struct port_hwclock_np *phn;
struct timePropertiesDS *tp;
struct time_status_np *tsn;
@@ -672,6 +689,17 @@ static void mgt_pre_send(struct management_tlv *m, struct
tlv_extra *extra)
HTONL(pwr->networkTimeInaccuracy);
HTONL(pwr->totalTimeInaccuracy);
break;
+ case MID_PORT_STATS_2_NP:
+ ps2n = (struct port_stats_2_np *)m->data;
+ ps2n->portIdentity.portNumber =
+ htons(ps2n->portIdentity.portNumber);
+ for (i = 0 ; i < MAX_MESSAGE_TYPES; i++) {
+ ps2n->stats.rxMsgType[i] =
__cpu_to_le64(ps2n->stats.rxMsgType[i]);
+ ps2n->stats.txMsgType[i] =
__cpu_to_le64(ps2n->stats.txMsgType[i]);
+ ps2n->extraStats.rxMsgType[i] =
__cpu_to_le64(ps2n->extraStats.rxMsgType[i]);
+ ps2n->extraStats.txMsgType[i] =
__cpu_to_le64(ps2n->extraStats.txMsgType[i]);
+ }
+ break;
}
}
diff --git a/tlv.h b/tlv.h
index 8b51ffd..33ecd26 100644
--- a/tlv.h
+++ b/tlv.h
@@ -129,6 +129,7 @@ enum management_action {
#define MID_UNICAST_MASTER_TABLE_NP 0xC008
#define MID_PORT_HWCLOCK_NP 0xC009
#define MID_POWER_PROFILE_SETTINGS_NP 0xC00A
+#define MID_PORT_STATS_2_NP 0xC00B
/* Management error ID values */
#define MID_RESPONSE_TOO_BIG 0x0001
@@ -426,6 +427,12 @@ struct port_stats_np {
struct PortStats stats;
} PACKED;
+struct port_stats_2_np {
+ struct PortIdentity portIdentity;
+ struct PortStats stats;
+ struct PortStats extraStats;
+} PACKED;
+
struct port_service_stats_np {
struct PortIdentity portIdentity;
struct PortServiceStats stats;
--
2.41.0
_______________________________________________
Linuxptp-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel