Skip to contentSkip to conversation

untangling asm/param.h

RFC PATCH In review Al Viro 2 participants 8 messages Dec 2, 2024 – Jun 20, 2025

Subsystems (5)
lore
Share & tools
lore

Al Viro

author
#0 lore raw

RFC PATCH 1/1 untangling asm/param.h

Currently the kernel-side include of asm/param.h is handled in four different ways, depending upon the architecture:

1) alpha:
asm/param.h resolves to arch/alpha/include/asm/param.h, which
* pulls uapi/asm/param.h (resolves to arch/alpha/include/uapi/asm/param.h)
* which defines HZ, EXEC_PAGESIZE, NOGROUP and MAXHOSTNAMELEN
* undefines HZ
* redefines HZ to CONFIG_HZ
* defines USER_HZ to 1024, which is what uapi/asm/param.h had for HZ
* defines CLOCKS_PER_SEC to USER_HZ

2) arc, arm, csky, microblaze, nios2, parisc, powerpc, riscv, s390, sh, x86:
asm/param.h resolves to (generated) arch/$ARCH/include/uapi/asm/param.h, which
* pulls asm-generic/param.h, which resolves to include/asm-generic/param.h, which
* pulls uapi/asm-generic/param.h (resolves to include/uapi/asm-generic/param.h)
* which defines HZ, EXEC_PAGESIZE, NOGROUP and MAXHOSTNAMELEN
* undefines HZ
* redefines HZ to CONFIG_HZ
* defines USER_HZ to 100, which is what uapi/asm-generic/param.h had for HZ
* defines CLOCKS_PER_SEC to USER_HZ

3) arm64, hexagon, m68k, mips, openrisc, sparc:
asm/param.h resolves to arch/$ARCH/include/uapi/asm/param.h, which
* defines EXEC_PAGESIZE
* pulls asm-generic/param.h, which resolves to include/asm-generic/param.h, which
* pulls uapi/asm-generic/param.h (resolves to include/uapi/asm-generic/param.h)
* which defines HZ, NOGROUP and MAXHOSTNAMELEN
* undefines HZ
* redefines HZ to CONFIG_HZ
* defines USER_HZ to 100, which is what uapi/asm-generic/param.h had for HZ
* defines CLOCKS_PER_SEC to USER_HZ

4) loongarch, um, xtensa:
asm/param.h resolves to (generated) arch/$ARCH/include/asm/param.h, which
* pulls asm-generic/param.h, which resolves to include/asm-generic/param.h, which
* pulls uapi/asm-generic/param.h (resolves to include/uapi/asm-generic/param.h)
* which defines HZ, EXEC_PAGESIZE, NOGROUP and MAXHOSTNAMELEN
* undefines HZ
* redefines HZ to CONFIG_HZ
* defines USER_HZ to 100, which is what uapi/asm-generic/param.h had for HZ
* defines CLOCKS_PER_SEC to USER_HZ

There is an additional complication for userland side of xtensa - it has a private copy of include/uapi/asm-generic/param.h, with extra definition (NGROUPS) stuck in it.

Once upon a time we used to have NGROUPS in all asm/param.h (all with the same value); in 2004 that got removed, along with the limit on number of supplementary groups. Unfortunately, xtensa port got started out of tree before the purge and hadn't been merged into mainline until 2005, and several years down the road that was enough to escape the consolidation of asm/param.h.

The difference between alpha and the rest of architectures is that on alpha the userland HZ is not 100 but 1024. That wouldn't be a big deal, but kernel-side we want the userland definition seen as USER_HZ, with HZ itself redefined as CONFIG_HZ. Since nothing in the macro body gets expanded at #define time, there's no way to preserve the value HZ had been defined to - not after we redefine it.

