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. Signed-off-by: Stefan Laesser <stefan.laes...@omicronenergy.com> --- .mailmap | 1 + doc/guides/nics/af_packet.rst | 8 ++++-- drivers/net/af_packet/rte_eth_af_packet.c | 34 +++++++++++++++++++++-- 3 files changed, 38 insertions(+), 5 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..e5da625e09 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 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..6a7d5d0ffb 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) +uint64_t af_packet_timestamp_dynflag; +int af_packet_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, af_packet_timestamp_dynfield_offset, + rte_mbuf_timestamp_t *) = + (uint64_t)ppd->tp_sec * 1000000000 + ppd->tp_nsec; + + mbuf->ol_flags |= af_packet_timestamp_dynflag; + } + /* release incoming frame and advance ring buffer */ ppd->tp_status = TP_STATUS_KERNEL; if (++framenum >= framecount) @@ -315,13 +330,25 @@ static int 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(&af_packet_timestamp_dynfield_offset, + &af_packet_timestamp_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; + + uint16_t i; for (i = 0; i < internals->nb_queues; i++) { dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; } + return 0; } @@ -365,6 +392,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 +409,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 +537,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