net: Add statistics how long packets have spent in RX path

Calculate how long on average net_pkt has spent on its way from
network device driver to the application. The data is only
calculated for UDP and TCP network packets.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2019-10-08 14:58:13 +03:00
commit 8d3b74ab61
6 changed files with 120 additions and 4 deletions

View file

@ -97,9 +97,10 @@ struct net_pkt {
struct net_if *orig_iface; /* Original network interface */
#endif
#if defined(CONFIG_NET_PKT_TIMESTAMP) || defined(CONFIG_NET_PKT_TXTIME)
#if defined(CONFIG_NET_PKT_TIMESTAMP) || defined(CONFIG_NET_PKT_TXTIME) || \
defined(CONFIG_NET_PKT_RXTIME_STATS)
union {
#if defined(CONFIG_NET_PKT_TIMESTAMP)
#if defined(CONFIG_NET_PKT_TIMESTAMP) || defined(CONFIG_NET_PKT_RXTIME_STATS)
/** Timestamp if available. */
struct net_ptp_time timestamp;
#endif /* CONFIG_NET_PKT_TIMESTAMP */

View file

@ -210,6 +210,14 @@ struct net_stats_tx_time {
net_stats_t time_count;
};
/**
* @brief Network packet receive times for calculating average RX time
*/
struct net_stats_rx_time {
u64_t sum;
net_stats_t count;
};
/**
* @brief Traffic class statistics
*/
@ -222,6 +230,7 @@ struct net_stats_tc {
} sent[NET_TC_TX_COUNT];
struct {
struct net_stats_rx_time rx_time;
net_stats_t pkts;
net_stats_t bytes;
u8_t priority;
@ -288,6 +297,11 @@ struct net_stats {
/** Network packet TX time statistics */
struct net_stats_tx_time tx_time;
#endif
#if defined(CONFIG_NET_PKT_RXTIME_STATS)
/** Network packet RX time statistics */
struct net_stats_rx_time rx_time;
#endif
};
/**

View file

@ -189,13 +189,21 @@ config NET_TC_MAPPING_SR_CLASS_B_ONLY
endchoice
config NET_TX_DEFAULT_PRIORITY
int "Default network packet priority if none have been set"
int "Default network TX packet priority if none have been set"
default 1
range 0 7
help
What is the default network packet priority if user has not specified
one. The value 0 means lowest priority and 7 is the highest.
config NET_RX_DEFAULT_PRIORITY
int "Default network RX packet priority if none have been set"
default 0
range 0 7
help
What is the default network RX packet priority if user has not set
one. The value 0 means lowest priority and 7 is the highest.
config NET_IP_ADDR_CHECK
bool "Check IP address validity before sending IP packet"
default y
@ -640,6 +648,19 @@ config NET_PKT_TXTIME
when the application wants to set the exact time when the network
packet should be sent.
config NET_PKT_RXTIME_STATS
bool "Enable network packet RX time statistics"
select NET_PKT_TIMESTAMP
select NET_STATISTICS
depends on (NET_UDP || NET_TCP)
help
Enable network packet RX time statistics support. This is used to
calculate how long on average it takes for a packet to travel from
device driver to just before it is given to application. The RX
timing information can then be seen in network interface statistics
in net-shell.
The RX statistics are only calculated for UDP and TCP packets.
config NET_PROMISCUOUS_MODE
bool "Enable promiscuous mode support [EXPERIMENTAL]"
select NET_MGMT

View file

@ -1187,7 +1187,26 @@ static struct net_pkt *pkt_alloc(struct k_mem_slab *slab, s32_t timeout)
net_pkt_set_ipv6_next_hdr(pkt, 255);
}
net_pkt_set_priority(pkt, CONFIG_NET_TX_DEFAULT_PRIORITY);
if (&tx_pkts == slab) {
net_pkt_set_priority(pkt, CONFIG_NET_TX_DEFAULT_PRIORITY);
} else if (&rx_pkts == slab) {
net_pkt_set_priority(pkt, CONFIG_NET_RX_DEFAULT_PRIORITY);
}
if (IS_ENABLED(CONFIG_NET_PKT_RXTIME_STATS)) {
struct net_ptp_time tp = {
/* Use the nanosecond field to temporarily
* store the cycle count as it is a 32-bit
* variable. The net_pkt timestamp field is used
* to calculate how long it takes the packet to travel
* from network device driver to the application.
*/
.nanosecond = k_cycle_get_32(),
};
net_pkt_set_timestamp(pkt, &tp);
}
net_pkt_set_vlan_tag(pkt, NET_VLAN_TAG_UNSPEC);
#if NET_LOG_LEVEL >= LOG_LEVEL_DBG

View file

@ -340,6 +340,21 @@ static inline void net_stats_update_tx_time(struct net_if *iface,
}
#endif /* CONFIG_NET_CONTEXT_TIMESTAMP && STATISTICS */
#if defined(CONFIG_NET_PKT_RXTIME_STATS) && defined(CONFIG_NET_STATISTICS)
static inline void net_stats_update_rx_time(struct net_if *iface,
u32_t start_time,
u32_t end_time)
{
u32_t diff = end_time - start_time;
UPDATE_STAT(iface, stats.rx_time.sum +=
SYS_CLOCK_HW_CYCLES_TO_NS64(diff) / NSEC_PER_USEC);
UPDATE_STAT(iface, stats.rx_time.count += 1);
}
#else
#define net_stats_update_rx_time(iface, start_time, end_time)
#endif /* CONFIG_NET_CONTEXT_TIMESTAMP && STATISTICS */
#if (NET_TC_COUNT > 1) && defined(CONFIG_NET_STATISTICS) \
&& defined(CONFIG_NET_NATIVE)
static inline void net_stats_update_tc_sent_pkt(struct net_if *iface, u8_t tc)
@ -387,6 +402,25 @@ static inline void net_stats_update_tc_tx_time(struct net_if *iface,
}
#endif /* CONFIG_NET_CONTEXT_TIMESTAMP && CONFIG_NET_STATISTICS */
#if defined(CONFIG_NET_PKT_RXTIME_STATS) && defined(CONFIG_NET_STATISTICS) \
&& defined(CONFIG_NET_NATIVE)
static inline void net_stats_update_tc_rx_time(struct net_if *iface,
u8_t tc,
u32_t start_time,
u32_t end_time)
{
u32_t diff = end_time - start_time;
UPDATE_STAT(iface, stats.tc.recv[tc].rx_time.sum +=
SYS_CLOCK_HW_CYCLES_TO_NS64(diff) / NSEC_PER_USEC);
UPDATE_STAT(iface, stats.tc.recv[tc].rx_time.count += 1);
net_stats_update_rx_time(iface, start_time, end_time);
}
#else
#define net_stats_update_tc_rx_time(iface, tc, start_time, end_time)
#endif /* NET_PKT_RXTIME_STATS && NET_STATISTICS */
static inline void net_stats_update_tc_recv_pkt(struct net_if *iface, u8_t tc)
{
UPDATE_STAT(iface, stats.tc.recv[tc].pkts++);
@ -434,6 +468,21 @@ static inline void net_stats_update_tc_tx_time(struct net_if *iface,
ARG_UNUSED(end_time);
}
#endif /* CONFIG_NET_CONTEXT_TIMESTAMP && CONFIG_NET_STATISTICS */
#if defined(CONFIG_NET_PKT_RXTIME_STATS) && defined(CONFIG_NET_STATISTICS) \
&& defined(CONFIG_NET_NATIVE)
static inline void net_stats_update_tc_rx_time(struct net_if *iface,
u8_t pkt_priority,
u32_t start_time,
u32_t end_time)
{
ARG_UNUSED(pkt_priority);
net_stats_update_rx_time(iface, start_time, end_time);
}
#else
#define net_stats_update_tc_rx_time(iface, priority, start_time, end_time)
#endif /* NET_PKT_RXTIME_STATS && NET_STATISTICS */
#endif /* NET_TC_COUNT > 1 */
#if defined(CONFIG_NET_STATISTICS_PERIODIC_OUTPUT) \

View file

@ -19,6 +19,7 @@ LOG_MODULE_REGISTER(net_sock, CONFIG_NET_SOCKETS_LOG_LEVEL);
#include <sys/fdtable.h>
#include <sys/math_extras.h>
#include <net/socks.h>
#include "../../ip/net_stats.h"
#include "sockets_internal.h"
@ -765,6 +766,11 @@ static inline ssize_t zsock_recv_dgram(struct net_context *ctx,
return -1;
}
net_stats_update_tc_rx_time(net_pkt_iface(pkt),
net_pkt_priority(pkt),
net_pkt_timestamp(pkt)->nanosecond,
k_cycle_get_32());
if (!(flags & ZSOCK_MSG_PEEK)) {
net_pkt_unref(pkt);
} else {
@ -846,6 +852,12 @@ static inline ssize_t zsock_recv_stream(struct net_context *ctx,
sock_set_eof(ctx);
}
net_stats_update_tc_rx_time(
net_pkt_iface(pkt),
net_pkt_priority(pkt),
net_pkt_timestamp(pkt)->nanosecond,
k_cycle_get_32());
net_pkt_unref(pkt);
}
} else {