This series massages the things to simpler and more uniform shape. By the end of it,
* all arch/*/include/uapi/asm/param.h are either generated includes
of <asm-generic/param.h> or a #define or two followed by such include.
* no arch/*/include/asm/param.h anywhere, generated or not.
* include <asm/param.h> resolves to arch/*/include/uapi/asm/param.h
of the architecture in question (or that of host in case of uml).
* include/asm-generic/param.h pulls uapi/asm-generic/param.h and
deals with USER_HZ, CLOCKS_PER_SEC and with HZ redefinition after that.

Branch lives in
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git #headers.param individual patches in followups. Review and testing would be welcome...

author
#1 lore raw

PATCH 1/3 xtensa: get rid uapi/asm/param.h

The only difference between it and generic is the stray (and utterly useless) definition of NGROUPS. It had been removed on all architectures back in 2004; xtensa port began prior to that and hadn't been merged until 2005, so it had missed the purge.

---
 arch/xtensa/include/uapi/asm/param.h | 31 ----------------------------
 1 file changed, 31 deletions(-)
 delete mode 100644 arch/xtensa/include/uapi/asm/param.h
arch/xtensa/include/uapi/asm/param.h deleted +0 -31
deleted file mode 100644
index e6feb4ee0590..000000000000
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * include/asm-xtensa/param.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
- */
-
-#ifndef _UAPI_XTENSA_PARAM_H
-#define _UAPI_XTENSA_PARAM_H
-
-#ifndef __KERNEL__
-# define HZ		100
-#endif
-
-#define EXEC_PAGESIZE	4096
-
-#ifndef NGROUPS
-#define NGROUPS		32
-#endif
-
-#ifndef NOGROUP
-#define NOGROUP		(-1)
-#endif
-
-#define MAXHOSTNAMELEN	64	/* max length of hostname */
-
-#endif /* _UAPI_XTENSA_PARAM_H */
Signature · 1 line
2.39.5
maintainer Reviewed-by on v1 1/3
#2 lore raw

Re: [PATCH 1/3] xtensa: get rid uapi/asm/param.h

Quoted 6 lines · Al Viro

The only difference between it and generic is the stray (and utterly useless) definition of NGROUPS. It had been removed on all architectures back in 2004; xtensa port began prior to that and hadn't been merged until 2005, so it had missed the purge.

author
#3 lore raw

PATCH 2/3 alpha: regularize the situation with asm/param.h

In reply to Al Viro

The only reason why alpha can't do what sparc et.al. are doing is that include/asm-generic/param.h relies upon the value of HZ set for userland header in uapi/asm/param.h being 100.

We need that value to define USER_HZ and we need that definition to outlive the redefinition of HZ kernel-side. And alpha needs it to be 1024, not 100 like everybody else.

So let's add __USER_HZ to uapi/asm-generic/param.h, defaulting to 100 and used to define HZ. That way include/asm-generic/param.h can use that thing instead of open-coding it - it won't be affected by undefining and redefining HZ.

That done, alpha asm/param.h can be removed and uapi/asm/param.h switched to defining __USER_HZ and EXEC_PAGESIZE and then including <asm-generic/param.h> - asm/param.h will resolve to uapi/asm/param.h, which pulls <asm-generic/param.h>, which will do the right thing both in the kernel and userland contexts.

---
 arch/alpha/include/asm/param.h      | 12 ------------
 arch/alpha/include/uapi/asm/param.h |  9 ++-------
 include/asm-generic/param.h         |  2 +-
 include/uapi/asm-generic/param.h    |  6 +++++-
 4 files changed, 8 insertions(+), 21 deletions(-)
 delete mode 100644 arch/alpha/include/asm/param.h
arch/alpha/include/asm/param.h deleted +0 -12
deleted file mode 100644
index cfe947ce9461..000000000000
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_ALPHA_PARAM_H
-#define _ASM_ALPHA_PARAM_H
-
-#include <uapi/asm/param.h>
-
-# undef HZ
-# define HZ		CONFIG_HZ
-# define USER_HZ	1024
-# define CLOCKS_PER_SEC	USER_HZ	/* frequency at which times() counts */
-
-#endif /* _ASM_ALPHA_PARAM_H */
arch/alpha/include/uapi/asm/param.h +2 -7
index 49c7119934e2..e4e410f9bf85 100644
@@ -2,14 +2,9 @@
 #ifndef _UAPI_ASM_ALPHA_PARAM_H
 #define _UAPI_ASM_ALPHA_PARAM_H
 
-#define HZ		1024
-
+#define __USER_HZ	1024
 #define EXEC_PAGESIZE	8192
 
-#ifndef NOGROUP
-#define NOGROUP		(-1)
-#endif
-
-#define MAXHOSTNAMELEN	64	/* max length of hostname */
+#include <asm-generic/param.h>
 
 #endif /* _UAPI_ASM_ALPHA_PARAM_H */
include/asm-generic/param.h +1 -1
index 8d3009dd28ff..8348c116aa3b 100644
@@ -6,6 +6,6 @@
 
 # undef HZ
 # define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
-# define USER_HZ	100		/* some user interfaces are */
+# define USER_HZ	__USER_HZ	/* some user interfaces are */
 # define CLOCKS_PER_SEC	(USER_HZ)       /* in "ticks" like times() */
 #endif /* __ASM_GENERIC_PARAM_H */
include/uapi/asm-generic/param.h +5 -1
index baad02ea7f93..3ed505dfea13 100644
@@ -2,8 +2,12 @@
 #ifndef _UAPI__ASM_GENERIC_PARAM_H
 #define _UAPI__ASM_GENERIC_PARAM_H
 
