net: pkt: Have separate create time for net_pkt

This value is used to measure the RX/TX statistics. The previous
use of the timestamp field did not work in RX path as the timestamp
value could be overwritten by the driver if gPTP timestamping
is enabled. So to fix the RX statistics, use a separate field
for the create time.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2021-04-13 13:04:42 +03:00 committed by Jukka Rissanen
commit bd03493fdc
4 changed files with 39 additions and 20 deletions

View file

@ -104,6 +104,10 @@ struct net_pkt {
/** Timestamp if available. */ /** Timestamp if available. */
struct net_ptp_time timestamp; struct net_ptp_time timestamp;
#if defined(CONFIG_NET_PKT_RXTIME_STATS) || defined(CONFIG_NET_PKT_TXTIME_STATS)
/** Create time in cycles */
uint32_t create_time;
#endif
#if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) || \ #if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) || \
defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL)
/** Collect extra statistics for net_pkt processing /** Collect extra statistics for net_pkt processing
@ -807,6 +811,33 @@ static inline void net_pkt_set_timestamp(struct net_pkt *pkt,
} }
#endif /* CONFIG_NET_PKT_TIMESTAMP */ #endif /* CONFIG_NET_PKT_TIMESTAMP */
#if defined(CONFIG_NET_PKT_RXTIME_STATS) || defined(CONFIG_NET_PKT_TXTIME_STATS)
static inline uint32_t net_pkt_create_time(struct net_pkt *pkt)
{
return pkt->create_time;
}
static inline void net_pkt_set_create_time(struct net_pkt *pkt,
uint32_t create_time)
{
pkt->create_time = create_time;
}
#else
static inline uint32_t net_pkt_create_time(struct net_pkt *pkt)
{
ARG_UNUSED(pkt);
return 0U;
}
static inline void net_pkt_set_create_time(struct net_pkt *pkt,
uint32_t create_time)
{
ARG_UNUSED(pkt);
ARG_UNUSED(create_time);
}
#endif /* CONFIG_NET_PKT_RXTIME_STATS || CONFIG_NET_PKT_TXTIME_STATS */
#if defined(CONFIG_NET_PKT_TXTIME) #if defined(CONFIG_NET_PKT_TXTIME)
static inline uint64_t net_pkt_txtime(struct net_pkt *pkt) static inline uint64_t net_pkt_txtime(struct net_pkt *pkt)
{ {

View file

@ -210,11 +210,9 @@ static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt)
}; };
struct net_linkaddr_storage ll_dst_storage; struct net_linkaddr_storage ll_dst_storage;
struct net_context *context; struct net_context *context;
uint32_t create_time;
int status; int status;
/* Timestamp of the current network packet sent if enabled */
struct net_ptp_time start_timestamp;
/* We collect send statistics for each socket priority if enabled */ /* We collect send statistics for each socket priority if enabled */
uint8_t pkt_priority; uint8_t pkt_priority;
@ -222,6 +220,8 @@ static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt)
return false; return false;
} }
create_time = net_pkt_create_time(pkt);
debug_check_packet(pkt); debug_check_packet(pkt);
/* If there're any link callbacks, with such a callback receiving /* If there're any link callbacks, with such a callback receiving
@ -247,8 +247,6 @@ static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt)
} }
if (IS_ENABLED(CONFIG_NET_PKT_TXTIME_STATS)) { if (IS_ENABLED(CONFIG_NET_PKT_TXTIME_STATS)) {
memcpy(&start_timestamp, net_pkt_timestamp(pkt),
sizeof(start_timestamp));
pkt_priority = net_pkt_priority(pkt); pkt_priority = net_pkt_priority(pkt);
if (IS_ENABLED(CONFIG_NET_PKT_TXTIME_STATS_DETAIL)) { if (IS_ENABLED(CONFIG_NET_PKT_TXTIME_STATS_DETAIL)) {
@ -268,13 +266,13 @@ static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt)
net_stats_update_tc_tx_time(iface, net_stats_update_tc_tx_time(iface,
pkt_priority, pkt_priority,
start_timestamp.nanosecond, create_time,
end_tick); end_tick);
if (IS_ENABLED(CONFIG_NET_PKT_TXTIME_STATS_DETAIL)) { if (IS_ENABLED(CONFIG_NET_PKT_TXTIME_STATS_DETAIL)) {
update_txtime_stats_detail( update_txtime_stats_detail(
pkt, pkt,
start_timestamp.nanosecond, create_time,
end_tick); end_tick);
net_stats_update_tc_tx_time_detail( net_stats_update_tc_tx_time_detail(

View file

@ -1230,17 +1230,7 @@ static struct net_pkt *pkt_alloc(struct k_mem_slab *slab, k_timeout_t timeout)
if (IS_ENABLED(CONFIG_NET_PKT_RXTIME_STATS) || if (IS_ENABLED(CONFIG_NET_PKT_RXTIME_STATS) ||
IS_ENABLED(CONFIG_NET_PKT_TXTIME_STATS)) { IS_ENABLED(CONFIG_NET_PKT_TXTIME_STATS)) {
struct net_ptp_time tp = { net_pkt_set_create_time(pkt, create_time);
/* 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
* between network device driver and application.
*/
.nanosecond = create_time,
};
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);

View file

@ -931,11 +931,11 @@ void net_socket_update_tc_rx_time(struct net_pkt *pkt, uint32_t end_tick)
net_stats_update_tc_rx_time(net_pkt_iface(pkt), net_stats_update_tc_rx_time(net_pkt_iface(pkt),
net_pkt_priority(pkt), net_pkt_priority(pkt),
net_pkt_timestamp(pkt)->nanosecond, net_pkt_create_time(pkt),
end_tick); end_tick);
if (IS_ENABLED(CONFIG_NET_PKT_RXTIME_STATS_DETAIL)) { if (IS_ENABLED(CONFIG_NET_PKT_RXTIME_STATS_DETAIL)) {
uint32_t val, prev = net_pkt_timestamp(pkt)->nanosecond; uint32_t val, prev = net_pkt_create_time(pkt);
int i; int i;
for (i = 0; i < net_pkt_stats_tick_count(pkt); i++) { for (i = 0; i < net_pkt_stats_tick_count(pkt); i++) {