* [patch 06/38] calibrate: Rework delay timer calibration
From: Thomas Gleixner @ 2026-04-10 12:18 UTC (permalink / raw)
To: LKML
Cc: Arnd Bergmann, x86, Lu Baolu, iommu, Michael Grzeschik, netdev,
linux-wireless, Herbert Xu, linux-crypto, Vlastimil Babka,
linux-mm, David Woodhouse, Bernie Thompson, linux-fbdev,
Theodore Tso, linux-ext4, Andrew Morton, Uladzislau Rezki,
Marco Elver, Dmitry Vyukov, kasan-dev, Andrey Ryabinin,
Thomas Sailer, linux-hams, Jason A. Donenfeld, Richard Henderson,
linux-alpha, Russell King, linux-arm-kernel, Catalin Marinas,
Huacai Chen, loongarch, Geert Uytterhoeven, linux-m68k,
Dinh Nguyen, Jonas Bonn, linux-openrisc, Helge Deller,
linux-parisc, Michael Ellerman, linuxppc-dev, Paul Walmsley,
linux-riscv, Heiko Carstens, linux-s390, David S. Miller,
sparclinux
In-Reply-To: <20260410120044.031381086@kernel.org>
The header define in asm/timex,h and the naming of the function to read the
delay timer are confusing at best.
Convert it to a config switch selected by the archictures, which provide
the functionality, and rename the function to delay_read_timer(), which
makes the purpose clear. Move the declaration to linux/delay.h where it
belongs.
Remove the resulting empty asm/timex.h files as well.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/Kconfig | 3 +++
arch/arm/Kconfig | 1 +
arch/arm/include/asm/delay.h | 1 -
arch/arm/include/asm/timex.h | 5 ++++-
arch/arm/lib/delay.c | 10 ++++------
arch/hexagon/Kconfig | 1 +
arch/hexagon/include/asm/timex.h | 20 --------------------
arch/hexagon/kernel/time.c | 8 +++++++-
arch/openrisc/Kconfig | 1 +
arch/openrisc/include/asm/timex.h | 2 --
arch/openrisc/lib/delay.c | 9 ++++-----
arch/riscv/Kconfig | 1 +
arch/riscv/include/asm/timex.h | 8 --------
arch/riscv/lib/delay.c | 7 ++++++-
arch/sparc/Kconfig | 1 +
arch/sparc/include/asm/timex_64.h | 2 --
arch/sparc/kernel/time_64.c | 4 ++--
arch/x86/Kconfig | 1 +
arch/x86/include/asm/timex.h | 2 --
arch/x86/lib/delay.c | 8 +++-----
include/asm-generic/timex.h | 7 -------
include/linux/delay.h | 2 ++
include/linux/timex.h | 2 --
init/calibrate.c | 19 +++++++++----------
24 files changed, 50 insertions(+), 75 deletions(-)
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -363,6 +363,9 @@ config ARCH_HAS_DMA_CLEAR_UNCACHED
config ARCH_HAS_CPU_FINALIZE_INIT
bool
+config ARCH_HAS_DELAY_TIMER
+ bool
+
# The architecture has a per-task state that includes the mm's PASID
config ARCH_HAS_CPU_PASID
bool
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -11,6 +11,7 @@ config ARM
select ARCH_HAS_CPU_FINALIZE_INIT if MMU
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL if MMU
+ select ARCH_HAS_DELAY_TIMER
select ARCH_HAS_DMA_ALLOC if MMU
select ARCH_HAS_DMA_OPS
select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
--- a/arch/arm/include/asm/delay.h
+++ b/arch/arm/include/asm/delay.h
@@ -91,7 +91,6 @@ extern void __loop_udelay(unsigned long
extern void __loop_const_udelay(unsigned long);
/* Delay-loop timer registration. */
-#define ARCH_HAS_READ_CURRENT_TIMER
extern void register_current_timer_delay(const struct delay_timer *timer);
#endif /* __ASSEMBLY__ */
--- a/arch/arm/include/asm/timex.h
+++ b/arch/arm/include/asm/timex.h
@@ -10,7 +10,10 @@
#define _ASMARM_TIMEX_H
typedef unsigned long cycles_t;
-#define get_cycles() ({ cycles_t c; read_current_timer(&c) ? 0 : c; })
+// Temporary workaround
+bool delay_read_timer(unsigned long *t);
+
+#define get_cycles() ({ cycles_t c; delay_read_timer(&c) ? 0 : c; })
#define random_get_entropy() (((unsigned long)get_cycles()) ?: random_get_entropy_fallback())
#endif
--- a/arch/arm/lib/delay.c
+++ b/arch/arm/lib/delay.c
@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/timex.h>
/*
* Default to the loop-based delay implementation.
@@ -27,15 +26,14 @@ static const struct delay_timer *delay_t
static bool delay_calibrated;
static u64 delay_res;
-int read_current_timer(unsigned long *timer_val)
+bool delay_read_timer(unsigned long *timer_val)
{
if (!delay_timer)
- return -ENXIO;
-
+ return false;
*timer_val = delay_timer->read_current_timer();
- return 0;
+ return true;
}
-EXPORT_SYMBOL_GPL(read_current_timer);
+EXPORT_SYMBOL_GPL(delay_read_timer);
static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
{
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -5,6 +5,7 @@ comment "Linux Kernel Configuration for
config HEXAGON
def_bool y
select ARCH_32BIT_OFF_T
+ select ARCH_HAS_DELAY_TIMER
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_NO_PREEMPT
select ARCH_WANT_FRAME_POINTERS
--- a/arch/hexagon/include/asm/timex.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- */
-
-#ifndef _ASM_TIMEX_H
-#define _ASM_TIMEX_H
-
-#include <asm-generic/timex.h>
-#include <asm/hexagon_vm.h>
-
-#define ARCH_HAS_READ_CURRENT_TIMER
-
-static inline int read_current_timer(unsigned long *timer_val)
-{
- *timer_val = __vmgettime();
- return 0;
-}
-
-#endif
--- a/arch/hexagon/kernel/time.c
+++ b/arch/hexagon/kernel/time.c
@@ -6,6 +6,7 @@
*/
#include <linux/init.h>
+#include <linux/delay.h>
#include <linux/clockchips.h>
#include <linux/clocksource.h>
#include <linux/interrupt.h>
@@ -17,7 +18,6 @@
#include <linux/of_irq.h>
#include <linux/module.h>
-#include <asm/delay.h>
#include <asm/hexagon_vm.h>
#include <asm/time.h>
@@ -231,3 +231,9 @@ void __udelay(unsigned long usecs)
cpu_relax(); /* not sure how this improves readability */
}
EXPORT_SYMBOL(__udelay);
+
+bool delay_read_timer(unsigned long *timer_val)
+{
+ *timer_val = __vmgettime();
+ return true;
+}
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -7,6 +7,7 @@
config OPENRISC
def_bool y
select ARCH_32BIT_OFF_T
+ select ARCH_HAS_DELAY_TIMER
select ARCH_HAS_DMA_SET_UNCACHED
select ARCH_HAS_DMA_CLEAR_UNCACHED
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
--- a/arch/openrisc/include/asm/timex.h
+++ b/arch/openrisc/include/asm/timex.h
@@ -25,6 +25,4 @@ static inline cycles_t get_cycles(void)
}
#define get_cycles get_cycles
-#define ARCH_HAS_READ_CURRENT_TIMER
-
#endif
--- a/arch/openrisc/lib/delay.c
+++ b/arch/openrisc/lib/delay.c
@@ -13,18 +13,17 @@
*/
#include <linux/kernel.h>
+#include <linux/delay.h>
#include <linux/export.h>
#include <linux/init.h>
-#include <linux/timex.h>
+
#include <asm/param.h>
-#include <asm/delay.h>
-#include <asm/timex.h>
#include <asm/processor.h>
-int read_current_timer(unsigned long *timer_value)
+bool delay_read_timer(unsigned long *timer_value)
{
*timer_value = get_cycles();
- return 0;
+ return true;
}
void __delay(unsigned long cycles)
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -29,6 +29,7 @@ config RISCV
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEBUG_WX
+ select ARCH_HAS_DELAY_TIMER
select ARCH_HAS_ELF_CORE_EFLAGS if BINFMT_ELF && ELF_CORE
select ARCH_HAS_FAST_MULTIPLIER
select ARCH_HAS_FORTIFY_SOURCE
--- a/arch/riscv/include/asm/timex.h
+++ b/arch/riscv/include/asm/timex.h
@@ -80,12 +80,4 @@ static inline u64 get_cycles64(void)
return ((u64)hi << 32) | lo;
}
#endif /* CONFIG_64BIT */
-
-#define ARCH_HAS_READ_CURRENT_TIMER
-static inline int read_current_timer(unsigned long *timer_val)
-{
- *timer_val = get_cycles();
- return 0;
-}
-
#endif /* _ASM_RISCV_TIMEX_H */
--- a/arch/riscv/lib/delay.c
+++ b/arch/riscv/lib/delay.c
@@ -6,7 +6,6 @@
#include <linux/delay.h>
#include <linux/math.h>
#include <linux/param.h>
-#include <linux/timex.h>
#include <linux/types.h>
#include <linux/export.h>
@@ -109,3 +108,9 @@ void ndelay(unsigned long nsecs)
__delay(ncycles >> NDELAY_SHIFT);
}
EXPORT_SYMBOL(ndelay);
+
+bool delay_read_timer(unsigned long *timer_val)
+{
+ *timer_val = get_cycles();
+ return true;
+}
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -70,6 +70,7 @@ config SPARC32
config SPARC64
def_bool 64BIT
select ALTERNATE_USER_ADDRESS_SPACE
+ select ARCH_HAS_DELAY_TIMER
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_KRETPROBES
--- a/arch/sparc/include/asm/timex_64.h
+++ b/arch/sparc/include/asm/timex_64.h
@@ -13,6 +13,4 @@
typedef unsigned long cycles_t;
#define get_cycles() tick_ops->get_tick()
-#define ARCH_HAS_READ_CURRENT_TIMER
-
#endif
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -894,8 +894,8 @@ unsigned long long sched_clock(void)
return ((get_tick() * quotient) >> SPARC64_NSEC_PER_CYC_SHIFT) - offset;
}
-int read_current_timer(unsigned long *timer_val)
+bool delay_read_timer(unsigned long *timer_val)
{
*timer_val = get_tick();
- return 0;
+ return true;
}
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -81,6 +81,7 @@ config X86
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEBUG_VM_PGTABLE if !X86_PAE
+ select ARCH_HAS_DELAY_TIMER
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_OPS if GART_IOMMU || XEN
select ARCH_HAS_EARLY_DEBUG if KGDB
--- a/arch/x86/include/asm/timex.h
+++ b/arch/x86/include/asm/timex.h
@@ -14,6 +14,4 @@ static inline unsigned long random_get_e
}
#define random_get_entropy random_get_entropy
-#define ARCH_HAS_READ_CURRENT_TIMER
-
#endif /* _ASM_X86_TIMEX_H */
--- a/arch/x86/lib/delay.c
+++ b/arch/x86/lib/delay.c
@@ -14,12 +14,10 @@
#include <linux/export.h>
#include <linux/sched.h>
-#include <linux/timex.h>
#include <linux/preempt.h>
#include <linux/delay.h>
#include <asm/processor.h>
-#include <asm/delay.h>
#include <asm/timer.h>
#include <asm/mwait.h>
@@ -189,13 +187,13 @@ void use_mwaitx_delay(void)
delay_fn = delay_halt;
}
-int read_current_timer(unsigned long *timer_val)
+bool delay_read_timer(unsigned long *timer_val)
{
if (delay_fn == delay_tsc) {
*timer_val = rdtsc();
- return 0;
+ return true;
}
- return -1;
+ return false;
}
void __delay(unsigned long loops)
--- a/include/asm-generic/timex.h
+++ b/include/asm-generic/timex.h
@@ -13,11 +13,4 @@ static inline cycles_t get_cycles(void)
}
#endif
-/*
- * Architectures are encouraged to implement read_current_timer
- * and define this in order to avoid the expensive delay loop
- * calibration during boot.
- */
-#undef ARCH_HAS_READ_CURRENT_TIMER
-
#endif /* __ASM_GENERIC_TIMEX_H */
--- a/include/linux/delay.h
+++ b/include/linux/delay.h
@@ -17,6 +17,8 @@ extern unsigned long loops_per_jiffy;
#include <asm/delay.h>
+bool delay_read_timer(unsigned long *t);
+
/*
* Using udelay() for intervals greater than a few milliseconds can
* risk overflow for high loops_per_jiffy (high bogomips) machines. The
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -156,8 +156,6 @@ extern int do_clock_adjtime(const clocki
extern void hardpps(const struct timespec64 *, const struct timespec64 *);
-int read_current_timer(unsigned long *timer_val);
-
/* The clock frequency of the i8253/i8254 PIT */
#define PIT_TICK_RATE 1193182ul
--- a/init/calibrate.c
+++ b/init/calibrate.c
@@ -13,7 +13,6 @@
#include <linux/printk.h>
#include <linux/smp.h>
#include <linux/stddef.h>
-#include <linux/timex.h>
unsigned long lpj_fine;
unsigned long preset_lpj;
@@ -25,9 +24,9 @@ static int __init lpj_setup(char *str)
__setup("lpj=", lpj_setup);
-#ifdef ARCH_HAS_READ_CURRENT_TIMER
+#ifdef CONFIG_ARCH_HAS_DELAY_TIMER
-/* This routine uses the read_current_timer() routine and gets the
+/* This routine uses the delay_read_timer() routine and gets the
* loops per jiffy directly, instead of guessing it using delay().
* Also, this code tries to handle non-maskable asynchronous events
* (like SMIs)
@@ -48,13 +47,13 @@ static unsigned long calibrate_delay_dir
int min = -1;
int i;
- if (read_current_timer(&pre_start) < 0 )
+ if (!delay_read_timer(&pre_start))
return 0;
/*
* A simple loop like
* while ( jiffies < start_jiffies+1)
- * start = read_current_timer();
+ * start = delay_read_timer();
* will not do. As we don't really know whether jiffy switch
* happened first or timer_value was read first. And some asynchronous
* event can happen between these two events introducing errors in lpj.
@@ -72,22 +71,22 @@ static unsigned long calibrate_delay_dir
for (i = 0; i < MAX_DIRECT_CALIBRATION_RETRIES; i++) {
pre_start = 0;
- read_current_timer(&start);
+ delay_read_timer(&start);
start_jiffies = jiffies;
while (time_before_eq(jiffies, start_jiffies + 1)) {
pre_start = start;
- read_current_timer(&start);
+ delay_read_timer(&start);
}
- read_current_timer(&post_start);
+ delay_read_timer(&post_start);
pre_end = 0;
end = post_start;
while (time_before_eq(jiffies, start_jiffies + 1 +
DELAY_CALIBRATION_TICKS)) {
pre_end = end;
- read_current_timer(&end);
+ delay_read_timer(&end);
}
- read_current_timer(&post_end);
+ delay_read_timer(&post_end);
timer_rate_max = (post_end - pre_start) /
DELAY_CALIBRATION_TICKS;
^ permalink raw reply
* [patch 05/38] treewide: Remove CLOCK_TICK_RATE
From: Thomas Gleixner @ 2026-04-10 12:18 UTC (permalink / raw)
To: LKML
Cc: Arnd Bergmann, x86, Lu Baolu, iommu, Michael Grzeschik, netdev,
linux-wireless, Herbert Xu, linux-crypto, Vlastimil Babka,
linux-mm, David Woodhouse, Bernie Thompson, linux-fbdev,
Theodore Tso, linux-ext4, Andrew Morton, Uladzislau Rezki,
Marco Elver, Dmitry Vyukov, kasan-dev, Andrey Ryabinin,
Thomas Sailer, linux-hams, Jason A. Donenfeld, Richard Henderson,
linux-alpha, Russell King, linux-arm-kernel, Catalin Marinas,
Huacai Chen, loongarch, Geert Uytterhoeven, linux-m68k,
Dinh Nguyen, Jonas Bonn, linux-openrisc, Helge Deller,
linux-parisc, Michael Ellerman, linuxppc-dev, Paul Walmsley,
linux-riscv, Heiko Carstens, linux-s390, David S. Miller,
sparclinux
In-Reply-To: <20260410120044.031381086@kernel.org>
This has been scheduled for removal more than a decade ago and the comments
related to it have been dutifully ignored. The last dependencies are gone.
Remove it along with various now empty asm/timex.h files.
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
---
arch/alpha/include/asm/timex.h | 4 ----
arch/arc/include/asm/timex.h | 15 ---------------
arch/arm/mach-omap1/Kconfig | 2 +-
arch/hexagon/include/asm/timex.h | 3 ---
arch/m68k/include/asm/timex.h | 15 ---------------
arch/microblaze/include/asm/timex.h | 13 -------------
arch/mips/include/asm/timex.h | 8 --------
arch/openrisc/include/asm/timex.h | 3 ---
arch/parisc/include/asm/timex.h | 2 --
arch/powerpc/include/asm/timex.h | 2 --
arch/s390/include/asm/timex.h | 2 --
arch/sh/include/asm/timex.h | 24 ------------------------
arch/sparc/include/asm/timex.h | 2 +-
arch/sparc/include/asm/timex_32.h | 14 --------------
arch/sparc/include/asm/timex_64.h | 2 --
arch/um/include/asm/timex.h | 9 ---------
arch/x86/include/asm/timex.h | 3 ---
17 files changed, 2 insertions(+), 121 deletions(-)
--- a/arch/alpha/include/asm/timex.h
+++ b/arch/alpha/include/asm/timex.h
@@ -7,10 +7,6 @@
#ifndef _ASMALPHA_TIMEX_H
#define _ASMALPHA_TIMEX_H
-/* With only one or two oddballs, we use the RTC as the ticker, selecting
- the 32.768kHz reference clock, which nicely divides down to our HZ. */
-#define CLOCK_TICK_RATE 32768
-
/*
* Standard way to access the cycle counter.
* Currently only used on SMP for scheduling.
--- a/arch/arc/include/asm/timex.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
- */
-
-#ifndef _ASM_ARC_TIMEX_H
-#define _ASM_ARC_TIMEX_H
-
-#define CLOCK_TICK_RATE 80000000 /* slated to be removed */
-
-#include <asm-generic/timex.h>
-
-/* XXX: get_cycles() to be implemented with RTSC insn */
-
-#endif /* _ASM_ARC_TIMEX_H */
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -74,7 +74,7 @@ config OMAP_32K_TIMER
currently only available for OMAP16XX, 24XX, 34XX, OMAP4/5 and DRA7XX.
On OMAP2PLUS this value is only used for CONFIG_HZ and
- CLOCK_TICK_RATE compile time calculation.
+ timer frequency compile time calculation.
The actual timer selection is done in the board file
through the (DT_)MACHINE_START structure.
--- a/arch/hexagon/include/asm/timex.h
+++ b/arch/hexagon/include/asm/timex.h
@@ -9,9 +9,6 @@
#include <asm-generic/timex.h>
#include <asm/hexagon_vm.h>
-/* Using TCX0 as our clock. CLOCK_TICK_RATE scheduled to be removed. */
-#define CLOCK_TICK_RATE 19200
-
#define ARCH_HAS_READ_CURRENT_TIMER
static inline int read_current_timer(unsigned long *timer_val)
--- a/arch/m68k/include/asm/timex.h
+++ b/arch/m68k/include/asm/timex.h
@@ -7,21 +7,6 @@
#ifndef _ASMm68K_TIMEX_H
#define _ASMm68K_TIMEX_H
-#ifdef CONFIG_COLDFIRE
-/*
- * CLOCK_TICK_RATE should give the underlying frequency of the tick timer
- * to make ntp work best. For Coldfires, that's the main clock.
- */
-#include <asm/coldfire.h>
-#define CLOCK_TICK_RATE MCF_CLK
-#else
-/*
- * This default CLOCK_TICK_RATE is probably wrong for many 68k boards
- * Users of those boards will need to check and modify accordingly
- */
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
-#endif
-
typedef unsigned long cycles_t;
static inline cycles_t get_cycles(void)
--- a/arch/microblaze/include/asm/timex.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- */
-
-#ifndef _ASM_MICROBLAZE_TIMEX_H
-#define _ASM_MICROBLAZE_TIMEX_H
-
-#include <asm-generic/timex.h>
-
-#define CLOCK_TICK_RATE 1000 /* Timer input freq. */
-
-#endif /* _ASM_TIMEX_H */
--- a/arch/mips/include/asm/timex.h
+++ b/arch/mips/include/asm/timex.h
@@ -19,14 +19,6 @@
#include <asm/cpu-type.h>
/*
- * This is the clock rate of the i8253 PIT. A MIPS system may not have
- * a PIT by the symbol is used all over the kernel including some APIs.
- * So keeping it defined to the number for the PIT is the only sane thing
- * for now.
- */
-#define CLOCK_TICK_RATE 1193182
-
-/*
* Standard way to access the cycle counter.
* Currently only used on SMP for scheduling.
*
--- a/arch/openrisc/include/asm/timex.h
+++ b/arch/openrisc/include/asm/timex.h
@@ -25,9 +25,6 @@ static inline cycles_t get_cycles(void)
}
#define get_cycles get_cycles
-/* This isn't really used any more */
-#define CLOCK_TICK_RATE 1000
-
#define ARCH_HAS_READ_CURRENT_TIMER
#endif
--- a/arch/parisc/include/asm/timex.h
+++ b/arch/parisc/include/asm/timex.h
@@ -9,8 +9,6 @@
#include <asm/special_insns.h>
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
-
typedef unsigned long cycles_t;
static inline cycles_t get_cycles(void)
--- a/arch/powerpc/include/asm/timex.h
+++ b/arch/powerpc/include/asm/timex.h
@@ -11,8 +11,6 @@
#include <asm/cputable.h>
#include <asm/vdso/timebase.h>
-#define CLOCK_TICK_RATE 1024000 /* Underlying HZ */
-
typedef unsigned long cycles_t;
static inline cycles_t get_cycles(void)
--- a/arch/s390/include/asm/timex.h
+++ b/arch/s390/include/asm/timex.h
@@ -177,8 +177,6 @@ static inline void local_tick_enable(uns
set_clock_comparator(get_lowcore()->clock_comparator);
}
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
-
typedef unsigned long cycles_t;
static __always_inline unsigned long get_tod_clock(void)
--- a/arch/sh/include/asm/timex.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * linux/include/asm-sh/timex.h
- *
- * sh architecture timex specifications
- */
-#ifndef __ASM_SH_TIMEX_H
-#define __ASM_SH_TIMEX_H
-
-/*
- * Only parts using the legacy CPG code for their clock framework
- * implementation need to define their own Pclk value. If provided, this
- * can be used for accurately setting CLOCK_TICK_RATE, otherwise we
- * simply fall back on the i8253 PIT value.
- */
-#ifdef CONFIG_SH_PCLK_FREQ
-#define CLOCK_TICK_RATE (CONFIG_SH_PCLK_FREQ / 4) /* Underlying HZ */
-#else
-#define CLOCK_TICK_RATE 1193180
-#endif
-
-#include <asm-generic/timex.h>
-
-#endif /* __ASM_SH_TIMEX_H */
--- a/arch/sparc/include/asm/timex.h
+++ b/arch/sparc/include/asm/timex.h
@@ -4,6 +4,6 @@
#if defined(__sparc__) && defined(__arch64__)
#include <asm/timex_64.h>
#else
-#include <asm/timex_32.h>
+#include <asm-generic/timex.h>
#endif
#endif
--- a/arch/sparc/include/asm/timex_32.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * linux/include/asm/timex.h
- *
- * sparc architecture timex specifications
- */
-#ifndef _ASMsparc_TIMEX_H
-#define _ASMsparc_TIMEX_H
-
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
-
-#include <asm-generic/timex.h>
-
-#endif
--- a/arch/sparc/include/asm/timex_64.h
+++ b/arch/sparc/include/asm/timex_64.h
@@ -9,8 +9,6 @@
#include <asm/timer.h>
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
-
/* Getting on the cycle counter on sparc64. */
typedef unsigned long cycles_t;
#define get_cycles() tick_ops->get_tick()
--- a/arch/um/include/asm/timex.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __UM_TIMEX_H
-#define __UM_TIMEX_H
-
-#define CLOCK_TICK_RATE (HZ)
-
-#include <asm-generic/timex.h>
-
-#endif
--- a/arch/x86/include/asm/timex.h
+++ b/arch/x86/include/asm/timex.h
@@ -14,9 +14,6 @@ static inline unsigned long random_get_e
}
#define random_get_entropy random_get_entropy
-/* Assume we use the PIT time source for the clock tick */
-#define CLOCK_TICK_RATE PIT_TICK_RATE
-
#define ARCH_HAS_READ_CURRENT_TIMER
#endif /* _ASM_X86_TIMEX_H */
^ permalink raw reply
* [patch 04/38] x86: Use PIT_TICK_RATE instead of CLOCK_TICK_RATE
From: Thomas Gleixner @ 2026-04-10 12:18 UTC (permalink / raw)
To: LKML
Cc: Arnd Bergmann, x86, Lu Baolu, iommu, Michael Grzeschik, netdev,
linux-wireless, Herbert Xu, linux-crypto, Vlastimil Babka,
linux-mm, David Woodhouse, Bernie Thompson, linux-fbdev,
Theodore Tso, linux-ext4, Andrew Morton, Uladzislau Rezki,
Marco Elver, Dmitry Vyukov, kasan-dev, Andrey Ryabinin,
Thomas Sailer, linux-hams, Jason A. Donenfeld, Richard Henderson,
linux-alpha, Russell King, linux-arm-kernel, Catalin Marinas,
Huacai Chen, loongarch, Geert Uytterhoeven, linux-m68k,
Dinh Nguyen, Jonas Bonn, linux-openrisc, Helge Deller,
linux-parisc, Michael Ellerman, linuxppc-dev, Paul Walmsley,
linux-riscv, Heiko Carstens, linux-s390, David S. Miller,
sparclinux
In-Reply-To: <20260410120044.031381086@kernel.org>
CLOCK_TICK_RATE is only used in x86 but defined all over the tree for no
reason with comments that it's scheduled for removal for more than a
decade.
Use PIT_TICK_RATE for registering refined jiffies to get rid of the last
dependency.
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
---
arch/x86/kernel/setup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1268,7 +1268,7 @@ void __init setup_arch(char **cmdline_p)
mcheck_init();
- register_refined_jiffies(CLOCK_TICK_RATE);
+ register_refined_jiffies(PIT_TICK_RATE);
#ifdef CONFIG_EFI
if (efi_enabled(EFI_BOOT))
^ permalink raw reply
* [patch 03/38] x86/apm: Remove last LATCH usage
From: Thomas Gleixner @ 2026-04-10 12:18 UTC (permalink / raw)
To: LKML
Cc: Arnd Bergmann, x86, Lu Baolu, iommu, Michael Grzeschik, netdev,
linux-wireless, Herbert Xu, linux-crypto, Vlastimil Babka,
linux-mm, David Woodhouse, Bernie Thompson, linux-fbdev,
Theodore Tso, linux-ext4, Andrew Morton, Uladzislau Rezki,
Marco Elver, Dmitry Vyukov, kasan-dev, Andrey Ryabinin,
Thomas Sailer, linux-hams, Jason A. Donenfeld, Richard Henderson,
linux-alpha, Russell King, linux-arm-kernel, Catalin Marinas,
Huacai Chen, loongarch, Geert Uytterhoeven, linux-m68k,
Dinh Nguyen, Jonas Bonn, linux-openrisc, Helge Deller,
linux-parisc, Michael Ellerman, linuxppc-dev, Paul Walmsley,
linux-riscv, Heiko Carstens, linux-s390, David S. Miller,
sparclinux
In-Reply-To: <20260410120044.031381086@kernel.org>
LATCH is a historical leftover and has been replaced with PIT_LATCH in all
other places a decade ago. Replace the last holdout and remove the
definition from jiffies.h.
This allows to remove the otherwise unused CLOCK_TICK_RATE define in the
next step.
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
---
arch/x86/kernel/apm_32.c | 4 ++--
include/linux/jiffies.h | 3 ---
2 files changed, 2 insertions(+), 5 deletions(-)
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -1196,9 +1196,9 @@ static void reinit_timer(void)
/* set the clock to HZ */
outb_p(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */
udelay(10);
- outb_p(LATCH & 0xff, PIT_CH0); /* LSB */
+ outb_p(PIT_LATCH & 0xff, PIT_CH0); /* LSB */
udelay(10);
- outb_p(LATCH >> 8, PIT_CH0); /* MSB */
+ outb_p(PIT_LATCH >> 8, PIT_CH0); /* MSB */
udelay(10);
raw_spin_unlock_irqrestore(&i8253_lock, flags);
#endif
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -56,9 +56,6 @@
#define SH_DIV(NOM,DEN,LSH) ( (((NOM) / (DEN)) << (LSH)) \
+ ((((NOM) % (DEN)) << (LSH)) + (DEN) / 2) / (DEN))
-/* LATCH is used in the interval timer and ftape setup. */
-#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
-
extern void register_refined_jiffies(long clock_tick_rate);
/* TICK_USEC is the time between ticks in usec */
^ permalink raw reply
* [patch 02/38] x86: Cleanup include recursion hell
From: Thomas Gleixner @ 2026-04-10 12:18 UTC (permalink / raw)
To: LKML
Cc: Arnd Bergmann, x86, Lu Baolu, iommu, Michael Grzeschik, netdev,
linux-wireless, Herbert Xu, linux-crypto, Vlastimil Babka,
linux-mm, David Woodhouse, Bernie Thompson, linux-fbdev,
Theodore Tso, linux-ext4, Andrew Morton, Uladzislau Rezki,
Marco Elver, Dmitry Vyukov, kasan-dev, Andrey Ryabinin,
Thomas Sailer, linux-hams, Jason A. Donenfeld, Richard Henderson,
linux-alpha, Russell King, linux-arm-kernel, Catalin Marinas,
Huacai Chen, loongarch, Geert Uytterhoeven, linux-m68k,
Dinh Nguyen, Jonas Bonn, linux-openrisc, Helge Deller,
linux-parisc, Michael Ellerman, linuxppc-dev, Paul Walmsley,
linux-riscv, Heiko Carstens, linux-s390, David S. Miller,
sparclinux
In-Reply-To: <20260410120044.031381086@kernel.org>
Including a random architecture specific header which requires global
headers just to avoid including that header at the two usage sites is
really beyond lazy and tasteless. Including global headers just to get the
__percpu macro from linux/compiler_types.h falls into the same category.
Remove the linux/percpu.h and asm/cpumask.h includes from msr.h and smp.h
and fix the resulting fallout by a simple forward struct declaration and by
including the x86 specific asm/cpumask.h header where it is actually
required.
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
---
arch/x86/include/asm/msr.h | 5 +++--
arch/x86/include/asm/pvclock.h | 1 +
arch/x86/include/asm/smp.h | 2 --
arch/x86/include/asm/vdso/gettimeofday.h | 5 ++---
arch/x86/kernel/cpu/mce/core.c | 1 +
arch/x86/kernel/nmi.c | 1 +
arch/x86/kernel/smpboot.c | 1 +
7 files changed, 9 insertions(+), 7 deletions(-)
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -8,12 +8,11 @@
#include <asm/asm.h>
#include <asm/errno.h>
-#include <asm/cpumask.h>
#include <uapi/asm/msr.h>
#include <asm/shared/msr.h>
+#include <linux/compiler_types.h>
#include <linux/types.h>
-#include <linux/percpu.h>
struct msr_info {
u32 msr_no;
@@ -256,6 +255,8 @@ int msr_set_bit(u32 msr, u8 bit);
int msr_clear_bit(u32 msr, u8 bit);
#ifdef CONFIG_SMP
+struct cpumask;
+
int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
int rdmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 *q);
--- a/arch/x86/include/asm/pvclock.h
+++ b/arch/x86/include/asm/pvclock.h
@@ -2,6 +2,7 @@
#ifndef _ASM_X86_PVCLOCK_H
#define _ASM_X86_PVCLOCK_H
+#include <asm/barrier.h>
#include <asm/clocksource.h>
#include <asm/pvclock-abi.h>
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -5,8 +5,6 @@
#include <linux/cpumask.h>
#include <linux/thread_info.h>
-#include <asm/cpumask.h>
-
DECLARE_PER_CPU_CACHE_HOT(int, cpu_number);
DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map);
--- a/arch/x86/include/asm/vdso/gettimeofday.h
+++ b/arch/x86/include/asm/vdso/gettimeofday.h
@@ -11,13 +11,12 @@
#define __ASM_VDSO_GETTIMEOFDAY_H
#ifndef __ASSEMBLER__
-
+#include <clocksource/hyperv_timer.h>
#include <uapi/linux/time.h>
+
#include <asm/vgtod.h>
#include <asm/unistd.h>
-#include <asm/msr.h>
#include <asm/pvclock.h>
-#include <clocksource/hyperv_timer.h>
#include <asm/vdso/sys_call.h>
#define VDSO_HAS_TIME 1
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -48,6 +48,7 @@
#include <linux/vmcore_info.h>
#include <asm/fred.h>
+#include <asm/cpumask.h>
#include <asm/cpu_device_id.h>
#include <asm/processor.h>
#include <asm/traps.h>
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -26,6 +26,7 @@
#include <linux/sched/clock.h>
#include <linux/kvm_types.h>
+#include <asm/cpumask.h>
#include <asm/cpu_entry_area.h>
#include <asm/traps.h>
#include <asm/mach_traps.h>
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -70,6 +70,7 @@
#include <asm/irq.h>
#include <asm/realmode.h>
#include <asm/cpu.h>
+#include <asm/cpumask.h>
#include <asm/numa.h>
#include <asm/tlbflush.h>
#include <asm/mtrr.h>
^ permalink raw reply
* [patch 01/38] percpu: Sanitize __percpu_qual include hell
From: Thomas Gleixner @ 2026-04-10 12:18 UTC (permalink / raw)
To: LKML
Cc: Arnd Bergmann, x86, Lu Baolu, iommu, Michael Grzeschik, netdev,
linux-wireless, Herbert Xu, linux-crypto, Vlastimil Babka,
linux-mm, David Woodhouse, Bernie Thompson, linux-fbdev,
Theodore Tso, linux-ext4, Andrew Morton, Uladzislau Rezki,
Marco Elver, Dmitry Vyukov, kasan-dev, Andrey Ryabinin,
Thomas Sailer, linux-hams, Jason A. Donenfeld, Richard Henderson,
linux-alpha, Russell King, linux-arm-kernel, Catalin Marinas,
Huacai Chen, loongarch, Geert Uytterhoeven, linux-m68k,
Dinh Nguyen, Jonas Bonn, linux-openrisc, Helge Deller,
linux-parisc, Michael Ellerman, linuxppc-dev, Paul Walmsley,
linux-riscv, Heiko Carstens, linux-s390, David S. Miller,
sparclinux
In-Reply-To: <20260410120044.031381086@kernel.org>
Slapping __percpu_qual into the next available header is sloppy at best.
It's required by __percpu which is defined in compiler_types.h and that is
meant to be included without requiring a boatload of other headers so that
a struct or function declaration can contain a __percpu qualifier w/o
further prerequisites.
This implicit dependency on linux/percpu.h makes that impossible and causes
a major problem when trying to seperate headers.
Create asm/percpu_types.h and move it there. Include that from
compiler_types.h and the whole recursion problem goes away.
Signed-off-by: Thomas Gleixner <tglx@kernel.org
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/x86/include/asm/percpu.h | 5 -----
arch/x86/include/asm/percpu_types.h | 17 +++++++++++++++++
include/asm-generic/Kbuild | 1 +
include/asm-generic/percpu_types.h | 20 ++++++++++++++++++++
include/linux/compiler_types.h | 1 +
5 files changed, 39 insertions(+), 5 deletions(-)
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -40,12 +40,10 @@
#endif
#define __percpu_prefix
-#define __percpu_seg_override CONCATENATE(__seg_, __percpu_seg)
#else /* !CONFIG_CC_HAS_NAMED_AS: */
#define __percpu_prefix __force_percpu_prefix
-#define __percpu_seg_override
#endif /* CONFIG_CC_HAS_NAMED_AS */
@@ -82,7 +80,6 @@
#define __force_percpu_prefix
#define __percpu_prefix
-#define __percpu_seg_override
#define PER_CPU_VAR(var) (var)__percpu_rel
@@ -92,8 +89,6 @@
# define __my_cpu_type(var) typeof(var)
# define __my_cpu_ptr(ptr) (ptr)
# define __my_cpu_var(var) (var)
-
-# define __percpu_qual __percpu_seg_override
#else
# define __my_cpu_type(var) typeof(var) __percpu_seg_override
# define __my_cpu_ptr(ptr) (__my_cpu_type(*(ptr))*)(__force uintptr_t)(ptr)
--- /dev/null
+++ b/arch/x86/include/asm/percpu_types.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_PERCPU_TYPES_H
+#define _ASM_X86_PERCPU_TYPES_H
+
+#if defined(CONFIG_SMP) && defined(CONFIG_CC_HAS_NAMED_AS)
+#define __percpu_seg_override CONCATENATE(__seg_, __percpu_seg)
+#else /* !CONFIG_CC_HAS_NAMED_AS: */
+#define __percpu_seg_override
+#endif
+
+#if defined(CONFIG_USE_X86_SEG_SUPPORT) && defined(USE_TYPEOF_UNQUAL)
+#define __percpu_qual __percpu_seg_override
+#endif
+
+#include <asm-generic/percpu_types.h>
+
+#endif
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -44,6 +44,7 @@ mandatory-y += module.lds.h
mandatory-y += msi.h
mandatory-y += pci.h
mandatory-y += percpu.h
+mandatory-y += percpu_types.h
mandatory-y += pgalloc.h
mandatory-y += preempt.h
mandatory-y += rqspinlock.h
--- /dev/null
+++ b/include/asm-generic/percpu_types.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_PERCPU_TYPES_H_
+#define _ASM_GENERIC_PERCPU_TYPES_H_
+
+#ifndef __ASSEMBLER__
+/*
+ * __percpu_qual is the qualifier for the percpu named address space.
+ *
+ * Most arches use generic named address space for percpu variables but
+ * some arches define percpu variables in different named address space
+ * (on the x86 arch, percpu variable may be declared as being relative
+ * to the %fs or %gs segments using __seg_fs or __seg_gs named address
+ * space qualifier).
+ */
+#ifndef __percpu_qual
+# define __percpu_qual
+#endif
+
+#endif /* __ASSEMBLER__ */
+#endif /* _ASM_GENERIC_PERCPU_TYPES_H_ */
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -41,6 +41,7 @@
# define BTF_TYPE_TAG(value) /* nothing */
#endif
+#include <asm/percpu_types.h>
#include <linux/compiler-context-analysis.h>
/* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */
^ permalink raw reply
* [patch 00/38] treewide: Cleanup LATCH, CLOCK_TICK_RATE and get_cycles() [ab]use
From: Thomas Gleixner @ 2026-04-10 12:18 UTC (permalink / raw)
To: LKML
Cc: Arnd Bergmann, x86, Lu Baolu, iommu, Michael Grzeschik, netdev,
linux-wireless, Herbert Xu, linux-crypto, Vlastimil Babka,
linux-mm, David Woodhouse, Bernie Thompson, linux-fbdev,
Theodore Tso, linux-ext4, Andrew Morton, Uladzislau Rezki,
Marco Elver, Dmitry Vyukov, kasan-dev, Andrey Ryabinin,
Thomas Sailer, linux-hams, Jason A. Donenfeld, Richard Henderson,
linux-alpha, Russell King, linux-arm-kernel, Catalin Marinas,
Huacai Chen, loongarch, Geert Uytterhoeven, linux-m68k,
Dinh Nguyen, Jonas Bonn, linux-openrisc, Helge Deller,
linux-parisc, Michael Ellerman, linuxppc-dev, Paul Walmsley,
linux-riscv, Heiko Carstens, linux-s390, David S. Miller,
sparclinux
First of all sorry for the insanely big Cc list, but people can't make
their mind up whether they want to be Cc'ed on everything or not. So I'm
opting for the worst case to cater to the people who want to be Cc'ed on
everything and assume that the rest of you got used to it by now. I really
wanted this to be more confined but a treewide cleanup does not give a lot
of options.
That said, let me explain what this is about.
1) LATCH
The LATCH define goes back to Linux version 0.1 and has survived until
today for the very wrong reasons.
Initially it was based on the x86 PIT frequency and also steered the
timekeeping conversions.
With the arrival of non x86 architectures it got changed to be based
on CLOCK_TICK_RATE in order not to change core code which depended on
LATCH.
That all got meaningless when timers, timekeeping and scheduling
infrastructure got rewritten more than two decades ago.
But there is still a lonely survivor in arch/x86/kernel/apm_32.c
which dates back to Linux 1.3.46 (Dec. 1995)
Which causes the next historical gem
2) CLOCK_TICK_RATE
When Linux got expanded beyond i386 LATCH was made "flexible" by
basing it on CLOCK_TICK_RATE to adjust for other frequencies than the
i386 PIT frequency.
As LATCH this got meaningless long ago and for amusement value it got
copied into new architectures arriving way after it got obsolete for
no reason but with comments to the effect that it's meaningless
And of course it had a lonely survivor in arch/x86/kernel/setup.c
despite it being only an alias for PIT_TICK_RATE for a very long time.
3) get_cycles()
That was introduced in 2.1.133pre4 (Dec. 1998) to utilize the back
then brand new TSC. The introduction broke everything except i386 SMP
with a CPU having a TSC and got then fixed up within a couple of days
with empty stubs returning 0 and #ifdeffery for CONFIG_TSC before the
2.2.0 release.
It's amusing that the naming deliberately ignored that TSC is the
acronym for Time Stamp Counter and not Cycle Counter and rather went
for the underlying coincidence that the TSC was running at the same
fixed frequency as the CPU core.
That turned out to be interesting when CPUs started to have frequency
scaling as the TSC then turned into a variable frequency random number
generator.
A decade later CPU designers came to senses and made the TSC invariant
usually running at the nominal CPU frequency, which allowed to use it
for reliable timekeeping purposes.
Non x86 architectures implemented get_cycles() based on whatever
continuously running counter they had available in their CPUs. Some of
them actual CPU cycle counters, but many of them running at a fixed
frequency which was completely unrelated to CPU cycles.
Around 2004/5 the timekeeping subsystem was completely rewritten and
made generic along with the scheduling clock and other related
infrastructure. With that rewrite get_cycles() got mostly obsolete,
but despite it being on the todo list of quite some people it never
ceased to exist and it was just a conveniance vehicle to base other
things like the recent addition of random_get_entropy() on top with a
hideous #ifdef/#define macro maze.
The other remaining use cases are mostly debugging and testing
code. Especially the usage in performance test code is hillarious at
best. While the name get_cycles() suggests that it provides access to
CPU cycles the reality is that it provides a unspecified counter for
most systems, where a lot of architectures simply return 0 because
they either do not have such a counter or did not bother to implement
it at all.
So in fact get_cycles() should have been renamed to get_bogo_cycles()
long ago matching the BogoMIPS "impress your friends" printk which
still exists for historical amusement value.
But the real solution is to remove it all together instead of
proliferating the bogosity.
This is what this series does with the following steps:
1) Cleanup some header dependency hell which got unearthed by the
restructuring and went unnoticed so far. It's amazing how the kernel
build system magically "works". This affects not only x86, but the
main fallout was observed and fixed there. ARM64 and MIPS are at
least as bad as they silently rely on the accidental asm/timex.h
include through a variety of generic headers to make their
architecture code compile. See the changelog and patches specific to
those two.
2) Removal of LATCH
3) Removal of CLOCK_TICK_RATE
4) Consolidation of cycles_t which was a typedef in asm/timex.h
5) Cleanup of read_current_timer() which is only used for delay
calibration and has nothing to do with get_cycles()
6) Cleanup of get_cycles() usage in debug and test code
7) Decoupling of random_get_entropy() from get_cycles()
8) Removal of asm/timex.h includes except for architecture internal
usage where necessary.
At the end get_cycles() survives in a couple of architectures as a purely
architecture internal implementation detail.
This survives compile testing on all architectures except hexagon and nios2
because the current cross tools based on gcc15 do not offer a compiler for
them anymore. Boot tested on x86 and some qemu instances covering only a
few architectures.
The series applies on v7.0-rc7 and with very minor conflicts on -next. It
is also available from git:
git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git getcycles-v1
Thanks,
tglx
---
arch/alpha/include/asm/timex.h | 33 --------
arch/arc/include/asm/timex.h | 15 ---
arch/arm/include/asm/timex.h | 16 ---
arch/arm64/include/asm/timex.h | 18 ----
arch/hexagon/include/asm/timex.h | 23 -----
arch/m68k/include/asm/timex.h | 42 ----------
arch/microblaze/include/asm/timex.h | 13 ---
arch/mips/include/asm/timex.h | 102 -------------------------
arch/sh/include/asm/timex.h | 24 -----
arch/sparc/include/asm/timex.h | 9 --
arch/sparc/include/asm/timex_32.h | 14 ---
arch/um/include/asm/timex.h | 9 --
b/Documentation/fb/udlfb.rst | 4
b/arch/Kconfig | 10 ++
b/arch/alpha/Kconfig | 1
b/arch/alpha/include/asm/random.h | 14 +++
b/arch/arm/Kconfig | 2
b/arch/arm/include/asm/delay.h | 1
b/arch/arm/include/asm/random.h | 14 +++
b/arch/arm/lib/delay.c | 14 +--
b/arch/arm/mach-omap1/Kconfig | 2
b/arch/arm64/Kconfig | 2
b/arch/arm64/include/asm/io.h | 5 -
b/arch/arm64/include/asm/ptp_vmclock.h | 12 ++
b/arch/arm64/include/asm/random.h | 11 ++
b/arch/arm64/include/asm/rqspinlock.h | 1
b/arch/arm64/kernel/time.c | 6 +
b/arch/arm64/kernel/topology.c | 1
b/arch/arm64/kernel/traps.c | 1
b/arch/arm64/kvm/emulate-nested.c | 1
b/arch/arm64/kvm/hyp/include/hyp/switch.h | 1
b/arch/arm64/lib/delay.c | 1
b/arch/hexagon/Kconfig | 1
b/arch/hexagon/kernel/time.c | 8 +
b/arch/loongarch/Kconfig | 1
b/arch/loongarch/include/asm/random.h | 15 +++
b/arch/loongarch/include/asm/timex.h | 2
b/arch/loongarch/kernel/relocate.c | 1
b/arch/loongarch/kernel/syscall.c | 1
b/arch/loongarch/lib/delay.c | 2
b/arch/m68k/Kconfig | 1
b/arch/m68k/amiga/config.c | 1
b/arch/m68k/include/asm/random.h | 14 +++
b/arch/m68k/kernel/time.c | 2
b/arch/mips/Kconfig | 1
b/arch/mips/generic/init.c | 1
b/arch/mips/include/asm/random.h | 7 +
b/arch/mips/kernel/pm-cps.c | 1
b/arch/mips/kernel/proc.c | 1
b/arch/mips/kernel/relocate.c | 2
b/arch/mips/kernel/time.c | 53 ++++++++++++
b/arch/mips/lib/dump_tlb.c | 1
b/arch/mips/mm/cache.c | 1
b/arch/nios2/Kconfig | 1
b/arch/nios2/include/asm/random.h | 14 +++
b/arch/nios2/include/asm/timex.h | 7 -
b/arch/nios2/kernel/time.c | 4
b/arch/openrisc/Kconfig | 2
b/arch/openrisc/include/asm/random.h | 12 ++
b/arch/openrisc/include/asm/timex.h | 10 --
b/arch/openrisc/lib/delay.c | 8 -
b/arch/parisc/Kconfig | 1
b/arch/parisc/include/asm/random.h | 12 ++
b/arch/parisc/include/asm/timex.h | 10 --
b/arch/parisc/kernel/processor.c | 1
b/arch/parisc/kernel/time.c | 1
b/arch/powerpc/Kconfig | 1
b/arch/powerpc/include/asm/random.h | 13 +++
b/arch/powerpc/include/asm/timex.h | 25 ------
b/arch/powerpc/platforms/cell/spufs/switch.c | 5 -
b/arch/riscv/Kconfig | 2
b/arch/riscv/include/asm/random.h | 25 ++++++
b/arch/riscv/include/asm/timex.h | 23 -----
b/arch/riscv/kernel/unaligned_access_speed.c | 1
b/arch/riscv/kvm/vcpu_timer.c | 1
b/arch/riscv/lib/delay.c | 8 +
b/arch/s390/Kconfig | 1
b/arch/s390/include/asm/random.h | 12 ++
b/arch/s390/include/asm/timex.h | 10 --
b/arch/s390/kernel/time.c | 1
b/arch/s390/kernel/vtime.c | 1
b/arch/sparc/Kconfig | 2
b/arch/sparc/include/asm/random.h | 15 +++
b/arch/sparc/include/asm/timex_64.h | 20 ----
b/arch/sparc/kernel/pcic.c | 1
b/arch/sparc/kernel/time_32.c | 1
b/arch/sparc/kernel/time_64.c | 4
b/arch/sparc/vdso/vclock_gettime.c | 1
b/arch/x86/Kconfig | 4
b/arch/x86/include/asm/iommu.h | 3
b/arch/x86/include/asm/msr.h | 5 -
b/arch/x86/include/asm/percpu.h | 5 -
b/arch/x86/include/asm/percpu_types.h | 17 ++++
b/arch/x86/include/asm/ptp_vmclock.h | 12 ++
b/arch/x86/include/asm/pvclock.h | 1
b/arch/x86/include/asm/random.h | 12 --
b/arch/x86/include/asm/smp.h | 2
b/arch/x86/include/asm/tsc.h | 11 --
b/arch/x86/include/asm/vdso/gettimeofday.h | 5 -
b/arch/x86/kernel/apm_32.c | 4
b/arch/x86/kernel/cpu/mce/core.c | 1
b/arch/x86/kernel/nmi.c | 1
b/arch/x86/kernel/setup.c | 2
b/arch/x86/kernel/smpboot.c | 1
b/arch/x86/kernel/tsc.c | 12 +-
b/arch/x86/lib/delay.c | 8 -
b/crypto/jitterentropy-kcapi.c | 1
b/crypto/tcrypt.c | 84 ++++++++++----------
b/drivers/iommu/intel/dmar.c | 4
b/drivers/iommu/intel/iommu.h | 8 +
b/drivers/irqchip/irq-apple-aic.c | 1
b/drivers/misc/sgi-gru/gruhandles.c | 20 +---
b/drivers/misc/sgi-gru/grukservices.c | 3
b/drivers/misc/sgi-gru/grutlbpurge.c | 5 -
b/drivers/net/arcnet/arc-rimi.c | 4
b/drivers/net/arcnet/arcdevice.h | 20 ----
b/drivers/net/arcnet/com20020.c | 6 -
b/drivers/net/arcnet/com90io.c | 6 -
b/drivers/net/arcnet/com90xx.c | 4
b/drivers/net/hamradio/baycom_epp.c | 51 ------------
b/drivers/net/wireless/ath/wil6210/debugfs.c | 2
b/drivers/net/wireless/ath/wil6210/txrx.c | 6 -
b/drivers/net/wireless/ath/wil6210/txrx_edma.c | 4
b/drivers/net/wireless/ath/wil6210/wil6210.h | 3
b/drivers/ptp/Kconfig | 6 -
b/drivers/ptp/ptp_vmclock.c | 6 -
b/drivers/video/fbdev/udlfb.c | 24 ++---
b/fs/ext4/mballoc.c | 4
b/include/asm-generic/Kbuild | 2
b/include/asm-generic/percpu_types.h | 20 ++++
b/include/linux/compiler_types.h | 1
b/include/linux/delay.h | 2
b/include/linux/jiffies.h | 3
b/include/linux/random.h | 18 ++++
b/include/linux/timex.h | 26 ------
b/include/linux/types.h | 6 +
b/init/calibrate.c | 19 ++--
b/kernel/kcsan/core.c | 3
b/kernel/kcsan/debugfs.c | 8 -
b/kernel/time/timer.c | 1
b/lib/interval_tree_test.c | 17 +---
b/lib/rbtree_test.c | 47 +++++------
b/lib/test_vmalloc.c | 10 +-
b/mm/kasan/sw_tags.c | 2
b/mm/slub.c | 37 +++++----
include/asm-generic/timex.h | 23 -----
146 files changed, 622 insertions(+), 796 deletions(-)
^ permalink raw reply
* Re: [PATCH v10 12/21] gpu: nova-core: mm: Add unified page table entry wrapper enums
From: John Hubbard @ 2026-04-09 18:02 UTC (permalink / raw)
To: Joel Fernandes
Cc: Eliot Courtney, linux-kernel, Miguel Ojeda, Boqun Feng, Gary Guo,
Bjorn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Dave Airlie, Daniel Almeida,
Koen Koning, dri-devel, rust-for-linux, Nikola Djukic,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Alex Deucher, Christian Koenig,
Jani Nikula, Joonas Lahtinen, Vivi Rodrigo, Tvrtko Ursulin,
Rui Huang, Matthew Auld, Matthew Brost, Lucas De Marchi,
Thomas Hellstrom, Helge Deller, Alex Gaynor, Boqun Feng,
Alistair Popple, Timur Tabi, Edwin Peer, Alexandre Courbot,
Andrea Righi, Andy Ritger, Zhi Wang, Balbir Singh,
Philipp Stanner, Elle Rhumsaa, Alexey Ivanov, linux-doc, amd-gfx,
intel-gfx, intel-xe, linux-fbdev
In-Reply-To: <1775730646.3752.4760@nvidia.com>
On 4/9/26 3:33 AM, Joel Fernandes wrote:
...
> Since it is 3 against 1 here, I rest my case :-). I am still in
As Danilo points out, we want to foster healthy debate and land
on whatever comes out of that. Not just by counting noses. :)
> disagreement since I do not see much benefit (that is why I said
> pointless above). Actually it is not even about readability, that is
> subjective (and I haven’t heard most people say parametrizing code for
> the sake of it makes it more readable anyway). It is that the code gen
> is worse, and the complexity is just moved to a higher level in the
> code, not removed. So what are we getting out of this really, other than
> more boiler plate in higher layers of the code that did not exist
> before? Not performance, not better generated code. Really nothing. See
> all the data points in my previous reply.
Alex's latest response[1] does a *much* better job than mine, in
explicitly highlighting what we get out of this. (It arrived a bit after
your response here.) Please take a very close look at that response and
see what you think.
The patterns in these page tables are not a new thing, and Rust has
language features to help express them.
[1] https://lore.kernel.org/DHOKJ3MJNO5P.SXKOAYKX13JL@nvidia.com
thanks,
--
John Hubbard
^ permalink raw reply
* [PATCH v2 2/2] staging: sm750fb: propagate error codes from de_wait()
From: Hungyu Lin @ 2026-04-09 15:58 UTC (permalink / raw)
To: Sudip Mukherjee, Teddy Wang, Greg Kroah-Hartman
Cc: linux-fbdev, linux-staging, linux-kernel, Hungyu Lin
In-Reply-To: <20260409155821.23375-1-dennylin0707@gmail.com>
The sm750 acceleration functions currently return -1 when
de_wait() fails, discarding the original error code.
Since de_wait() now returns proper errno values, propagate
the error code instead of returning -1.
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
---
drivers/staging/sm750fb/sm750_accel.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c
index 0f94d859e91c..688ec262a8ed 100644
--- a/drivers/staging/sm750fb/sm750_accel.c
+++ b/drivers/staging/sm750fb/sm750_accel.c
@@ -90,14 +90,16 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
u32 color, u32 rop)
{
u32 de_ctrl;
+ int ret;
- if (accel->de_wait() != 0) {
+ ret = accel->de_wait();
+ if (ret) {
/*
- * int time wait and always busy,seems hardware
+ * int time wait and always busy, seems hardware
* got something error
*/
pr_debug("De engine always busy\n");
- return -1;
+ return ret;
}
write_dpr(accel, DE_WINDOW_DESTINATION_BASE, base); /* dpr40 */
@@ -154,6 +156,7 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
unsigned int rop2)
{
unsigned int direction, de_ctrl;
+ int ret;
direction = LEFT_TO_RIGHT;
/* Direction of ROP2 operation: 1 = Left to Right, (-1) = Right to Left */
@@ -263,8 +266,9 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
DE_WINDOW_WIDTH_DST_MASK) |
(source_pitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr3c */
- if (accel->de_wait() != 0)
- return -1;
+ ret = accel->de_wait();
+ if (ret)
+ return ret;
write_dpr(accel, DE_SOURCE,
((sx << DE_SOURCE_X_K1_SHIFT) & DE_SOURCE_X_K1_MASK) |
@@ -326,14 +330,16 @@ int sm750_hw_imageblit(struct lynx_accel *accel, const char *src_buf,
unsigned int de_ctrl = 0;
unsigned char remain[4];
int i, j;
+ int ret;
start_bit &= 7; /* Just make sure the start bit is within legal range */
bytes_per_scan = (width + start_bit + 7) / 8;
words_per_scan = bytes_per_scan & ~3;
bytes_remain = bytes_per_scan & 3;
- if (accel->de_wait() != 0)
- return -1;
+ ret = accel->de_wait();
+ if (ret)
+ return ret;
/*
* 2D Source Base.
--
2.34.1
^ permalink raw reply related
* [PATCH v2 1/2] staging: sm750fb: return -ETIMEDOUT on timeout in de_wait functions
From: Hungyu Lin @ 2026-04-09 15:58 UTC (permalink / raw)
To: Sudip Mukherjee, Teddy Wang, Greg Kroah-Hartman
Cc: linux-fbdev, linux-staging, linux-kernel, Hungyu Lin
In-Reply-To: <20260409155821.23375-1-dennylin0707@gmail.com>
The hw_sm750le_de_wait() and hw_sm750_de_wait() functions return -1
when a timeout occurs. Replace these with -ETIMEDOUT to use a proper
errno value and better describe the error condition.
All callers check the return value as non-zero, so this change does
not alter existing behavior.
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
---
drivers/staging/sm750fb/sm750_hw.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c
index a2798d428663..3809401baa3a 100644
--- a/drivers/staging/sm750fb/sm750_hw.c
+++ b/drivers/staging/sm750fb/sm750_hw.c
@@ -502,7 +502,7 @@ int hw_sm750le_de_wait(void)
return 0;
}
/* timeout error */
- return -1;
+ return -ETIMEDOUT;
}
int hw_sm750_de_wait(void)
@@ -520,7 +520,7 @@ int hw_sm750_de_wait(void)
return 0;
}
/* timeout error */
- return -1;
+ return -ETIMEDOUT;
}
int hw_sm750_pan_display(struct lynxfb_crtc *crtc,
--
2.34.1
^ permalink raw reply related
* [PATCH v2 0/2] staging: sm750fb: improve error handling in de_wait path
From: Hungyu Lin @ 2026-04-09 15:58 UTC (permalink / raw)
To: Sudip Mukherjee, Teddy Wang, Greg Kroah-Hartman
Cc: linux-fbdev, linux-staging, linux-kernel, Hungyu Lin
This series improves error handling in the sm750fb driver.
The de_wait() helpers previously returned -1 on timeout, and
callers discarded the error code by always returning -1. This
series replaces -1 with -ETIMEDOUT and propagates the error code
to improve error reporting.
Patch 1 replaces -1 with -ETIMEDOUT in de_wait() helpers.
Patch 2 propagates error codes from de_wait().
v2:
- Restore the removed comment in sm750_accel.c as requested
Hungyu Lin (2):
staging: sm750fb: return -ETIMEDOUT on timeout in de_wait functions
staging: sm750fb: propagate error codes from de_wait()
drivers/staging/sm750fb/sm750_accel.c | 20 +++++++++++++-------
drivers/staging/sm750fb/sm750_hw.c | 4 ++--
2 files changed, 15 insertions(+), 9 deletions(-)
--
2.34.1
^ permalink raw reply
* Re: [PATCH 2/2] staging: sm750fb: propagate error codes from de_wait()
From: Greg Kroah-Hartman @ 2026-04-09 15:22 UTC (permalink / raw)
To: Denny Lin
Cc: Sudip Mukherjee, Teddy Wang, linux-fbdev, linux-staging,
linux-kernel
In-Reply-To: <CAGEkeHd8p48H6U36VBFAAMffz_tW71jcb90POekDgG51JN4YUA@mail.gmail.com>
On Thu, Apr 09, 2026 at 08:15:36AM -0700, Denny Lin wrote:
> Hi Greg,
>
Odd email style, try replying inline in the real email, not at the top
please :)
> > Why did you delete the comment?
>
> The comment was removed as part of simplifying the code while
> changing the error handling to propagate the return value from
> de_wait(). I can restore or update it if needed.
Please keep it.
> > And when did de_wait() start returning correct values?
>
> de_wait() starts returning a proper errno value in patch 1 of this
> series, where the timeout return value is changed from -1 to
> -ETIMEDOUT. This patch then propagates that error value.
Ah, that wasn't obvious, sorry.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH 2/2] staging: sm750fb: propagate error codes from de_wait()
From: Denny Lin @ 2026-04-09 15:15 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Sudip Mukherjee, Teddy Wang, linux-fbdev, linux-staging,
linux-kernel
In-Reply-To: <2026040931-robust-siamese-4e11@gregkh>
Hi Greg,
> Why did you delete the comment?
The comment was removed as part of simplifying the code while
changing the error handling to propagate the return value from
de_wait(). I can restore or update it if needed.
> And when did de_wait() start returning correct values?
de_wait() starts returning a proper errno value in patch 1 of this
series, where the timeout return value is changed from -1 to
-ETIMEDOUT. This patch then propagates that error value.
Thanks,
Hungyu
On Thu, Apr 9, 2026 at 8:05 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Thu, Apr 09, 2026 at 02:41:19PM +0000, Hungyu Lin wrote:
> > The sm750 acceleration functions currently return -1 when
> > de_wait() fails, discarding the original error code.
> >
> > Since de_wait() now returns proper errno values, propagate
> > the error code instead of returning -1.
> >
> > Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
> > ---
> > drivers/staging/sm750fb/sm750_accel.c | 22 ++++++++++++----------
> > 1 file changed, 12 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c
> > index 0f94d859e91c..891d12a5e2cc 100644
> > --- a/drivers/staging/sm750fb/sm750_accel.c
> > +++ b/drivers/staging/sm750fb/sm750_accel.c
> > @@ -90,14 +90,12 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
> > u32 color, u32 rop)
> > {
> > u32 de_ctrl;
> > + int ret;
> >
> > - if (accel->de_wait() != 0) {
> > - /*
> > - * int time wait and always busy,seems hardware
> > - * got something error
> > - */
>
> Why did you delete the comment?
>
> And when did de_wait() start returning correct values?
>
> thanks,
>
> greg k-h
^ permalink raw reply
* Re: [PATCH 2/2] staging: sm750fb: propagate error codes from de_wait()
From: Greg Kroah-Hartman @ 2026-04-09 15:05 UTC (permalink / raw)
To: Hungyu Lin
Cc: Sudip Mukherjee, Teddy Wang, linux-fbdev, linux-staging,
linux-kernel
In-Reply-To: <20260409144119.21500-3-dennylin0707@gmail.com>
On Thu, Apr 09, 2026 at 02:41:19PM +0000, Hungyu Lin wrote:
> The sm750 acceleration functions currently return -1 when
> de_wait() fails, discarding the original error code.
>
> Since de_wait() now returns proper errno values, propagate
> the error code instead of returning -1.
>
> Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
> ---
> drivers/staging/sm750fb/sm750_accel.c | 22 ++++++++++++----------
> 1 file changed, 12 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c
> index 0f94d859e91c..891d12a5e2cc 100644
> --- a/drivers/staging/sm750fb/sm750_accel.c
> +++ b/drivers/staging/sm750fb/sm750_accel.c
> @@ -90,14 +90,12 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
> u32 color, u32 rop)
> {
> u32 de_ctrl;
> + int ret;
>
> - if (accel->de_wait() != 0) {
> - /*
> - * int time wait and always busy,seems hardware
> - * got something error
> - */
Why did you delete the comment?
And when did de_wait() start returning correct values?
thanks,
greg k-h
^ permalink raw reply
* [PATCH 2/2] staging: sm750fb: propagate error codes from de_wait()
From: Hungyu Lin @ 2026-04-09 14:41 UTC (permalink / raw)
To: Sudip Mukherjee, Teddy Wang, Greg Kroah-Hartman
Cc: linux-fbdev, linux-staging, linux-kernel, Hungyu Lin
In-Reply-To: <20260409144119.21500-1-dennylin0707@gmail.com>
The sm750 acceleration functions currently return -1 when
de_wait() fails, discarding the original error code.
Since de_wait() now returns proper errno values, propagate
the error code instead of returning -1.
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
---
drivers/staging/sm750fb/sm750_accel.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c
index 0f94d859e91c..891d12a5e2cc 100644
--- a/drivers/staging/sm750fb/sm750_accel.c
+++ b/drivers/staging/sm750fb/sm750_accel.c
@@ -90,14 +90,12 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
u32 color, u32 rop)
{
u32 de_ctrl;
+ int ret;
- if (accel->de_wait() != 0) {
- /*
- * int time wait and always busy,seems hardware
- * got something error
- */
+ ret = accel->de_wait();
+ if (ret) {
pr_debug("De engine always busy\n");
- return -1;
+ return ret;
}
write_dpr(accel, DE_WINDOW_DESTINATION_BASE, base); /* dpr40 */
@@ -154,6 +152,7 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
unsigned int rop2)
{
unsigned int direction, de_ctrl;
+ int ret;
direction = LEFT_TO_RIGHT;
/* Direction of ROP2 operation: 1 = Left to Right, (-1) = Right to Left */
@@ -263,8 +262,9 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
DE_WINDOW_WIDTH_DST_MASK) |
(source_pitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr3c */
- if (accel->de_wait() != 0)
- return -1;
+ ret = accel->de_wait();
+ if (ret)
+ return ret;
write_dpr(accel, DE_SOURCE,
((sx << DE_SOURCE_X_K1_SHIFT) & DE_SOURCE_X_K1_MASK) |
@@ -326,14 +326,16 @@ int sm750_hw_imageblit(struct lynx_accel *accel, const char *src_buf,
unsigned int de_ctrl = 0;
unsigned char remain[4];
int i, j;
+ int ret;
start_bit &= 7; /* Just make sure the start bit is within legal range */
bytes_per_scan = (width + start_bit + 7) / 8;
words_per_scan = bytes_per_scan & ~3;
bytes_remain = bytes_per_scan & 3;
- if (accel->de_wait() != 0)
- return -1;
+ ret = accel->de_wait();
+ if (ret)
+ return ret;
/*
* 2D Source Base.
--
2.34.1
^ permalink raw reply related
* [PATCH 1/2] staging: sm750fb: return -ETIMEDOUT on timeout in de_wait functions
From: Hungyu Lin @ 2026-04-09 14:41 UTC (permalink / raw)
To: Sudip Mukherjee, Teddy Wang, Greg Kroah-Hartman
Cc: linux-fbdev, linux-staging, linux-kernel, Hungyu Lin
In-Reply-To: <20260409144119.21500-1-dennylin0707@gmail.com>
The hw_sm750le_de_wait() and hw_sm750_de_wait() functions return -1
when a timeout occurs. Replace these with -ETIMEDOUT to use a proper
errno value and better describe the error condition.
All callers check the return value as non-zero, so this change does
not alter existing behavior.
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
---
drivers/staging/sm750fb/sm750_hw.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c
index a2798d428663..3809401baa3a 100644
--- a/drivers/staging/sm750fb/sm750_hw.c
+++ b/drivers/staging/sm750fb/sm750_hw.c
@@ -502,7 +502,7 @@ int hw_sm750le_de_wait(void)
return 0;
}
/* timeout error */
- return -1;
+ return -ETIMEDOUT;
}
int hw_sm750_de_wait(void)
@@ -520,7 +520,7 @@ int hw_sm750_de_wait(void)
return 0;
}
/* timeout error */
- return -1;
+ return -ETIMEDOUT;
}
int hw_sm750_pan_display(struct lynxfb_crtc *crtc,
--
2.34.1
^ permalink raw reply related
* [PATCH 0/2] staging: sm750fb: improve error handling in de_wait path
From: Hungyu Lin @ 2026-04-09 14:41 UTC (permalink / raw)
To: Sudip Mukherjee, Teddy Wang, Greg Kroah-Hartman
Cc: linux-fbdev, linux-staging, linux-kernel, Hungyu Lin
This series improves error handling in the sm750fb driver.
The de_wait() helpers currently return -1 on timeout and callers
discard error codes by always returning -1. This series replaces
-1 with -ETIMEDOUT and propagates the error code to improve
error reporting.
Patch 1 replaces -1 with -ETIMEDOUT in de_wait() helpers.
Patch 2 propagates error codes in callers instead of returning -1.
Hungyu Lin (2):
staging: sm750fb: return -ETIMEDOUT on timeout in de_wait functions
staging: sm750fb: propagate error codes from de_wait()
drivers/staging/sm750fb/sm750_accel.c | 22 ++++++++++++----------
drivers/staging/sm750fb/sm750_hw.c | 4 ++--
2 files changed, 14 insertions(+), 12 deletions(-)
--
2.34.1
^ permalink raw reply
* [PATCH] fbdev: udlfb: avoid divide-by-zero on FBIOPUT_VSCREENINFO
From: Greg Kroah-Hartman @ 2026-04-09 13:23 UTC (permalink / raw)
To: linux-fbdev, dri-devel
Cc: linux-kernel, Greg Kroah-Hartman, Bernie Thompson, Helge Deller
Much like commit 19f953e74356 ("fbdev: fb_pm2fb: Avoid potential divide
by zero error"), we also need to prevent that same crash from happening
in the udlfb driver as it uses pixclock directly when dividing, which
will crash.
Cc: Bernie Thompson <bernie@plugable.com>
Cc: Helge Deller <deller@gmx.de>
Fixes: 59277b679f8b ("Staging: udlfb: add dynamic modeset support")
Assisted-by: gregkh_clanker_t1000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/video/fbdev/udlfb.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
index 3c6a9b5758d9..c341d76bc564 100644
--- a/drivers/video/fbdev/udlfb.c
+++ b/drivers/video/fbdev/udlfb.c
@@ -1018,6 +1018,9 @@ static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
struct fb_videomode mode;
struct dlfb_data *dlfb = info->par;
+ if (!var->pixclock)
+ return -EINVAL;
+
/* set device-specific elements of var unrelated to mode */
dlfb_var_color_format(var);
--
2.53.0
^ permalink raw reply related
* [PATCH] fbdev: tdfxfb: avoid divide-by-zero on FBIOPUT_VSCREENINFO
From: Greg Kroah-Hartman @ 2026-04-09 13:23 UTC (permalink / raw)
To: linux-fbdev, dri-devel
Cc: linux-kernel, Greg Kroah-Hartman, Helge Deller, stable
Much like commit 19f953e74356 ("fbdev: fb_pm2fb: Avoid potential divide
by zero error"), we also need to prevent that same crash from happening
in the udlfb driver as it uses pixclock directly when dividing, which
will crash.
Cc: Helge Deller <deller@gmx.de>
Assisted-by: gregkh_clanker_t1000
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/video/fbdev/tdfxfb.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c
index 51ebe78359ec..531fb8478e20 100644
--- a/drivers/video/fbdev/tdfxfb.c
+++ b/drivers/video/fbdev/tdfxfb.c
@@ -496,6 +496,9 @@ static int tdfxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
}
}
+ if (!var->pixclock)
+ return -EINVAL;
+
if (PICOS2KHZ(var->pixclock) > par->max_pixclock) {
DPRINTK("pixclock too high (%ldKHz)\n",
PICOS2KHZ(var->pixclock));
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v10 12/21] gpu: nova-core: mm: Add unified page table entry wrapper enums
From: Gary Guo @ 2026-04-09 11:02 UTC (permalink / raw)
To: Joel Fernandes, Alexandre Courbot, Eliot Courtney,
Danilo Krummrich
Cc: linux-kernel, Miguel Ojeda, Boqun Feng, Gary Guo, Bjorn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Dave Airlie, Daniel Almeida, Koen Koning, dri-devel,
rust-for-linux, Nikola Djukic, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Jonathan Corbet,
Alex Deucher, Christian Koenig, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Huang Rui, Matthew Auld,
Matthew Brost, Lucas De Marchi, Thomas Hellstrom, Helge Deller,
Alex Gaynor, Boqun Feng, John Hubbard, Alistair Popple,
Timur Tabi, Edwin Peer, Andrea Righi, Andy Ritger, Zhi Wang,
Balbir Singh, Philipp Stanner, Elle Rhumsaa, alexeyi, joel,
linux-doc, amd-gfx, intel-gfx, intel-xe, linux-fbdev
In-Reply-To: <2f004511-61d1-4197-84b6-cddcdd275e55@nvidia.com>
On Wed Apr 8, 2026 at 9:19 PM BST, Joel Fernandes wrote:
> Hi Alex, Eliot, Danilo,
>
> Thanks for taking a look. Let me respond to the specific points below.
>
> On Wed, 08 Apr 2026, Alexandre Courbot wrote:
>> After a quick look I'd say that having a trait here would actually be
>> *good* for correctness and maintainability.
>>
>> The current design implies that every operation on a page table (most
>> likely using the walker) goes through a branching point. Just looking at
>> `PtWalk::read_pte_at_level`, there are already at least 6
>> `if version == 2 { } else { }` branches that all resolve to the same
>> result. Include walking down the PDEs and you have at least a dozen of
>> these just to resolve a virtual address. I know CPUs are fast, but this
>> is still wasted cycles for no good reason.
>
> I did some measurements and there is no notieceable difference in both
> approaches. I ran perf and loaded nova with self-tests running. The extra
> potential branching is lost in the noise. In both cases, loading nova and
> running the self-tests has ~119.7M branch instructions on my Ampere. The total
> instruction count is also identical (~615M).
>
> I measured like this:
> perf stat -e
> branches,branch-misses,cache-references,cache-misses,instructions,cycles --
> modprobe nova_core
>
> So I think the branching argument is not a strong one. I also did more
> measurements and the dominant time taken is MMIO. During the map prep and
> execute, page table walks are done. A TLB flush alone costs ~1.4 microseconds.
> And PRAMIN BAR0 writes to write the PTE is also about 1 microsecond. Considering
> this, I don't think the extra branching argument holds (even without branch
> prediction and speculation).
>
> Also some branches cannot be eliminated even with parameterization:
>
> if level == self.mmu_version.dual_pde_level() {
> // 128-bit dual PDE read
> } else {
> // Regular 64-bit PDE read
> }
>
> This isn't really a version branch -- it's a structural branch that
> distinguishes between 64-bit PDE and 128-bit dual PDE entries. Any MMU
> version with a dual PDE level would need this same distinction.
>
> I also did code-generation size analysis (see diff of code used below):
>
> Code generation analysis:
>
> Module .ko size: Before: 511,792 bytes After: 524,464 bytes (+2.5%)
> .text section: Before: 112,620 bytes After: 116,628 bytes (+4,008 bytes)
>
> The +4K .text growth is the monomorphization cost: every generic function
> is compiled twice (once for MmuV2, once for MmuV3).
>
>> If you use a trait here, and make `PtWalk` generic against it, you can
>> optimize this away. We had a similar situation when we introduced Turing
>> support and the v2 ucode header, and tried both approaches: the
>> trait-based one was slightly shorter, and arguably more readable.
>
> Actually I was the one who suggested traits for Falcon ucode descriptor if you
> see this thread [1]. So basically you and Eliot are telling me to do what I
> suggested in [1]. :-) However, I disagree that it is the right choice for this code.
>
> [1] https://lore.kernel.org/all/20251117231028.GA1095236@joelbox2/
>
> I think the two cases are quite different in complexity:
>
> The falcon ucode descriptor is essentially a set of flat field accessors
> and a few params (imem_sec_load_params, dmem_load_params).
> The trait has ~10 simple getter methods. There's no multi-level hierarchy,
> no walker, and no generic propagation.
>
> The MMU page table case is structurally different. Making PtWalk generic
> over an Mmu trait would require:
>
> - PtWalk<M: Mmu> (the walker)
> - Plus all the associated types: M::Pte, M::Pde, M::DualPde each
> needing their own trait bounds
>
> And we would also need:
> - Vmm<M: Mmu> (which creates PtWalk)
> - BarUser<M: Mmu> (which creates Vmm)
>
> I am also against making Vmm an enum as Eliot suggested:
> enum Vmm {
> V2(VmmInner<MmuV2>),
> V3(VmmInner<MmuV3>),
> }
>
> That moves the version complexity up to the reader. Code complexity IMO should
> decrease as we go up abstractions, making it easier for users (Vmm/Bar).
>
> If you look at the the changes in vmm.rs to handle version dispatch there [2]:
> Added: +109
> Removed: -28
>
> [2]
> https://github.com/Edgeworth/linux/commit/3627af550b61256184d589e7ec666c1108971f0e
>
> The main benefit of my approach is version-specific dispatch complexity is
> completely isolated inside MmuVersion thus making the code outside of
> pagetable.rs much more readable, without having to parametrize anything, and
> without code size increase. I think that is worth considering.
>
>> But the main argument to use a trait here IMO is that it enables
>> associated types and constants. That's particularly critical since some
>> equivalent fields have different lengths between v2 and v3. An
>> associated `Bounded` type for these would force the caller to validate
>> the length of these fields before calling a non-fallible operation,
>> which is exactly the level of caution that we want when dealing with
>> page tables.
>
> I think Bounded validation is orthogonal to the dispatch model.
> We can add Bounded to the current design without restructuring
> into traits. For example:
>
> // In ver2::Pte
> pub fn new_vram(pfn: Bounded<Pfn, 25>, writable: bool) -> Self { ... }
>
> // In ver3::Pte
> pub fn new_vram(pfn: Bounded<Pfn, 40>, writable: bool) -> Self { ... }
>
> The unified Pte enum wrapper already dispatches to the correct
> version-specific constructor, which would enforce the correct Bounded
> constraint for that version.
>
>> In order to fully benefit from it, we will need the bitfield macro from
>> the `kernel` crate so the PDE/PTE fields can be `Bounded`, I will try to
>> make it available quickly in a patch that you can depend on.
>
> That would be great, and I'd be happy to integrate Bounded validation once
> the macro is available. I just don't think we need to restructure the
> dispatch model in order to benefit from it.
>
>> But long story short, and although I need to dive deeper into the code,
>> this looks like a good candidate for using a trait and associated types.
>
> The walker code (walk.rs) is already version-agnostic and reads cleanly.
> The version dispatch is encapsulated behind method calls, not exposed as
> inline if/else blocks.
>
> Generic propagation (or version-specific dispatch at higher levels) adds more
> complexity at higher layers.
>
> Enclosed below [3] is the diff I used for my testing with the data, I don't
> really see a net readability win there (IMO, it is a net-loss in readability).
>
> [3]
> https://git.kernel.org/pub/scm/linux/kernel/git/jfern/linux.git/commit/?h=trait-pt-dispatch&id=5eb0e98af11ba608ff4d0f7a06065ee863f5066a
IMO this diff is quite has got me quite in favour of trait approach.
I wanted about to purpose something similar (or maybe I had already?) trait
approach some versions ago but didn't due to the eventual need of `match` like
dispatch (like you had with `vmm_dispatch`), but your code made that looks not
as bad as I thought it would be.
Best,
Gary
^ permalink raw reply
* Re: [PATCH v10 12/21] gpu: nova-core: mm: Add unified page table entry wrapper enums
From: Danilo Krummrich @ 2026-04-09 11:00 UTC (permalink / raw)
To: Joel Fernandes
Cc: John Hubbard, Eliot Courtney, linux-kernel, Miguel Ojeda,
Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Dave Airlie,
Daniel Almeida, Koen Koning, dri-devel, rust-for-linux,
Nikola Djukic, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Jonathan Corbet,
Alex Deucher, Christian Koenig, Jani Nikula, Joonas Lahtinen,
Vivi Rodrigo, Tvrtko Ursulin, Rui Huang, Matthew Auld,
Matthew Brost, Lucas De Marchi, Thomas Hellstrom, Helge Deller,
Alex Gaynor, Boqun Feng, Alistair Popple, Timur Tabi, Edwin Peer,
Alexandre Courbot, Andrea Righi, Andy Ritger, Zhi Wang,
Balbir Singh, Philipp Stanner, Elle Rhumsaa, Alexey Ivanov,
linux-doc, amd-gfx, intel-gfx, intel-xe, linux-fbdev
In-Reply-To: <1775730646.3752.4760@nvidia.com>
On Thu Apr 9, 2026 at 12:33 PM CEST, Joel Fernandes wrote:
> Since it is 3 against 1 here, I rest my case :-).
That's not how I'd view it. :)
Anyways, in case I'm included in "3", that's not my position. My point was to
ensure we keep discussing advantages and disadvantages on their merits, as I
think you both have good points.
> I am still in disagreement since I do not see much benefit (that is why I said
> pointless above).
That is fair -- in this case please explain why the advantages pointed out by
others are not worth it, propose something that picks up the best of both
worlds, etc.
You can also turn it around and ask people whether they can tweak their counter
proposal to get rid of specific parts you dislike for a reason.
IOW, keep the ball rolling, so we can come up with the best possible solution.
^ permalink raw reply
* Re: [PATCH v10 12/21] gpu: nova-core: mm: Add unified page table entry wrapper enums
From: Alexandre Courbot @ 2026-04-09 10:56 UTC (permalink / raw)
To: Joel Fernandes
Cc: Eliot Courtney, Danilo Krummrich, linux-kernel, Miguel Ojeda,
Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Dave Airlie,
Daniel Almeida, Koen Koning, dri-devel, rust-for-linux,
Nikola Djukic, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Jonathan Corbet,
Alex Deucher, Christian Koenig, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Huang Rui, Matthew Auld,
Matthew Brost, Lucas De Marchi, Thomas Hellstrom, Helge Deller,
Alex Gaynor, Boqun Feng, John Hubbard, Alistair Popple,
Timur Tabi, Edwin Peer, Andrea Righi, Andy Ritger, Zhi Wang,
Balbir Singh, Philipp Stanner, Elle Rhumsaa, alexeyi, joel,
linux-doc, amd-gfx, intel-gfx, intel-xe, linux-fbdev
In-Reply-To: <2f004511-61d1-4197-84b6-cddcdd275e55@nvidia.com>
On Thu Apr 9, 2026 at 5:19 AM JST, Joel Fernandes wrote:
> Hi Alex, Eliot, Danilo,
>
> Thanks for taking a look. Let me respond to the specific points below.
>
> On Wed, 08 Apr 2026, Alexandre Courbot wrote:
>> After a quick look I'd say that having a trait here would actually be
>> *good* for correctness and maintainability.
>>
>> The current design implies that every operation on a page table (most
>> likely using the walker) goes through a branching point. Just looking at
>> `PtWalk::read_pte_at_level`, there are already at least 6
>> `if version == 2 { } else { }` branches that all resolve to the same
>> result. Include walking down the PDEs and you have at least a dozen of
>> these just to resolve a virtual address. I know CPUs are fast, but this
>> is still wasted cycles for no good reason.
>
> I did some measurements and there is no notieceable difference in both
> approaches. I ran perf and loaded nova with self-tests running. The extra
> potential branching is lost in the noise. In both cases, loading nova and
> running the self-tests has ~119.7M branch instructions on my Ampere. The total
> instruction count is also identical (~615M).
That's expected - as I said, CPUs are fast - and that's also not my
point. My issue is that we are doing countless tests that all resolve to
the code path, a code path that is already known during probe time.
That's a huge code smell.
When we create the GPU, we know whether we will be using v2 or v3 page
tables. That we need to test that again 12 times per address resolution
is a design issue, irrespective of performance. There are 24 version
match sites in patch 12 alone.
And that's precisely a good justification for using monomorphization. v2
and v3 are technically two different page table implementations (they
even have their own distinct module in your series), we just use
generics to factorize the (source) code a bit.
>
> I measured like this:
> perf stat -e
> branches,branch-misses,cache-references,cache-misses,instructions,cycles --
> modprobe nova_core
>
> So I think the branching argument is not a strong one. I also did more
> measurements and the dominant time taken is MMIO. During the map prep and
> execute, page table walks are done. A TLB flush alone costs ~1.4 microseconds.
> And PRAMIN BAR0 writes to write the PTE is also about 1 microsecond. Considering
> this, I don't think the extra branching argument holds (even without branch
> prediction and speculation).
>
> Also some branches cannot be eliminated even with parameterization:
>
> if level == self.mmu_version.dual_pde_level() {
> // 128-bit dual PDE read
> } else {
> // Regular 64-bit PDE read
> }
>
> This isn't really a version branch -- it's a structural branch that
> distinguishes between 64-bit PDE and 128-bit dual PDE entries. Any MMU
> version with a dual PDE level would need this same distinction.
The dual PDE level should be an associated constant - you still need to
do the test, but note that you would also do it if there was only a
single page table version. It's orthogonal to whether we use a trait or
not here.
>
> I also did code-generation size analysis (see diff of code used below):
>
> Code generation analysis:
>
> Module .ko size: Before: 511,792 bytes After: 524,464 bytes (+2.5%)
> .text section: Before: 112,620 bytes After: 116,628 bytes (+4,008 bytes)
>
> The +4K .text growth is the monomorphization cost: every generic function
> is compiled twice (once for MmuV2, once for MmuV3).
I would say this is working as intended then.
>
>> If you use a trait here, and make `PtWalk` generic against it, you can
>> optimize this away. We had a similar situation when we introduced Turing
>> support and the v2 ucode header, and tried both approaches: the
>> trait-based one was slightly shorter, and arguably more readable.
>
> Actually I was the one who suggested traits for Falcon ucode descriptor if you
> see this thread [1]. So basically you and Eliot are telling me to do what I
> suggested in [1]. :-) However, I disagree that it is the right choice for this code.
>
> [1] https://lore.kernel.org/all/20251117231028.GA1095236@joelbox2/
>
> I think the two cases are quite different in complexity:
Exactly. The complexity is different (this one involves multiple traits
and associated types) but the pattern is the same - and that's a pattern
traits are designed to address. If we were supposed to stop applying it
when things go beyond a certain level of complexity, the conceptors of
Rust would not have bothered addings things like associated types.
These traits are nothing new, they simply formalize a reality that
already exists in your code, which is that each version of the page
table needs to implement a given set of methods. It's already there with
the version doing dispatches, only it is not articulated clearly to the
reader. So in that respect, having traits make the code *more* readable
imho.
>
> The falcon ucode descriptor is essentially a set of flat field accessors
> and a few params (imem_sec_load_params, dmem_load_params).
> The trait has ~10 simple getter methods. There's no multi-level hierarchy,
> no walker, and no generic propagation.
>
> The MMU page table case is structurally different. Making PtWalk generic
> over an Mmu trait would require:
>
> - PtWalk<M: Mmu> (the walker)
> - Plus all the associated types: M::Pte, M::Pde, M::DualPde each
> needing their own trait bounds
>
> And we would also need:
> - Vmm<M: Mmu> (which creates PtWalk)
> - BarUser<M: Mmu> (which creates Vmm)
>
> I am also against making Vmm an enum as Eliot suggested:
> enum Vmm {
> V2(VmmInner<MmuV2>),
> V3(VmmInner<MmuV3>),
> }
>
> That moves the version complexity up to the reader. Code complexity IMO should
> decrease as we go up abstractions, making it easier for users (Vmm/Bar).
>
> If you look at the the changes in vmm.rs to handle version dispatch there [2]:
> Added: +109
> Removed: -28
>
> [2]
> https://github.com/Edgeworth/linux/commit/3627af550b61256184d589e7ec666c1108971f0e
>
> The main benefit of my approach is version-specific dispatch complexity is
> completely isolated inside MmuVersion thus making the code outside of
> pagetable.rs much more readable, without having to parametrize anything, and
> without code size increase. I think that is worth considering.
>
>> But the main argument to use a trait here IMO is that it enables
>> associated types and constants. That's particularly critical since some
>> equivalent fields have different lengths between v2 and v3. An
>> associated `Bounded` type for these would force the caller to validate
>> the length of these fields before calling a non-fallible operation,
>> which is exactly the level of caution that we want when dealing with
>> page tables.
>
> I think Bounded validation is orthogonal to the dispatch model.
> We can add Bounded to the current design without restructuring
> into traits. For example:
>
> // In ver2::Pte
> pub fn new_vram(pfn: Bounded<Pfn, 25>, writable: bool) -> Self { ... }
>
> // In ver3::Pte
> pub fn new_vram(pfn: Bounded<Pfn, 40>, writable: bool) -> Self { ... }
>
> The unified Pte enum wrapper already dispatches to the correct
> version-specific constructor, which would enforce the correct Bounded
> constraint for that version.
But then what type does the `new_vram` dispatch method take? Generic
code lets us expose the expected `Bounded` type to the caller, which can
do the proper validation. This is a small example, but I expect this
pattern to come up in other parts of the code as well.
>
>> In order to fully benefit from it, we will need the bitfield macro from
>> the `kernel` crate so the PDE/PTE fields can be `Bounded`, I will try to
>> make it available quickly in a patch that you can depend on.
>
> That would be great, and I'd be happy to integrate Bounded validation once
> the macro is available. I just don't think we need to restructure the
> dispatch model in order to benefit from it.
I'll finish the series and hopefully send it a bit later today. That's
another significant rework for the series (sorry about that) but it
should be worth the effort for the added correctness.
^ permalink raw reply
* Re: [PATCH v10 12/21] gpu: nova-core: mm: Add unified page table entry wrapper enums
From: Joel Fernandes @ 2026-04-09 10:33 UTC (permalink / raw)
To: John Hubbard
Cc: Joel Fernandes, Eliot Courtney, linux-kernel, Miguel Ojeda,
Boqun Feng, Gary Guo, Bjorn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
Dave Airlie, Daniel Almeida, Koen Koning, dri-devel,
rust-for-linux, Nikola Djukic, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Jonathan Corbet,
Alex Deucher, Christian Koenig, Jani Nikula, Joonas Lahtinen,
Vivi Rodrigo, Tvrtko Ursulin, Rui Huang, Matthew Auld,
Matthew Brost, Lucas De Marchi, Thomas Hellstrom, Helge Deller,
Alex Gaynor, Boqun Feng, Alistair Popple, Timur Tabi, Edwin Peer,
Alexandre Courbot, Andrea Righi, Andy Ritger, Zhi Wang,
Balbir Singh, Philipp Stanner, Elle Rhumsaa, Alexey Ivanov,
linux-doc, amd-gfx, intel-gfx, intel-xe, linux-fbdev
In-Reply-To: <42dd707f-e23a-4725-8b6f-08ca346b0143@nvidia.com>
> On Apr 8, 2026, at 7:13 PM, John Hubbard <jhubbard@nvidia.com> wrote:
>
> On 4/8/26 9:58 AM, Joel Fernandes wrote:
>>> On 4/8/2026 9:26 AM, Eliot Courtney wrote:
>>> On Tue Apr 7, 2026 at 10:59 PM JST, Joel Fernandes wrote:
>>>> On 4/7/2026 9:42 AM, Eliot Courtney wrote:
>>>>> On Tue Apr 7, 2026 at 6:55 AM JST, Joel Fernandes wrote:
> ...>> [1]: https://github.com/Edgeworth/linux/commits/review/nova-mm-v10/
>> First, thanks for the effort. I looked through this, its pretty much what I
>> had before when I used traits. I don't think it is better to be honest. In
>> fact your version is worse, it adds many new types and things like the
>> following which I did not need before.
>
> Hi Joel and all,
>
> I also looked through Eliot's above attempt carefully, and actually
> liked it a lot (sorry! haha):
>
> * It cleans up the code. The initial working version was readable, but
> also had lots of noise on the screen: match statements and pairs of
> v2/v3 statements.
>
> And interestingly, the mmu_version was, in effect, sporadically
> implementing a Trait-based approach. But because it is custom,
> readers don't benefit as much as they would with Traits, which
> tell you immediately how things are structured.
>
> Joel, I am passionately in agreement with your principles: code must
> be readable on the screen.
>
> In this case, though, Traits make considerably more readable,
> especially if one makes the very reasonable assumption that readers are
> thoroughly accustomed to dealing with Rust traits.
>
>>
>> To put it mildly, the following suggestion should not be anywhere near my code:
>>
>
> lol I understand, believe me. But this is short and not too bad, really.
>
>> /// Type-erased MMU-specific [`Vmm`] implementations.
>
> Type erasure remains a semi-exotic thing, IMHO. As such, another
> sentence to elaborate on this would be a nice touch.
>
>> enum VmmInner {
>> /// `Vmm` implementation for MMU v2.
>> V2(VmmImpl<MmuV2>),
>> /// `Vmm` implementation for MMU v3.
>> V3(VmmImpl<MmuV3>),
>> }
>>
>> /// MMU-specific [`Vmm`] implementation.
>> struct VmmImpl<M: Mmu> {
>>
>> Seriously, I have to pass on this. :-)
>>
>> And, you unfortunately seem to have ignored my point about requiring 4 NEW
>> traits (Mmu, PteOps, PdeOps, DualPdeOps etc), which I did not need before.
>> So you're making the code much much worse than before actually. We don't
>> new traits and types pointlessly.
>
> They are not pointless.
>
> However! What I think would be nice is: do a new v11 with approximately
> this approach, and then we can beat it into being as readable as
> possible.
Since it is 3 against 1 here, I rest my case :-). I am still in
disagreement since I do not see much benefit (that is why I said
pointless above). Actually it is not even about readability, that is
subjective (and I haven’t heard most people say parametrizing code for
the sake of it makes it more readable anyway). It is that the code gen
is worse, and the complexity is just moved to a higher level in the
code, not removed. So what are we getting out of this really, other than
more boiler plate in higher layers of the code that did not exist
before? Not performance, not better generated code. Really nothing. See
all the data points in my previous reply.
Note that if the mmu version threading bothers everyone so much, we can
also pass down chipset instead and let the walker deal with determining
versioning. Would that be better?
But otherwise and since you guys asked, here comes a parameterized v11... ;-).
(Coming next week since this week I’m working on IRQ handling).
thanks,
--
Joel Fernandes
^ permalink raw reply
* 回复: Re: [PATCH] fbdev: omap2: fix inconsistent lock returns in omapfb_mmap
From: 曾红玲 @ 2026-04-09 9:33 UTC (permalink / raw)
To: linux-omap, linux-fbdev, dri-devel, Helge Deller
Cc: linux-kernel, zhongling0719, kernel test robot
[-- Attachment #1: Type: text/html, Size: 2312 bytes --]
^ permalink raw reply
* Re: [PATCH] fbdev: omap2: fix inconsistent lock returns in omapfb_mmap
From: Helge Deller @ 2026-04-09 8:29 UTC (permalink / raw)
To: zenghongling, linux-omap, linux-fbdev, dri-devel
Cc: linux-kernel, zhongling0719, kernel test robot
In-Reply-To: <20260402093403.12173-1-zenghongling@kylinos.cn>
On 4/2/26 11:34, zenghongling wrote:
> Fix the warning about inconsistent returns for '&rg->lock' in
> omapfb_mmap() function. The warning arises because the error path
> uses 'ofbi->region' while the normal path uses 'rg'.
>
> smatch warnings:
> drivers/video/fbdev/omap2/omapfb/omapfb-main.c:1126 omapfb_mmap()
> warn: inconsistent returns '&rg->lock'.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Signed-off-by: zenghongling <zenghongling@kylinos.cn>
> ---
> drivers/video/fbdev/omap2/omapfb/omapfb-main.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
applied.
PS: I replaced author/email name by "Hongling Zeng" instead of "zenghongling".
I assume that's Ok, if not please let me know.
Thanks!
Helge
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox