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 */ struct net_if *orig_iface; /* Original network interface */
#endif #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 { union {
#if defined(CONFIG_NET_PKT_TIMESTAMP) #if defined(CONFIG_NET_PKT_TIMESTAMP) || defined(CONFIG_NET_PKT_RXTIME_STATS)
/** Timestamp if available. */ /** Timestamp if available. */
struct net_ptp_time timestamp; struct net_ptp_time timestamp;
#endif /* CONFIG_NET_PKT_TIMESTAMP */ #endif /* CONFIG_NET_PKT_TIMESTAMP */

View file

@ -210,6 +210,14 @@ struct net_stats_tx_time {
net_stats_t time_count; 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 * @brief Traffic class statistics
*/ */
@ -222,6 +230,7 @@ struct net_stats_tc {
} sent[NET_TC_TX_COUNT]; } sent[NET_TC_TX_COUNT];
struct { struct {
struct net_stats_rx_time rx_time;
net_stats_t pkts; net_stats_t pkts;
net_stats_t bytes; net_stats_t bytes;
u8_t priority; u8_t priority;
@ -288,6 +297,11 @@ struct net_stats {
/** Network packet TX time statistics */ /** Network packet TX time statistics */
struct net_stats_tx_time tx_time; struct net_stats_tx_time tx_time;
#endif #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 endchoice
config NET_TX_DEFAULT_PRIORITY 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 default 1
range 0 7 range 0 7
help help
What is the default network packet priority if user has not specified What is the default network packet priority if user has not specified
one. The value 0 means lowest priority and 7 is the highest. 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 config NET_IP_ADDR_CHECK
bool "Check IP address validity before sending IP packet" bool "Check IP address validity before sending IP packet"
default y default y
@ -640,6 +648,19 @@ config NET_PKT_TXTIME
when the application wants to set the exact time when the network when the application wants to set the exact time when the network
packet should be sent. 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 config NET_PROMISCUOUS_MODE
bool "Enable promiscuous mode support [EXPERIMENTAL]" bool "Enable promiscuous mode support [EXPERIMENTAL]"
select NET_MGMT 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_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); net_pkt_set_vlan_tag(pkt, NET_VLAN_TAG_UNSPEC);
#if NET_LOG_LEVEL >= LOG_LEVEL_DBG #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 */ #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) \ #if (NET_TC_COUNT > 1) && defined(CONFIG_NET_STATISTICS) \
&& defined(CONFIG_NET_NATIVE) && defined(CONFIG_NET_NATIVE)
static inline void net_stats_update_tc_sent_pkt(struct net_if *iface, u8_t tc) 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 */ #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) static inline void net_stats_update_tc_recv_pkt(struct net_if *iface, u8_t tc)
{ {
UPDATE_STAT(iface, stats.tc.recv[tc].pkts++); 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); ARG_UNUSED(end_time);
} }
#endif /* CONFIG_NET_CONTEXT_TIMESTAMP && CONFIG_NET_STATISTICS */ #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 */ #endif /* NET_TC_COUNT > 1 */
#if defined(CONFIG_NET_STATISTICS_PERIODIC_OUTPUT) \ #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/fdtable.h>
#include <sys/math_extras.h> #include <sys/math_extras.h>
#include <net/socks.h> #include <net/socks.h>
#include "../../ip/net_stats.h"
#include "sockets_internal.h" #include "sockets_internal.h"
@ -765,6 +766,11 @@ static inline ssize_t zsock_recv_dgram(struct net_context *ctx,
return -1; 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)) { if (!(flags & ZSOCK_MSG_PEEK)) {
net_pkt_unref(pkt); net_pkt_unref(pkt);
} else { } else {
@ -846,6 +852,12 @@ static inline ssize_t zsock_recv_stream(struct net_context *ctx,
sock_set_eof(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); net_pkt_unref(pkt);
} }
} else { } else {