+#ifndef __USER_HZ
+#define __USER_HZ	100
+#endif
+
 #ifndef HZ
-#define HZ 100
+#define HZ __USER_HZ
 #endif
 
 #ifndef EXEC_PAGESIZE
Signature · 1 line
2.39.5
maintainer Reviewed-by on v1 2/3
#4 lore raw

Re: [PATCH 2/3] alpha: regularize the situation with asm/param.h

Quoted 13 lines · Al Viro

The only reason why alpha can't do what sparc et.al. are doing is that include/asm-generic/param.h relies upon the value of HZ set for userland header in uapi/asm/param.h being 100.

We need that value to define USER_HZ and we need that definition to outlive the redefinition of HZ kernel-side. And alpha needs it to be 1024, not 100 like everybody else.

So let's add __USER_HZ to uapi/asm-generic/param.h, defaulting to 100 and used to define HZ. That way include/asm-generic/param.h can use that thing instead of open-coding it - it won't be affected by undefining and redefining HZ.

Quoted 7 lines

That done, alpha asm/param.h can be removed and uapi/asm/param.h switched to defining __USER_HZ and EXEC_PAGESIZE and then including <asm-generic/param.h> - asm/param.h will resolve to uapi/asm/param.h, which pulls <asm-generic/param.h>, which will do the right thing both in the kernel and userland contexts.

Looks correct to me, though after looking at it for a bit I think I came up with a way to simplify it further:

Quoted 8 lines

index 49c7119934e2..e4e410f9bf85 100644

arch/alpha/include/uapi/asm/param.h +0 -1
@@ -2,14 +2,9 @@
 #ifndef _UAPI_ASM_ALPHA_PARAM_H
 #define _UAPI_ASM_ALPHA_PARAM_H
 
-#define HZ		1024

arch/alpha/include/uapi/asm/param.h line 8

Quoted 10 lines
arch/alpha/include/uapi/asm/param.h +2 -6
-
+#define __USER_HZ	1024
 #define EXEC_PAGESIZE	8192
 
-#ifndef NOGROUP
-#define NOGROUP		(-1)
-#endif
-
-#define MAXHOSTNAMELEN	64	/* max length of hostname */
+#include <asm-generic/param.h>

If you make this one

#ifdef __KERNEL__
#define USER_HZ 1024
#endif

and rely on 'make headers_install' to drop the USER_HZ macro again, you can avoid the additional __USER_HZ macro and just guard against redefining it in asm-generic/param.h.

With or without that change,

author
#5 lore raw

PATCH 3/3 loongarch, um, xtensa: get rid of generated arch/$ARCH/include/asm/param.h

In reply to Al Viro

For loongarch and xtensa that gets them to do what x86 et.al. are doing - have asm/param.h resolve to uapi variant, which is generated by mandatory-y += param.h and contains exact same include.

On um it will resolve to x86 uapi variant instead, which also contains the same include (um doesn't have uapi headers, but it does build the host ones).

---
 arch/loongarch/include/asm/Kbuild | 1 -
 arch/um/include/asm/Kbuild        | 1 -
 arch/xtensa/include/asm/Kbuild    | 1 -
 3 files changed, 3 deletions(-)
arch/loongarch/include/asm/Kbuild +0 -1
index 80ddb5edb845..b04d2cef935f 100644
@@ -10,5 +10,4 @@ generic-y += user.h
 generic-y += ioctl.h
 generic-y += mmzone.h
 generic-y += statfs.h
-generic-y += param.h
 generic-y += text-patching.h
arch/um/include/asm/Kbuild +0 -1
index 428f2c5158c2..2bd0cd046652 100644
@@ -14,7 +14,6 @@ generic-y += kdebug.h
 generic-y += mcs_spinlock.h
 generic-y += mmiowb.h
 generic-y += module.lds.h
-generic-y += param.h
 generic-y += parport.h
 generic-y += percpu.h
 generic-y += preempt.h
arch/xtensa/include/asm/Kbuild +0 -1
index cc5dba738389..13fe45dea296 100644
@@ -3,7 +3,6 @@ generated-y += syscall_table.h
 generic-y += extable.h
 generic-y += kvm_para.h
 generic-y += mcs_spinlock.h
-generic-y += param.h
 generic-y += parport.h
 generic-y += qrwlock.h
 generic-y += qspinlock.h
Signature · 1 line
2.39.5
maintainer Reviewed-by on v1 3/3
#6 lore raw

Re: [PATCH 3/3] loongarch, um, xtensa: get rid of generated arch/$ARCH/include/asm/param.h

Quoted 9 lines · Al Viro

For loongarch and xtensa that gets them to do what x86 et.al. are doing - have asm/param.h resolve to uapi variant, which is generated by mandatory-y += param.h and contains exact same include.

On um it will resolve to x86 uapi variant instead, which also contains the same include (um doesn't have uapi headers, but it does build the host ones).

author
#7 lore raw
In reply to Al Viro
Quoted 61 lines · Al Viro

Currently the kernel-side include of asm/param.h is handled in four different ways, depending upon the architecture:

1) alpha:
asm/param.h resolves to arch/alpha/include/asm/param.h, which
* pulls uapi/asm/param.h (resolves to arch/alpha/include/uapi/asm/param.h)
* which defines HZ, EXEC_PAGESIZE, NOGROUP and MAXHOSTNAMELEN
* undefines HZ
* redefines HZ to CONFIG_HZ
* defines USER_HZ to 1024, which is what uapi/asm/param.h had for HZ
* defines CLOCKS_PER_SEC to USER_HZ

2) arc, arm, csky, microblaze, nios2, parisc, powerpc, riscv, s390, sh, x86:
asm/param.h resolves to (generated) arch/$ARCH/include/uapi/asm/param.h, which
* pulls asm-generic/param.h, which resolves to include/asm-generic/param.h, which
* pulls uapi/asm-generic/param.h (resolves to include/uapi/asm-generic/param.h)
* which defines HZ, EXEC_PAGESIZE, NOGROUP and MAXHOSTNAMELEN
* undefines HZ
* redefines HZ to CONFIG_HZ
* defines USER_HZ to 100, which is what uapi/asm-generic/param.h had for HZ
* defines CLOCKS_PER_SEC to USER_HZ

