From: Isaac Boukris <iboukris@gmail.com>
To: dev@dpdk.org
Cc: stephen@networkplumber.org, Isaac Boukris <iboukris@gmail.com>,
Tyler Retzlaff <roretzla@linux.microsoft.com>,
Bruce Richardson <bruce.richardson@intel.com>,
Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>,
Pallavi Kadam <pallavi.kadam@intel.com>
Subject: [PATCH 2/2] timer/linux: override TSC freq if no tsc_known_freq
Date: Sat, 21 Sep 2024 17:00:22 +0300 [thread overview]
Message-ID: <20240921140022.107239-2-iboukris@gmail.com> (raw)
In-Reply-To: <20240921140022.107239-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 | 48 +++++++++++++++++++++++++++++--
lib/eal/windows/eal_timer.c | 5 +++-
5 files changed, 56 insertions(+), 7 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 241b20d416..cdbd191828 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,38 @@ 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)
+{
+ char line[2048];
+ FILE *stream;
+ bool ret = true; /* Assume tsc_known_freq */
+
+ 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);
+
+ 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 +229,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,6 +242,17 @@ 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 architecture frequency %"PRIu64
+ " to actual frequency %"PRIu64".",
+ arch_hz, tsc_hz);
+ }
+
/* Round up to 10Khz. 1E4 ~ 10Khz */
return RTE_ALIGN_MUL_NEAR(tsc_hz, CYC_PER_10KHZ);
}
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-09-21 14:00 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 ` Isaac Boukris [this message]
2024-09-24 17:04 ` [PATCH 2/2] timer/linux: override TSC freq if no tsc_known_freq 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 ` [PATCH v3 2/2] timer/linux/x86: override TSC freq if no tsc_known_freq Isaac Boukris
2024-10-01 15:19 ` 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=20240921140022.107239-2-iboukris@gmail.com \
--to=iboukris@gmail.com \
--cc=bruce.richardson@intel.com \
--cc=dev@dpdk.org \
--cc=dmitry.kozliuk@gmail.com \
--cc=pallavi.kadam@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).