patch 'pcapng: fix timestamp wrapping in output files' has been queued to stable release 21.11.2

Kevin Traynor ktraynor at redhat.com
Thu Jun 9 13:35:58 CEST 2022


Hi,

FYI, your patch has been queued to stable release 21.11.2

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 06/13/22. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/kevintraynor/dpdk-stable

This queued commit can be viewed at:
https://github.com/kevintraynor/dpdk-stable/commit/3a9e4cdb3f8cf9b98b22ef0d51a22dcf6519cdb8

Thanks.

Kevin

---
>From 3a9e4cdb3f8cf9b98b22ef0d51a22dcf6519cdb8 Mon Sep 17 00:00:00 2001
From: Quentin Armitage <quentin at armitage.org.uk>
Date: Tue, 17 May 2022 11:01:15 +0100
Subject: [PATCH] pcapng: fix timestamp wrapping in output files

[ upstream commit c882eb544842d94ce06af12b87bb7a4c572b20fb ]

In pcap_tsc_to_ns(), delta * NSEC_PER_SEC will overflow approx 8
seconds after pcap_init is called when using a TSC with a frequency
of 2.5GHz.

To avoid the overflow, update the saved time and TSC value once
delta >= tsc_hz.

Fixes: 8d23ce8f5ee ("pcapng: add new library for writing pcapng files")

Signed-off-by: Quentin Armitage <quentin at armitage.org.uk>
Acked-by: Stephen Hemminger <stephen at networkplumber.org>
---
 lib/pcapng/rte_pcapng.c | 45 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/lib/pcapng/rte_pcapng.c b/lib/pcapng/rte_pcapng.c
index 9db058fe42..0caf3d31f8 100644
--- a/lib/pcapng/rte_pcapng.c
+++ b/lib/pcapng/rte_pcapng.c
@@ -21,4 +21,5 @@
 #include <rte_mbuf.h>
 #include <rte_pcapng.h>
+#include <rte_reciprocal.h>
 #include <rte_time.h>
 
@@ -36,10 +37,13 @@ struct rte_pcapng {
 
 /* For converting TSC cycles to PCAPNG ns format */
-struct pcapng_time {
+static struct pcapng_time {
 	uint64_t ns;
 	uint64_t cycles;
+	uint64_t tsc_hz;
+	struct rte_reciprocal_u64 tsc_hz_inverse;
 } pcapng_time;
 
-RTE_INIT(pcapng_init)
+static inline void
+pcapng_init(void)
 {
 	struct timespec ts;
@@ -47,5 +51,9 @@ RTE_INIT(pcapng_init)
 	pcapng_time.cycles = rte_get_tsc_cycles();
 	clock_gettime(CLOCK_REALTIME, &ts);
+	pcapng_time.cycles = (pcapng_time.cycles + rte_get_tsc_cycles()) / 2;
 	pcapng_time.ns = rte_timespec_to_ns(&ts);
+
+	pcapng_time.tsc_hz = rte_get_tsc_hz();
+	pcapng_time.tsc_hz_inverse = rte_reciprocal_value_u64(pcapng_time.tsc_hz);
 }
 
@@ -53,8 +61,37 @@ RTE_INIT(pcapng_init)
 static uint64_t pcapng_tsc_to_ns(uint64_t cycles)
 {
-	uint64_t delta;
+	uint64_t delta, secs;
 
+	if (!pcapng_time.tsc_hz)
+		pcapng_init();
+
+	/* In essence the calculation is:
+	 *   delta = (cycles - pcapng_time.cycles) * NSEC_PRE_SEC / rte_get_tsc_hz()
+	 * but this overflows within 4 to 8 seconds depending on TSC frequency.
+	 * Instead, if delta >= pcapng_time.tsc_hz:
+	 *   Increase pcapng_time.ns and pcapng_time.cycles by the number of
+	 *   whole seconds in delta and reduce delta accordingly.
+	 * delta will therefore always lie in the interval [0, pcapng_time.tsc_hz),
+	 * which will not overflow when multiplied by NSEC_PER_SEC provided the
+	 * TSC frequency < approx 18.4GHz.
+	 *
+	 * Currently all TSCs operate below 5GHz.
+	 */
 	delta = cycles - pcapng_time.cycles;
-	return pcapng_time.ns + (delta * NSEC_PER_SEC) / rte_get_tsc_hz();
+	if (unlikely(delta >= pcapng_time.tsc_hz)) {
+		if (likely(delta < pcapng_time.tsc_hz * 2)) {
+			delta -= pcapng_time.tsc_hz;
+			pcapng_time.cycles += pcapng_time.tsc_hz;
+			pcapng_time.ns += NSEC_PER_SEC;
+		} else {
+			secs = rte_reciprocal_divide_u64(delta, &pcapng_time.tsc_hz_inverse);
+			delta -= secs * pcapng_time.tsc_hz;
+			pcapng_time.cycles += secs * pcapng_time.tsc_hz;
+			pcapng_time.ns += secs * NSEC_PER_SEC;
+		}
+	}
+
+	return pcapng_time.ns + rte_reciprocal_divide_u64(delta * NSEC_PER_SEC,
+							  &pcapng_time.tsc_hz_inverse);
 }
 
-- 
2.34.3

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2022-06-09 12:34:30.035182769 +0100
+++ 0011-pcapng-fix-timestamp-wrapping-in-output-files.patch	2022-06-09 12:34:29.618980424 +0100
@@ -1 +1 @@
-From c882eb544842d94ce06af12b87bb7a4c572b20fb Mon Sep 17 00:00:00 2001
+From 3a9e4cdb3f8cf9b98b22ef0d51a22dcf6519cdb8 Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit c882eb544842d94ce06af12b87bb7a4c572b20fb ]
+
@@ -14 +15,0 @@
-Cc: stable at dpdk.org
@@ -23 +24 @@
-index 90b2f5bc69..06ad712bd1 100644
+index 9db058fe42..0caf3d31f8 100644
@@ -26 +27 @@
-@@ -20,4 +20,5 @@
+@@ -21,4 +21,5 @@
@@ -32 +33 @@
-@@ -35,10 +36,13 @@ struct rte_pcapng {
+@@ -36,10 +37,13 @@ struct rte_pcapng {
@@ -48 +49 @@
-@@ -46,5 +50,9 @@ RTE_INIT(pcapng_init)
+@@ -47,5 +51,9 @@ RTE_INIT(pcapng_init)
@@ -58 +59 @@
-@@ -52,8 +60,37 @@ RTE_INIT(pcapng_init)
+@@ -53,8 +61,37 @@ RTE_INIT(pcapng_init)



More information about the stable mailing list