3) arm64, hexagon, m68k, mips, openrisc, sparc:
asm/param.h resolves to arch/$ARCH/include/uapi/asm/param.h, which
* defines EXEC_PAGESIZE
* pulls asm-generic/param.h, which resolves to include/asm-generic/param.h, which
* pulls uapi/asm-generic/param.h (resolves to include/uapi/asm-generic/param.h)
* which defines HZ, NOGROUP and MAXHOSTNAMELEN
* undefines HZ
* redefines HZ to CONFIG_HZ
* defines USER_HZ to 100, which is what uapi/asm-generic/param.h had for HZ
* defines CLOCKS_PER_SEC to USER_HZ

4) loongarch, um, xtensa:
asm/param.h resolves to (generated) arch/$ARCH/include/asm/param.h, which
* pulls asm-generic/param.h, which resolves to include/asm-generic/param.h, which
* pulls uapi/asm-generic/param.h (resolves to include/uapi/asm-generic/param.h)
* which defines HZ, EXEC_PAGESIZE, NOGROUP and MAXHOSTNAMELEN
* undefines HZ
* redefines HZ to CONFIG_HZ
* defines USER_HZ to 100, which is what uapi/asm-generic/param.h had for HZ
* defines CLOCKS_PER_SEC to USER_HZ

There is an additional complication for userland side of xtensa - it has a private copy of include/uapi/asm-generic/param.h, with extra definition (NGROUPS) stuck in it.

Once upon a time we used to have NGROUPS in all asm/param.h (all with the same value); in 2004 that got removed, along with the limit on number of supplementary groups. Unfortunately, xtensa port got started out of tree before the purge and hadn't been merged into mainline until 2005, and several years down the road that was enough to escape the consolidation of asm/param.h.

The difference between alpha and the rest of architectures is that on alpha the userland HZ is not 100 but 1024. That wouldn't be a big deal, but kernel-side we want the userland definition seen as USER_HZ, with HZ itself redefined as CONFIG_HZ. Since nothing in the macro body gets expanded at #define time, there's no way to preserve the value HZ had been defined to - not after we redefine it.

Quoted 9 lines

This series massages the things to simpler and more uniform shape. By the end of it,
* all arch/*/include/uapi/asm/param.h are either generated includes
of <asm-generic/param.h> or a #define or two followed by such include.
* no arch/*/include/asm/param.h anywhere, generated or not.
* include <asm/param.h> resolves to arch/*/include/uapi/asm/param.h
of the architecture in question (or that of host in case of uml).
* include/asm-generic/param.h pulls uapi/asm-generic/param.h and
deals with USER_HZ, CLOCKS_PER_SEC and with HZ redefinition after that.

Branch rebased to 6.16-rc1 and force-pushed to
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git #headers.param

No changes in patches since the last time around; see
https://lore.kernel.org/all/20241202040207.GM3387508@ZenIV/ for the old posting.

Folks, if nobody objects, I'm putting this stuff into -next this cycle.