Add the packet timestamp from TPACKET_V2 to the mbuf dynamic rx timestamp register if offload RTE_ETH_RX_OFFLOAD_TIMESTAMP is enabled.
TPACKET_V2 provides the timestamp with nanosecond resolution and UNIX origo, i.e. time since 1-JAN-1970 UTC. Signed-off-by: Stefan Laesser <stefan.laes...@omicronenergy.com> Acked-by: Morten Brørup <m...@smartsharesystems.com> --- v3: * fixed compilation errors v2: * mentioned that timestamp is since 1-JAN-1970 UTC * made the two timestamp_dynflag variables private and removed prefix * undo moving of counter variable in eth_dev_start() to reduce code changes .mailmap | 1 + doc/guides/nics/af_packet.rst | 8 +++--- drivers/net/af_packet/rte_eth_af_packet.c | 30 ++++++++++++++++++++++- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/.mailmap b/.mailmap index 4a508bafad..69314e34a0 100644 --- a/.mailmap +++ b/.mailmap @@ -1414,6 +1414,7 @@ Steeven Lee <stee...@gmail.com> Steeven Li <steeven...@broadcom.com> Stefan Baranoff <sbaran...@gmail.com> Stefan Hajnoczi <stefa...@redhat.com> +Stefan Laesser <stefan.laes...@omicronenergy.com> Stefan Puiu <stefan.p...@gmail.com> Stefan Wegrzyn <stefan.wegr...@intel.com> Stepan Sojka <stepan.so...@adaptivemobile.com> diff --git a/doc/guides/nics/af_packet.rst b/doc/guides/nics/af_packet.rst index 66b977e1a2..a343d3a961 100644 --- a/doc/guides/nics/af_packet.rst +++ b/doc/guides/nics/af_packet.rst @@ -69,6 +69,8 @@ framecnt=512): Features and Limitations ------------------------ -The PMD will re-insert the VLAN tag transparently to the packet if the kernel -strips it, as long as the ``RTE_ETH_RX_OFFLOAD_VLAN_STRIP`` is not enabled by the -application. +* The PMD will re-insert the VLAN tag transparently to the packet if the kernel + strips it, as long as the ``RTE_ETH_RX_OFFLOAD_VLAN_STRIP`` is not enabled by the + application. +* The PMD will add the kernel packet timestamp with nanoseconds resolution and + UNIX origo, i.e. time since 1-JAN-1970 UTC, if ``RTE_ETH_RX_OFFLOAD_TIMESTAMP`` is enabled. diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c index 6b7b16f348..d532105745 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -40,6 +40,9 @@ #define DFLT_FRAME_SIZE (1 << 11) #define DFLT_FRAME_COUNT (1 << 9) +static uint64_t timestamp_dynflag; +static int timestamp_dynfield_offset = -1; + struct __rte_cache_aligned pkt_rx_queue { int sockfd; @@ -51,6 +54,7 @@ struct __rte_cache_aligned pkt_rx_queue { struct rte_mempool *mb_pool; uint16_t in_port; uint8_t vlan_strip; + uint8_t timestamp_offloading; volatile unsigned long rx_pkts; volatile unsigned long rx_bytes; @@ -82,6 +86,7 @@ struct pmd_internals { struct pkt_rx_queue *rx_queue; struct pkt_tx_queue *tx_queue; uint8_t vlan_strip; + uint8_t timestamp_offloading; }; static const char *valid_arguments[] = { @@ -157,6 +162,16 @@ eth_af_packet_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) PMD_LOG(ERR, "Failed to reinsert VLAN tag"); } + /* add kernel provided timestamp when offloading is enabled */ + if (pkt_q->timestamp_offloading) { + /* since TPACKET_V2 timestamps are provided in nanoseconds resolution */ + *RTE_MBUF_DYNFIELD(mbuf, timestamp_dynfield_offset, + rte_mbuf_timestamp_t *) = + (uint64_t)ppd->tp_sec * 1000000000 + ppd->tp_nsec; + + mbuf->ol_flags |= timestamp_dynflag; + } + /* release incoming frame and advance ring buffer */ ppd->tp_status = TP_STATUS_KERNEL; if (++framenum >= framecount) @@ -317,6 +332,16 @@ eth_dev_start(struct rte_eth_dev *dev) struct pmd_internals *internals = dev->data->dev_private; uint16_t i; + if (internals->timestamp_offloading) { + /* Register mbuf field and flag for Rx timestamp */ + int rc = rte_mbuf_dyn_rx_timestamp_register(×tamp_dynfield_offset, + ×tamp_dynflag); + if (rc) { + PMD_LOG(ERR, "Cannot register mbuf field/flag for timestamp"); + return rc; + } + } + dev->data->dev_link.link_status = RTE_ETH_LINK_UP; for (i = 0; i < internals->nb_queues; i++) { dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; @@ -365,6 +390,7 @@ eth_dev_configure(struct rte_eth_dev *dev __rte_unused) struct pmd_internals *internals = dev->data->dev_private; internals->vlan_strip = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP); + internals->timestamp_offloading = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP); return 0; } @@ -381,7 +407,8 @@ eth_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->min_rx_bufsize = 0; dev_info->tx_offload_capa = RTE_ETH_TX_OFFLOAD_MULTI_SEGS | RTE_ETH_TX_OFFLOAD_VLAN_INSERT; - dev_info->rx_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP; + dev_info->rx_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP | + RTE_ETH_RX_OFFLOAD_TIMESTAMP; return 0; } @@ -508,6 +535,7 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, dev->data->rx_queues[rx_queue_id] = pkt_q; pkt_q->in_port = dev->data->port_id; pkt_q->vlan_strip = internals->vlan_strip; + pkt_q->timestamp_offloading = internals->timestamp_offloading; return 0; } -- 2.34.1