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...