From: Isaac Boukris <iboukris@gmail.com>
To: dev@dpdk.org
Cc: stephen@networkplumber.org, bruce.richardson@intel.com,
roretzla@linux.microsoft.com, dmitry.kozliuk@gmail.com,
david.marchand@redhat.com, Isaac Boukris <iboukris@gmail.com>
Subject: [PATCH v3 2/2] timer/linux/x86: override TSC freq if no tsc_known_freq
Date: Tue, 1 Oct 2024 03:22:51 +0300 [thread overview]
Message-ID: <20241001002527.277838-3-iboukris@gmail.com> (raw)
In-Reply-To: <20241001002527.277838-1-iboukris@gmail.com>
If the tsc_known_freq cpu flag is missing, it means the kernel doesn't
trust it and calculates its own. We should do the same to avoid drift.
Signed-off-by: Isaac Boukris <iboukris@gmail.com>
---
lib/eal/common/eal_common_timer.c | 3 +-
lib/eal/common/eal_private.h | 2 +-
lib/eal/freebsd/eal_timer.c | 5 ++-
lib/eal/linux/eal_timer.c | 53 +++++++++++++++++++++++++++++--
lib/eal/windows/eal_timer.c | 5 ++-
5 files changed, 60 insertions(+), 8 deletions(-)
diff --git a/lib/eal/common/eal_common_timer.c b/lib/eal/common/eal_common_timer.c
index c5c4703f15..e00be0a5c8 100644
--- a/lib/eal/common/eal_common_timer.c
+++ b/lib/eal/common/eal_common_timer.c
@@ -66,8 +66,7 @@ set_tsc_freq(void)
}
freq = get_tsc_freq_arch();
- if (!freq)
- freq = get_tsc_freq();
+ freq = get_tsc_freq(freq);
if (!freq)
freq = estimate_tsc_freq();
diff --git a/lib/eal/common/eal_private.h b/lib/eal/common/eal_private.h
index af09620426..bb315dab04 100644
--- a/lib/eal/common/eal_private.h
+++ b/lib/eal/common/eal_private.h
@@ -374,7 +374,7 @@ void set_tsc_freq(void);
*
* This function is private to the EAL.
*/
-uint64_t get_tsc_freq(void);
+uint64_t get_tsc_freq(uint64_t arch_hz);
/**
* Get TSC frequency if the architecture supports.
diff --git a/lib/eal/freebsd/eal_timer.c b/lib/eal/freebsd/eal_timer.c
index 3dd70e24ba..5a8aea03e1 100644
--- a/lib/eal/freebsd/eal_timer.c
+++ b/lib/eal/freebsd/eal_timer.c
@@ -26,12 +26,15 @@
enum timer_source eal_timer_source = EAL_TIMER_TSC;
uint64_t
-get_tsc_freq(void)
+get_tsc_freq(uint64_t arch_hz)
{
size_t sz;
int tmp;
uint64_t tsc_hz;
+ if (arch_hz)
+ return arch_hz;
+
sz = sizeof(tmp);
tmp = 0;
diff --git a/lib/eal/linux/eal_timer.c b/lib/eal/linux/eal_timer.c
index f56a7ae15b..2c5fc9ff3e 100644
--- a/lib/eal/linux/eal_timer.c
+++ b/lib/eal/linux/eal_timer.c
@@ -5,9 +5,9 @@
#include <stdio.h>
#include <stdint.h>
+#include <inttypes.h>
#ifdef RTE_LIBEAL_USE_HPET
#include <fcntl.h>
-#include <inttypes.h>
#include <sys/mman.h>
#include <unistd.h>
#endif
@@ -187,8 +187,41 @@ rte_eal_hpet_init(int make_default)
}
#endif
+/* Check if the kernel deems the arch provided TSC frequency trustworthy. */
+
+static bool
+is_tsc_known_freq(void)
+{
+ bool ret = true; /* Assume tsc_known_freq */
+
+#if defined(RTE_ARCH_X86)
+ char line[2048];
+ FILE *stream;
+
+ stream = fopen("/proc/cpuinfo", "r");
+ if (!stream) {
+ EAL_LOG(WARNING, "Unable to open /proc/cpuinfo");
+ return ret;
+ }
+
+ while (fgets(line, sizeof(line), stream)) {
+ if (strncmp(line, "flags", 5) != 0)
+ continue;
+
+ if (!strstr(line, "tsc_known_freq"))
+ ret = false;
+
+ break;
+ }
+
+ fclose(stream);
+#endif
+
+ return ret;
+}
+
uint64_t
-get_tsc_freq(void)
+get_tsc_freq(uint64_t arch_hz)
{
#ifdef CLOCK_MONOTONIC_RAW
#define NS_PER_SEC 1E9
@@ -199,6 +232,9 @@ get_tsc_freq(void)
struct timespec t_start, t_end;
uint64_t tsc_hz;
+ if (arch_hz && is_tsc_known_freq())
+ return arch_hz;
+
if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0) {
uint64_t ns, end, start = rte_rdtsc();
nanosleep(&sleeptime,NULL);
@@ -209,11 +245,22 @@ get_tsc_freq(void)
double secs = (double)ns/NS_PER_SEC;
tsc_hz = (uint64_t)((end - start)/secs);
+
+ if (arch_hz) {
+ /* Make sure we're within 1% for sanity check */
+ if (arch_hz - tsc_hz > arch_hz / 100)
+ return arch_hz;
+
+ EAL_LOG(DEBUG,
+ "Refined arch frequency %"PRIu64" to measured frequency %"PRIu64,
+ arch_hz, tsc_hz);
+ }
+
/* Round up to 100Khz. 1E5 ~ 100Khz */
return RTE_ALIGN_MUL_NEAR(tsc_hz, CYC_PER_100KHZ);
}
#endif
- return 0;
+ return arch_hz;
}
int
diff --git a/lib/eal/windows/eal_timer.c b/lib/eal/windows/eal_timer.c
index b070cb7751..cfd6c267ac 100644
--- a/lib/eal/windows/eal_timer.c
+++ b/lib/eal/windows/eal_timer.c
@@ -49,13 +49,16 @@ rte_delay_us_sleep(unsigned int us)
}
uint64_t
-get_tsc_freq(void)
+get_tsc_freq(uint64_t arch_hz)
{
LARGE_INTEGER t_start, t_end, elapsed_us;
LARGE_INTEGER frequency;
uint64_t tsc_hz;
uint64_t end, start;
+ if (arch_hz)
+ return arch_hz;
+
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&t_start);
--
2.45.0
next prev parent reply other threads:[~2024-10-01 0:26 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-21 14:00 [PATCH 1/2] timer/linux: lower rounding of tsc estimation to 10KHz Isaac Boukris
2024-09-21 14:00 ` [PATCH 2/2] timer/linux: override TSC freq if no tsc_known_freq Isaac Boukris
2024-09-24 17:04 ` Isaac Boukris
2024-09-30 15:04 ` Bruce Richardson
2024-09-30 22:08 ` [PATCH v2 0/2] Improve TSC frequency accuracy on Linux Isaac Boukris
2024-09-30 22:08 ` [PATCH v2 1/2] timer/linux: lower rounding of tsc estimation to 100KHz Isaac Boukris
2024-09-30 22:08 ` [PATCH v2 2/2] timer/linux/x86: override TSC freq if no tsc_known_freq Isaac Boukris
2024-10-01 0:10 ` Stephen Hemminger
2024-10-01 0:22 ` [PATCH v3 0/2] Improve TSC frequency accuracy on Linux Isaac Boukris
2024-10-01 0:22 ` [PATCH v3 1/2] timer/linux: lower rounding of tsc estimation to 100KHz Isaac Boukris
2024-10-01 15:18 ` Stephen Hemminger
2024-10-01 0:22 ` Isaac Boukris [this message]
2024-10-01 15:19 ` [PATCH v3 2/2] timer/linux/x86: override TSC freq if no tsc_known_freq Stephen Hemminger
2024-10-01 21:56 ` Isaac Boukris
2024-10-01 20:01 ` Bruce Richardson
2024-10-01 21:59 ` Isaac Boukris
2024-10-02 8:06 ` Bruce Richardson
2024-10-02 16:56 ` [PATCH v4 0/2] Improve TSC frequency accuracy Isaac Boukris
2024-10-02 16:56 ` [PATCH v4 1/2] timer: lower rounding of TSC estimation to 100KHz Isaac Boukris
2024-10-02 16:56 ` [PATCH v4 2/2] timer: allow platform to override cpu TSC frequency Isaac Boukris
2024-10-02 17:11 ` Bruce Richardson
2024-10-02 19:14 ` Isaac Boukris
2024-10-03 9:31 ` Bruce Richardson
2024-10-03 12:29 ` Isaac Boukris
2024-10-02 17:12 ` [PATCH v4 0/2] Improve TSC frequency accuracy Bruce Richardson
2024-10-03 12:26 ` [PATCH v5 " Isaac Boukris
2024-10-03 12:26 ` [PATCH v5 1/2] timer: lower rounding of TSC estimation to 100KHz Isaac Boukris
2024-10-03 14:05 ` Bruce Richardson
2024-10-03 15:13 ` Stephen Hemminger
2024-10-08 7:56 ` David Marchand
2024-10-03 12:26 ` [PATCH v5 2/2] timer: allow platform to override cpu TSC frequency Isaac Boukris
2024-10-03 14:06 ` Bruce Richardson
2024-10-03 15:14 ` Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241001002527.277838-3-iboukris@gmail.com \
--to=iboukris@gmail.com \
--cc=bruce.richardson@intel.com \
--cc=david.marchand@redhat.com \
--cc=dev@dpdk.org \
--cc=dmitry.kozliuk@gmail.com \
--cc=roretzla@linux.microsoft.com \
--cc=stephen@networkplumber.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.