Avoid doing slow instructions in receive path when calculating timestamp. Give all packets in the same rx burst the same timestamp.
Signed-off-by: Stephen Hemminger <[email protected]> --- drivers/net/pcap/pcap_ethdev.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/net/pcap/pcap_ethdev.c b/drivers/net/pcap/pcap_ethdev.c index 175d6998f9..e283fb3787 100644 --- a/drivers/net/pcap/pcap_ethdev.c +++ b/drivers/net/pcap/pcap_ethdev.c @@ -20,6 +20,7 @@ #include <bus_vdev_driver.h> #include <rte_os_shim.h> #include <rte_time.h> +#include <rte_reciprocal.h> #include "pcap_osdep.h" @@ -41,7 +42,7 @@ static struct timespec start_time; static uint64_t start_cycles; -static uint64_t hz; +static struct rte_reciprocal_u64 hz_inv; static uint64_t timestamp_rx_dynflag; static int timestamp_dynfield_offset = -1; @@ -362,8 +363,6 @@ eth_null_rx(void *queue __rte_unused, return 0; } -#define NSEC_PER_SEC 1000000000L - /* * This function stores nanoseconds in `tv_usec` field of `struct timeval`, * because `ts` goes directly to nanosecond-precision dump. @@ -374,8 +373,10 @@ calculate_timestamp(struct timeval *ts) { struct timespec cur_time; cycles = rte_get_timer_cycles() - start_cycles; - cur_time.tv_sec = cycles / hz; - cur_time.tv_nsec = (cycles % hz) * NSEC_PER_SEC / hz; + cur_time.tv_sec = rte_reciprocal_divide_u64(cycles, &hz_inv); + /* compute remainder */ + cycles -= cur_time.tv_sec * rte_get_timer_hz(); + cur_time.tv_nsec = rte_reciprocal_divide_u64(cycles * NS_PER_S, &hz_inv); ts->tv_sec = start_time.tv_sec + cur_time.tv_sec; ts->tv_usec = start_time.tv_nsec + cur_time.tv_nsec; @@ -394,6 +395,7 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) unsigned int i; struct pmd_process_private *pp; struct pcap_tx_queue *dumper_q = queue; + struct pcap_pkthdr header; uint16_t num_tx = 0; uint32_t tx_bytes = 0; pcap_dumper_t *dumper; @@ -406,13 +408,14 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) if (unlikely(dumper == NULL || nb_pkts == 0)) return 0; - /* writes the nb_pkts packets to the previously opened pcap file - * dumper */ + /* all packets in burst have same timestamp */ + calculate_timestamp(&header.ts); + + /* writes the nb_pkts packets to the previously opened pcap file dumper */ for (i = 0; i < nb_pkts; i++) { struct rte_mbuf *mbuf = bufs[i]; size_t len = rte_pktmbuf_pkt_len(mbuf); uint8_t temp_data[RTE_ETH_PCAP_SNAPLEN]; - struct pcap_pkthdr header; if (unlikely(len > mtu)) continue; @@ -420,7 +423,6 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) if ((mbuf->ol_flags & RTE_MBUF_F_TX_VLAN) && rte_vlan_insert(&mbuf)) continue; - calculate_timestamp(&header.ts); header.len = len; header.caplen = len; @@ -1530,7 +1532,8 @@ pmd_pcap_probe(struct rte_vdev_device *dev) timespec_get(&start_time, TIME_UTC); start_cycles = rte_get_timer_cycles(); - hz = rte_get_timer_hz(); + + hz_inv = rte_reciprocal_value_u64(rte_get_timer_hz()); if (rte_eal_process_type() == RTE_PROC_SECONDARY) { eth_dev = rte_eth_dev_attach_secondary(name); -- 2.51.0

