Skip to content

Commit d0d8d76

Browse files
committed
Propagate DPDK mbuf RX timestamp to FreeBSD mbuf rcv_tstmp
Enable RTE_ETH_RX_OFFLOAD_TIMESTAMP on ports where the NIC supports it, register the timestamp dynamic field and flag via rte_mbuf_dyn_rx_timestamp_register() after rte_eth_dev_start() (when the PMD has registered the dynfield), and copy it into the FreeBSD mbuf's m_pkthdr.rcv_tstmp so that the existing SO_TIMESTAMP / SCM_TIMESTAMP path delivers it to userspace. Uses the DPDK 23.11 dynamic field API: checks the registered dynflag mask per-packet (not the legacy RTE_MBUF_F_RX_IEEE1588_TMST) and reads the timestamp via RTE_MBUF_DYNFIELD at the registered offset. When HW timestamps are not available the offload is not enabled, the dynflag is never set, and the new code path is never entered — fully backward compatible. Fixes: #1045
1 parent 81919cd commit d0d8d76

3 files changed

Lines changed: 37 additions & 0 deletions

File tree

lib/ff_dpdk_if.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include <rte_udp.h>
5555
#include <rte_eth_bond.h>
5656
#include <rte_eth_bond_8023ad.h>
57+
#include <rte_mbuf_dyn.h>
5758

5859
#include "ff_dpdk_if.h"
5960
#include "ff_dpdk_pcap.h"
@@ -80,6 +81,8 @@ static int numa_on;
8081

8182
static unsigned idle_sleep;
8283
static unsigned pkt_tx_delay;
84+
static int timestamp_dynfield_offset = -1;
85+
static uint64_t timestamp_dynflag_mask;
8386
static uint64_t usr_cb_tsc;
8487
static int stop_loop;
8588

@@ -740,6 +743,11 @@ init_port_start(void)
740743
pconf->hw_features.rx_csum = 1;
741744
}
742745

746+
if (dev_info.rx_offload_capa & RTE_ETH_RX_OFFLOAD_TIMESTAMP) {
747+
ff_log(FF_LOG_INFO, FF_LOGTYPE_FSTACK_LIB, "RX timestamp offload supported\n");
748+
port_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
749+
}
750+
743751
if (ff_global_cfg.dpdk.tx_csum_offoad_skip == 0) {
744752
if ((dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM)) {
745753
ff_log(FF_LOG_INFO, FF_LOGTYPE_FSTACK_LIB, "TX ip checksum offload supported\n");
@@ -851,6 +859,20 @@ init_port_start(void)
851859
return ret;
852860
}
853861

862+
if ((port_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) &&
863+
timestamp_dynfield_offset < 0) {
864+
ret = rte_mbuf_dyn_rx_timestamp_register(
865+
&timestamp_dynfield_offset, &timestamp_dynflag_mask);
866+
if (ret == 0) {
867+
ff_log(FF_LOG_INFO, FF_LOGTYPE_FSTACK_LIB,
868+
"RX timestamp dynfield registered, offset=%d\n",
869+
timestamp_dynfield_offset);
870+
} else {
871+
ff_log(FF_LOG_ERR, FF_LOGTYPE_FSTACK_LIB,
872+
"RX timestamp dynfield registration failed\n");
873+
}
874+
}
875+
854876
//RSS reta update will failed when enable flow isolate
855877
#if !defined(FF_FLOW_ISOLATE) && !defined(FF_FLOW_IPIP)
856878
if (nb_queues > 1) {
@@ -1459,6 +1481,13 @@ ff_veth_input(const struct ff_dpdk_if_context *ctx, struct rte_mbuf *pkt)
14591481
ff_mbuf_set_vlan_info(hdr, pkt->vlan_tci);
14601482
}
14611483

1484+
if ((pkt->ol_flags & timestamp_dynflag_mask) &&
1485+
timestamp_dynfield_offset >= 0) {
1486+
rte_mbuf_timestamp_t ts = *RTE_MBUF_DYNFIELD(
1487+
pkt, timestamp_dynfield_offset, rte_mbuf_timestamp_t *);
1488+
ff_mbuf_set_timestamp(hdr, (uint64_t)ts);
1489+
}
1490+
14621491
struct rte_mbuf *pn = pkt->next;
14631492
void *prev = hdr;
14641493
while(pn != NULL) {

lib/ff_veth.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,3 +1124,10 @@ ff_mbuf_set_vlan_info(void *hdr, uint16_t vlan_tci) {
11241124
return;
11251125
}
11261126

1127+
void
1128+
ff_mbuf_set_timestamp(void *hdr, uint64_t timestamp) {
1129+
struct mbuf *m = (struct mbuf *)hdr;
1130+
m->m_pkthdr.rcv_tstmp = timestamp;
1131+
m->m_flags |= M_TSTMP | M_TSTMP_HPREC;
1132+
}
1133+

lib/ff_veth.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,6 @@ void *ff_veth_get_softc(void *host_ctx);
5252
void ff_veth_free_softc(void *softc);
5353

5454
void ff_mbuf_set_vlan_info(void *hdr, uint16_t vlan_tci);
55+
void ff_mbuf_set_timestamp(void *hdr, uint64_t timestamp);
5556

5657
#endif /* ifndef _FSTACK_VETH_H */

0 commit comments

Comments
 (0)