* [PATCH] eal: fail initialization if TSC frequency is zero
@ 2026-09-27 19:54 Stephen Hemminger
2026-09-27 20:09 ` Stephen Hemminger
2026-09-28 23:15 ` [PATCH v2] " Stephen Hemminger
0 siblings, 2 replies; 8+ messages in thread
From: Stephen Hemminger @ 2026-09-27 19:54 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, Bruce Richardson, Dmitry Kozlyuk, Ravi Kerur,
Thomas Monjalon
Lots of parts of DPDK will fail with divide by zero and
other errors if the initialization logic ever TSC hz was ever
determined to be zero. This might happen on a broken get_tsc_freq_arch()
or bad emulation in QEMU.
If TSC hz is zero, log the error and propagate back to
fail rte_eal_init().
This fix doesn't need to go to stable since it is a purely
theoretical problem; we aren't getting divide by zero reports
from users.
Fixes: 040cf8a41187 ("eal: deduplicate timer functions")
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/eal/common/eal_common_timer.c | 22 ++++++++++++++++++++--
lib/eal/common/eal_private.h | 2 +-
lib/eal/freebsd/eal_timer.c | 3 +--
lib/eal/include/generic/rte_cycles.h | 7 ++++++-
lib/eal/linux/eal_timer.c | 3 +--
lib/eal/windows/eal_timer.c | 3 +--
6 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/lib/eal/common/eal_common_timer.c b/lib/eal/common/eal_common_timer.c
index bbf8b8b11b..d502468053 100644
--- a/lib/eal/common/eal_common_timer.c
+++ b/lib/eal/common/eal_common_timer.c
@@ -52,7 +52,7 @@ estimate_tsc_freq(void)
return RTE_ALIGN_MUL_NEAR(rte_rdtsc() - start, CYC_PER_10MHZ);
}
-void
+int
set_tsc_freq(void)
{
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
@@ -65,8 +65,13 @@ set_tsc_freq(void)
* systems where arch-specific frequency detection is not
* available.
*/
+ if (mcfg->tsc_hz == 0) {
+ EAL_LOG(ERR, "Primary process TSC frequency is zero");
+ return -1;
+ }
+
eal_tsc_resolution_hz = mcfg->tsc_hz;
- return;
+ return 0;
}
freq = get_tsc_freq_arch();
@@ -74,9 +79,22 @@ set_tsc_freq(void)
if (!freq)
freq = estimate_tsc_freq();
+ /*
+ * Several get_tsc_freq_arch() implementations return zero when the
+ * frequency cannot be read, and a TSC that does not advance at least
+ * once per second measures as zero. Such a counter cannot be scaled
+ * to a time at all, so fail rather than let callers of
+ * rte_get_tsc_hz() divide by zero.
+ */
+ if (freq == 0) {
+ EAL_LOG(ERR, "TSC frequency could not be determined");
+ return -1;
+ }
+
EAL_LOG(DEBUG, "TSC frequency is ~%" PRIu64 " KHz", freq / 1000);
eal_tsc_resolution_hz = freq;
mcfg->tsc_hz = freq;
+ return 0;
}
RTE_EXPORT_SYMBOL(rte_delay_us_callback_register)
diff --git a/lib/eal/common/eal_private.h b/lib/eal/common/eal_private.h
index 6340bab8be..952cb5a03e 100644
--- a/lib/eal/common/eal_private.h
+++ b/lib/eal/common/eal_private.h
@@ -409,7 +409,7 @@ int eal_cpu_detected(unsigned lcore_id);
*
* This function is private to the EAL.
*/
-void set_tsc_freq(void);
+int set_tsc_freq(void);
/**
* Get precise TSC frequency from system
diff --git a/lib/eal/freebsd/eal_timer.c b/lib/eal/freebsd/eal_timer.c
index d21ffa2694..84127d876b 100644
--- a/lib/eal/freebsd/eal_timer.c
+++ b/lib/eal/freebsd/eal_timer.c
@@ -65,6 +65,5 @@ get_tsc_freq(uint64_t arch_hz)
int
rte_eal_timer_init(void)
{
- set_tsc_freq();
- return 0;
+ return set_tsc_freq();
}
diff --git a/lib/eal/include/generic/rte_cycles.h b/lib/eal/include/generic/rte_cycles.h
index 7cfd51f0eb..8e3d8aad91 100644
--- a/lib/eal/include/generic/rte_cycles.h
+++ b/lib/eal/include/generic/rte_cycles.h
@@ -33,8 +33,13 @@ extern enum timer_source eal_timer_source;
/**
* Get the measured frequency of the RDTSC counter
*
+ * The frequency is determined once during rte_eal_init(), which fails if
+ * it cannot be established, so this never returns zero once the EAL is
+ * initialized and the value does not change afterwards. It is therefore
+ * safe to divide by without checking.
+ *
* @return
- * The TSC frequency for this lcore
+ * The TSC frequency for this lcore, always non-zero.
*/
uint64_t
rte_get_tsc_hz(void);
diff --git a/lib/eal/linux/eal_timer.c b/lib/eal/linux/eal_timer.c
index 39f975b6b9..bccff60ff8 100644
--- a/lib/eal/linux/eal_timer.c
+++ b/lib/eal/linux/eal_timer.c
@@ -99,6 +99,5 @@ rte_eal_timer_init(void)
eal_timer_source = EAL_TIMER_TSC;
- set_tsc_freq();
- return 0;
+ return set_tsc_freq();
}
diff --git a/lib/eal/windows/eal_timer.c b/lib/eal/windows/eal_timer.c
index 33cbac6a03..aec8ea854d 100644
--- a/lib/eal/windows/eal_timer.c
+++ b/lib/eal/windows/eal_timer.c
@@ -94,6 +94,5 @@ get_tsc_freq(uint64_t arch_hz)
int
rte_eal_timer_init(void)
{
- set_tsc_freq();
- return 0;
+ return set_tsc_freq();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] eal: fail initialization if TSC frequency is zero
2026-09-27 19:54 [PATCH] eal: fail initialization if TSC frequency is zero Stephen Hemminger
@ 2026-09-27 20:09 ` Stephen Hemminger
2026-09-28 23:15 ` [PATCH v2] " Stephen Hemminger
1 sibling, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2026-09-27 20:09 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson, Dmitry Kozlyuk, Ravi Kerur, Thomas Monjalon
On Sun, 27 Sep 2026 12:54:40 -0700
Stephen Hemminger <stephen@networkplumber.org> wrote:
> + /*
> + * Several get_tsc_freq_arch() implementations return zero when the
> + * frequency cannot be read, and a TSC that does not advance at least
> + * once per second measures as zero. Such a counter cannot be scaled
> + * to a time at all, so fail rather than let callers of
> + * rte_get_tsc_hz() divide by zero.
> + */
> + if (freq == 0) {
> + EAL_LOG(ERR, "TSC frequency could not be determined");
> + return -1;
> + }
> +
Sorry for the AI generated comment here. Will fix in next version.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] eal: fail initialization if TSC frequency is zero
2026-09-27 19:54 [PATCH] eal: fail initialization if TSC frequency is zero Stephen Hemminger
2026-09-27 20:09 ` Stephen Hemminger
@ 2026-09-28 23:15 ` Stephen Hemminger
2026-09-29 8:39 ` Bruce Richardson
2026-09-29 14:13 ` [PATCH v3] " Stephen Hemminger
1 sibling, 2 replies; 8+ messages in thread
From: Stephen Hemminger @ 2026-09-28 23:15 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, Bruce Richardson, Dmitry Kozlyuk,
Thomas Monjalon, Ravi Kerur
Many parts of DPDK will fail with divide by zero and
other errors if the initialization logic ever TSC hz was ever
determined to be zero. This might happen on a broken get_tsc_freq_arch()
or bad emulation in QEMU.
If TSC hz is zero, log the error and propagate back to
fail rte_eal_init().
This fix doesn't need to go to stable since it is a purely
theoretical problem; we aren't getting divide by zero reports
from users.
Fixes: 040cf8a41187 ("eal: deduplicate timer functions")
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
v2 - cleanups: mostly squash useless comments
lib/eal/common/eal_common_timer.c | 19 ++++++++++++++++---
lib/eal/common/eal_private.h | 2 +-
lib/eal/freebsd/eal_timer.c | 3 +--
lib/eal/include/generic/rte_cycles.h | 2 +-
lib/eal/linux/eal_timer.c | 3 +--
lib/eal/windows/eal_timer.c | 3 +--
6 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/lib/eal/common/eal_common_timer.c b/lib/eal/common/eal_common_timer.c
index bbf8b8b11b..e9f8b56b59 100644
--- a/lib/eal/common/eal_common_timer.c
+++ b/lib/eal/common/eal_common_timer.c
@@ -52,7 +52,7 @@ estimate_tsc_freq(void)
return RTE_ALIGN_MUL_NEAR(rte_rdtsc() - start, CYC_PER_10MHZ);
}
-void
+int
set_tsc_freq(void)
{
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
@@ -65,18 +65,31 @@ set_tsc_freq(void)
* systems where arch-specific frequency detection is not
* available.
*/
+ if (mcfg->tsc_hz == 0) {
+ EAL_LOG(ERR, "Primary process TSC frequency is zero");
+ return -1;
+ }
+
eal_tsc_resolution_hz = mcfg->tsc_hz;
- return;
+ return 0;
}
freq = get_tsc_freq_arch();
freq = get_tsc_freq(freq);
- if (!freq)
+ if (freq == 0) {
freq = estimate_tsc_freq();
+ /* Check if TSC is not moving */
+ if (freq == 0) {
+ EAL_LOG(ERR, "TSC frequency is not changing");
+ return -1;
+ }
+ }
+
EAL_LOG(DEBUG, "TSC frequency is ~%" PRIu64 " KHz", freq / 1000);
eal_tsc_resolution_hz = freq;
mcfg->tsc_hz = freq;
+ return 0;
}
RTE_EXPORT_SYMBOL(rte_delay_us_callback_register)
diff --git a/lib/eal/common/eal_private.h b/lib/eal/common/eal_private.h
index 6340bab8be..952cb5a03e 100644
--- a/lib/eal/common/eal_private.h
+++ b/lib/eal/common/eal_private.h
@@ -409,7 +409,7 @@ int eal_cpu_detected(unsigned lcore_id);
*
* This function is private to the EAL.
*/
-void set_tsc_freq(void);
+int set_tsc_freq(void);
/**
* Get precise TSC frequency from system
diff --git a/lib/eal/freebsd/eal_timer.c b/lib/eal/freebsd/eal_timer.c
index d21ffa2694..84127d876b 100644
--- a/lib/eal/freebsd/eal_timer.c
+++ b/lib/eal/freebsd/eal_timer.c
@@ -65,6 +65,5 @@ get_tsc_freq(uint64_t arch_hz)
int
rte_eal_timer_init(void)
{
- set_tsc_freq();
- return 0;
+ return set_tsc_freq();
}
diff --git a/lib/eal/include/generic/rte_cycles.h b/lib/eal/include/generic/rte_cycles.h
index 7cfd51f0eb..f8e1cde332 100644
--- a/lib/eal/include/generic/rte_cycles.h
+++ b/lib/eal/include/generic/rte_cycles.h
@@ -34,7 +34,7 @@ extern enum timer_source eal_timer_source;
* Get the measured frequency of the RDTSC counter
*
* @return
- * The TSC frequency for this lcore
+ * The TSC frequency for all lcores, always non-zero
*/
uint64_t
rte_get_tsc_hz(void);
diff --git a/lib/eal/linux/eal_timer.c b/lib/eal/linux/eal_timer.c
index 39f975b6b9..bccff60ff8 100644
--- a/lib/eal/linux/eal_timer.c
+++ b/lib/eal/linux/eal_timer.c
@@ -99,6 +99,5 @@ rte_eal_timer_init(void)
eal_timer_source = EAL_TIMER_TSC;
- set_tsc_freq();
- return 0;
+ return set_tsc_freq();
}
diff --git a/lib/eal/windows/eal_timer.c b/lib/eal/windows/eal_timer.c
index 33cbac6a03..aec8ea854d 100644
--- a/lib/eal/windows/eal_timer.c
+++ b/lib/eal/windows/eal_timer.c
@@ -94,6 +94,5 @@ get_tsc_freq(uint64_t arch_hz)
int
rte_eal_timer_init(void)
{
- set_tsc_freq();
- return 0;
+ return set_tsc_freq();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] eal: fail initialization if TSC frequency is zero
2026-09-28 23:15 ` [PATCH v2] " Stephen Hemminger
@ 2026-09-29 8:39 ` Bruce Richardson
2026-09-29 13:42 ` Stephen Hemminger
2026-09-29 14:13 ` [PATCH v3] " Stephen Hemminger
1 sibling, 1 reply; 8+ messages in thread
From: Bruce Richardson @ 2026-09-29 8:39 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, Dmitry Kozlyuk, Thomas Monjalon, Ravi Kerur
On Mon, Sep 28, 2026 at 04:15:58PM -0700, Stephen Hemminger wrote:
> Many parts of DPDK will fail with divide by zero and
> other errors if the initialization logic ever TSC hz was ever
> determined to be zero. This might happen on a broken get_tsc_freq_arch()
> or bad emulation in QEMU.
>
> If TSC hz is zero, log the error and propagate back to
> fail rte_eal_init().
>
> This fix doesn't need to go to stable since it is a purely
> theoretical problem; we aren't getting divide by zero reports
> from users.
>
How was this discovered? Is there a coverity issue id, or was it just AI
discovered?
> Fixes: 040cf8a41187 ("eal: deduplicate timer functions")
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> v2 - cleanups: mostly squash useless comments
>
Code looks generally ok to me.
> lib/eal/common/eal_common_timer.c | 19 ++++++++++++++++---
> lib/eal/common/eal_private.h | 2 +-
> lib/eal/freebsd/eal_timer.c | 3 +--
> lib/eal/include/generic/rte_cycles.h | 2 +-
> lib/eal/linux/eal_timer.c | 3 +--
> lib/eal/windows/eal_timer.c | 3 +--
> 6 files changed, 21 insertions(+), 11 deletions(-)
>
> diff --git a/lib/eal/common/eal_common_timer.c b/lib/eal/common/eal_common_timer.c
> index bbf8b8b11b..e9f8b56b59 100644
> --- a/lib/eal/common/eal_common_timer.c
> +++ b/lib/eal/common/eal_common_timer.c
> @@ -52,7 +52,7 @@ estimate_tsc_freq(void)
> return RTE_ALIGN_MUL_NEAR(rte_rdtsc() - start, CYC_PER_10MHZ);
> }
>
> -void
> +int
> set_tsc_freq(void)
> {
> struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
> @@ -65,18 +65,31 @@ set_tsc_freq(void)
> * systems where arch-specific frequency detection is not
> * available.
> */
> + if (mcfg->tsc_hz == 0) {
> + EAL_LOG(ERR, "Primary process TSC frequency is zero");
> + return -1;
> + }
> +
> eal_tsc_resolution_hz = mcfg->tsc_hz;
> - return;
> + return 0;
> }
>
> freq = get_tsc_freq_arch();
> freq = get_tsc_freq(freq);
> - if (!freq)
> + if (freq == 0) {
> freq = estimate_tsc_freq();
>
> + /* Check if TSC is not moving */
> + if (freq == 0) {
> + EAL_LOG(ERR, "TSC frequency is not changing");
> + return -1;
> + }
> + }
> +
> EAL_LOG(DEBUG, "TSC frequency is ~%" PRIu64 " KHz", freq / 1000);
> eal_tsc_resolution_hz = freq;
> mcfg->tsc_hz = freq;
> + return 0;
> }
>
> RTE_EXPORT_SYMBOL(rte_delay_us_callback_register)
> diff --git a/lib/eal/common/eal_private.h b/lib/eal/common/eal_private.h
> index 6340bab8be..952cb5a03e 100644
> --- a/lib/eal/common/eal_private.h
> +++ b/lib/eal/common/eal_private.h
> @@ -409,7 +409,7 @@ int eal_cpu_detected(unsigned lcore_id);
> *
> * This function is private to the EAL.
> */
> -void set_tsc_freq(void);
> +int set_tsc_freq(void);
>
One minor suggestion: set_tsc_freq name implies that the user passes in a
value to be set. I wonder if "init_tsc_freq" might be a better name here,
since you are updating all calls anyway to handle an error return.
> /**
> * Get precise TSC frequency from system
> diff --git a/lib/eal/freebsd/eal_timer.c b/lib/eal/freebsd/eal_timer.c
> index d21ffa2694..84127d876b 100644
> --- a/lib/eal/freebsd/eal_timer.c
> +++ b/lib/eal/freebsd/eal_timer.c
> @@ -65,6 +65,5 @@ get_tsc_freq(uint64_t arch_hz)
> int
> rte_eal_timer_init(void)
> {
> - set_tsc_freq();
> - return 0;
> + return set_tsc_freq();
> }
> diff --git a/lib/eal/include/generic/rte_cycles.h b/lib/eal/include/generic/rte_cycles.h
> index 7cfd51f0eb..f8e1cde332 100644
> --- a/lib/eal/include/generic/rte_cycles.h
> +++ b/lib/eal/include/generic/rte_cycles.h
> @@ -34,7 +34,7 @@ extern enum timer_source eal_timer_source;
> * Get the measured frequency of the RDTSC counter
> *
> * @return
> - * The TSC frequency for this lcore
> + * The TSC frequency for all lcores, always non-zero
> */
> uint64_t
> rte_get_tsc_hz(void);
> diff --git a/lib/eal/linux/eal_timer.c b/lib/eal/linux/eal_timer.c
> index 39f975b6b9..bccff60ff8 100644
> --- a/lib/eal/linux/eal_timer.c
> +++ b/lib/eal/linux/eal_timer.c
> @@ -99,6 +99,5 @@ rte_eal_timer_init(void)
>
> eal_timer_source = EAL_TIMER_TSC;
>
> - set_tsc_freq();
> - return 0;
> + return set_tsc_freq();
> }
> diff --git a/lib/eal/windows/eal_timer.c b/lib/eal/windows/eal_timer.c
> index 33cbac6a03..aec8ea854d 100644
> --- a/lib/eal/windows/eal_timer.c
> +++ b/lib/eal/windows/eal_timer.c
> @@ -94,6 +94,5 @@ get_tsc_freq(uint64_t arch_hz)
> int
> rte_eal_timer_init(void)
> {
> - set_tsc_freq();
> - return 0;
> + return set_tsc_freq();
> }
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] eal: fail initialization if TSC frequency is zero
2026-09-29 8:39 ` Bruce Richardson
@ 2026-09-29 13:42 ` Stephen Hemminger
2026-09-29 13:57 ` Bruce Richardson
0 siblings, 1 reply; 8+ messages in thread
From: Stephen Hemminger @ 2026-09-29 13:42 UTC (permalink / raw)
To: Bruce Richardson; +Cc: dev, Dmitry Kozlyuk, Thomas Monjalon, Ravi Kerur
On Tue, 29 Sep 2026 09:39:36 +0100
Bruce Richardson <bruce.richardson@intel.com> wrote:
> On Mon, Sep 28, 2026 at 04:15:58PM -0700, Stephen Hemminger wrote:
> > Many parts of DPDK will fail with divide by zero and
> > other errors if the initialization logic ever TSC hz was ever
> > determined to be zero. This might happen on a broken get_tsc_freq_arch()
> > or bad emulation in QEMU.
> >
> > If TSC hz is zero, log the error and propagate back to
> > fail rte_eal_init().
> >
> > This fix doesn't need to go to stable since it is a purely
> > theoretical problem; we aren't getting divide by zero reports
> > from users.
> >
>
> How was this discovered? Is there a coverity issue id, or was it just AI
> discovered?
It was part of review of pcapng timestamp calculation.
Kind of funny, AI spotted overflow (which I verified) in the code which
it had previously helped write. Then it was asking it self,
"what if TSC was 0". I didn't see how this could happen unless QEMU
had some broken CPU emulation.
To me it seemed best to fail fast and die in a safer manner.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] eal: fail initialization if TSC frequency is zero
2026-09-29 13:42 ` Stephen Hemminger
@ 2026-09-29 13:57 ` Bruce Richardson
2026-09-29 14:10 ` Stephen Hemminger
0 siblings, 1 reply; 8+ messages in thread
From: Bruce Richardson @ 2026-09-29 13:57 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, Dmitry Kozlyuk, Thomas Monjalon, Ravi Kerur
On Tue, Sep 29, 2026 at 06:42:08AM -0700, Stephen Hemminger wrote:
> On Tue, 29 Sep 2026 09:39:36 +0100
> Bruce Richardson <bruce.richardson@intel.com> wrote:
>
> > On Mon, Sep 28, 2026 at 04:15:58PM -0700, Stephen Hemminger wrote:
> > > Many parts of DPDK will fail with divide by zero and
> > > other errors if the initialization logic ever TSC hz was ever
> > > determined to be zero. This might happen on a broken get_tsc_freq_arch()
> > > or bad emulation in QEMU.
> > >
> > > If TSC hz is zero, log the error and propagate back to
> > > fail rte_eal_init().
> > >
> > > This fix doesn't need to go to stable since it is a purely
> > > theoretical problem; we aren't getting divide by zero reports
> > > from users.
> > >
> >
> > How was this discovered? Is there a coverity issue id, or was it just AI
> > discovered?
>
> It was part of review of pcapng timestamp calculation.
> Kind of funny, AI spotted overflow (which I verified) in the code which
> it had previously helped write. Then it was asking it self,
> "what if TSC was 0". I didn't see how this could happen unless QEMU
> had some broken CPU emulation.
>
> To me it seemed best to fail fast and die in a safer manner.
>
Agreed. You can add my ack, either for this version or a new version with
the "set" function renamed as I suggest.
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] eal: fail initialization if TSC frequency is zero
2026-09-29 13:57 ` Bruce Richardson
@ 2026-09-29 14:10 ` Stephen Hemminger
0 siblings, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2026-09-29 14:10 UTC (permalink / raw)
To: Bruce Richardson; +Cc: dev, Dmitry Kozlyuk, Thomas Monjalon, Ravi Kerur
On Tue, 29 Sep 2026 14:57:54 +0100
Bruce Richardson <bruce.richardson@intel.com> wrote:
> On Tue, Sep 29, 2026 at 06:42:08AM -0700, Stephen Hemminger wrote:
> > On Tue, 29 Sep 2026 09:39:36 +0100
> > Bruce Richardson <bruce.richardson@intel.com> wrote:
> >
> > > On Mon, Sep 28, 2026 at 04:15:58PM -0700, Stephen Hemminger wrote:
> > > > Many parts of DPDK will fail with divide by zero and
> > > > other errors if the initialization logic ever TSC hz was ever
> > > > determined to be zero. This might happen on a broken get_tsc_freq_arch()
> > > > or bad emulation in QEMU.
> > > >
> > > > If TSC hz is zero, log the error and propagate back to
> > > > fail rte_eal_init().
> > > >
> > > > This fix doesn't need to go to stable since it is a purely
> > > > theoretical problem; we aren't getting divide by zero reports
> > > > from users.
> > > >
> > >
> > > How was this discovered? Is there a coverity issue id, or was it just AI
> > > discovered?
> >
> > It was part of review of pcapng timestamp calculation.
> > Kind of funny, AI spotted overflow (which I verified) in the code which
> > it had previously helped write. Then it was asking it self,
> > "what if TSC was 0". I didn't see how this could happen unless QEMU
> > had some broken CPU emulation.
> >
> > To me it seemed best to fail fast and die in a safer manner.
> >
> Agreed. You can add my ack, either for this version or a new version with
> the "set" function renamed as I suggest.
>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
>
I also updated comment to rte_get_tsc_hz() since existing
comment implies the value could be different on each lcore.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v3] eal: fail initialization if TSC frequency is zero
2026-09-28 23:15 ` [PATCH v2] " Stephen Hemminger
2026-09-29 8:39 ` Bruce Richardson
@ 2026-09-29 14:13 ` Stephen Hemminger
1 sibling, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2026-09-29 14:13 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, Bruce Richardson, Dmitry Kozlyuk, Ravi Kerur,
Thomas Monjalon
Many parts of DPDK will fail with divide by zero and
other errors if the initialization logic ever TSC hz was ever
determined to be zero. This might happen on a broken get_tsc_freq_arch()
or bad emulation in QEMU.
If TSC hz is zero, log the error and propagate back to
fail rte_eal_init().
This fix doesn't need to go to stable since it is a purely
theoretical problem; we aren't getting divide by zero reports
from users.
Also, clarify that DPDK TSC is stable and the same for all lcore's.
The comment in rte_cycles.h implied that it could be different per lcore.
Fixes: 040cf8a41187 ("eal: deduplicate timer functions")
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
v3 - rename set_tsc_freq to init_tsc_freq
lib/eal/common/eal_common_timer.c | 19 +++++++++++++++----
lib/eal/common/eal_private.h | 2 +-
lib/eal/freebsd/eal_timer.c | 3 +--
lib/eal/include/generic/rte_cycles.h | 2 +-
lib/eal/linux/eal_timer.c | 3 +--
lib/eal/windows/eal_timer.c | 3 +--
6 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/lib/eal/common/eal_common_timer.c b/lib/eal/common/eal_common_timer.c
index bbf8b8b11b..67ede70c62 100644
--- a/lib/eal/common/eal_common_timer.c
+++ b/lib/eal/common/eal_common_timer.c
@@ -52,8 +52,8 @@ estimate_tsc_freq(void)
return RTE_ALIGN_MUL_NEAR(rte_rdtsc() - start, CYC_PER_10MHZ);
}
-void
-set_tsc_freq(void)
+int
+init_tsc_freq(void)
{
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
uint64_t freq;
@@ -65,18 +65,29 @@ set_tsc_freq(void)
* systems where arch-specific frequency detection is not
* available.
*/
+ if (mcfg->tsc_hz == 0) {
+ EAL_LOG(ERR, "Primary process TSC frequency is zero");
+ return -1;
+ }
+
eal_tsc_resolution_hz = mcfg->tsc_hz;
- return;
+ return 0;
}
freq = get_tsc_freq_arch();
freq = get_tsc_freq(freq);
- if (!freq)
+ if (freq == 0) {
freq = estimate_tsc_freq();
+ if (freq == 0) {
+ EAL_LOG(ERR, "TSC frequency is too slow");
+ return -1;
+ }
+ }
EAL_LOG(DEBUG, "TSC frequency is ~%" PRIu64 " KHz", freq / 1000);
eal_tsc_resolution_hz = freq;
mcfg->tsc_hz = freq;
+ return 0;
}
RTE_EXPORT_SYMBOL(rte_delay_us_callback_register)
diff --git a/lib/eal/common/eal_private.h b/lib/eal/common/eal_private.h
index 6340bab8be..7da3783c9e 100644
--- a/lib/eal/common/eal_private.h
+++ b/lib/eal/common/eal_private.h
@@ -409,7 +409,7 @@ int eal_cpu_detected(unsigned lcore_id);
*
* This function is private to the EAL.
*/
-void set_tsc_freq(void);
+int init_tsc_freq(void);
/**
* Get precise TSC frequency from system
diff --git a/lib/eal/freebsd/eal_timer.c b/lib/eal/freebsd/eal_timer.c
index d21ffa2694..b966c30258 100644
--- a/lib/eal/freebsd/eal_timer.c
+++ b/lib/eal/freebsd/eal_timer.c
@@ -65,6 +65,5 @@ get_tsc_freq(uint64_t arch_hz)
int
rte_eal_timer_init(void)
{
- set_tsc_freq();
- return 0;
+ return init_tsc_freq();
}
diff --git a/lib/eal/include/generic/rte_cycles.h b/lib/eal/include/generic/rte_cycles.h
index 7cfd51f0eb..f8e1cde332 100644
--- a/lib/eal/include/generic/rte_cycles.h
+++ b/lib/eal/include/generic/rte_cycles.h
@@ -34,7 +34,7 @@ extern enum timer_source eal_timer_source;
* Get the measured frequency of the RDTSC counter
*
* @return
- * The TSC frequency for this lcore
+ * The TSC frequency for all lcores, always non-zero
*/
uint64_t
rte_get_tsc_hz(void);
diff --git a/lib/eal/linux/eal_timer.c b/lib/eal/linux/eal_timer.c
index 39f975b6b9..c425ea4ed8 100644
--- a/lib/eal/linux/eal_timer.c
+++ b/lib/eal/linux/eal_timer.c
@@ -99,6 +99,5 @@ rte_eal_timer_init(void)
eal_timer_source = EAL_TIMER_TSC;
- set_tsc_freq();
- return 0;
+ return init_tsc_freq();
}
diff --git a/lib/eal/windows/eal_timer.c b/lib/eal/windows/eal_timer.c
index 33cbac6a03..1e381ad673 100644
--- a/lib/eal/windows/eal_timer.c
+++ b/lib/eal/windows/eal_timer.c
@@ -94,6 +94,5 @@ get_tsc_freq(uint64_t arch_hz)
int
rte_eal_timer_init(void)
{
- set_tsc_freq();
- return 0;
+ return init_tsc_freq();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-29 14:14 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-27 19:54 [PATCH] eal: fail initialization if TSC frequency is zero Stephen Hemminger
2026-09-27 20:09 ` Stephen Hemminger
2026-09-28 23:15 ` [PATCH v2] " Stephen Hemminger
2026-09-29 8:39 ` Bruce Richardson
2026-09-29 13:42 ` Stephen Hemminger
2026-09-29 13:57 ` Bruce Richardson
2026-09-29 14:10 ` Stephen Hemminger
2026-09-29 14:13 ` [PATCH v3] " Stephen Hemminger
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).