On Fri, Oct 02, 2026 at 10:40:38AM +0200, Petr Pavlu wrote: > Module-related stubs for CONFIG_MODULES=n can normally live in > linux/module.h. This works well when the stub does nothing or simply > returns a constant. However, some non-module implementations may be more > expensive, either because they have a real implementation or because they > require additional dependencies to be pulled into linux/module.h. This > header appears in roughly 15k #include directives across the kernel, so it > should avoid bringing in unnecessary definitions. > > Specifically, linux/module.h defines module_put_and_kthread_exit() as an > alias for kthread_exit() when CONFIG_MODULES=n. That in turn requires > linux/kthread.h, even though linux/module.h otherwise has no need for it. > Note that linux/module.h currently doesn't include linux/kthread.h and > requires its users to pick it up through other paths, which is itself not > quite right. > > Introduce kernel/module/stubs.c to hold such stubs, built only for > CONFIG_MODULES=n. This mirrors kernel/time/posix-stubs.c, which is used for > CONFIG_POSIX_TIMERS=n. > > Define module_put_and_kthread_exit() in both CONFIG_MODULES configurations > to call __module_put_and_kthread_exit() and add a CONFIG_MODULES=n > implementation of that function to kernel/module/stubs.c. Since > __module_put_and_kthread_exit() is now implemented even when > CONFIG_MODULES=n, remove the corresponding '#ifdef CONFIG_MODULES' from the > noreturn_deny BPF list. > > Signed-off-by: Petr Pavlu <[email protected]> > --- > kernel/module/stubs.c should also be used for add_taint_module() [1] in the > future. > > [1] > https://lore.kernel.org/linux-modules/[email protected]/ > --- > Changes in v2: > - Remove the unnecessary include of internal.h in stubs.c. > - Remove the unnecessary EXPORT_SYMBOL(__module_put_and_kthread_exit) in > stubs.c. > - Link to v1: > https://patch.msgid.link/[email protected] > --- > include/linux/module.h | 9 +++------ > kernel/Makefile | 2 +- > kernel/bpf/verifier.c | 2 -- > kernel/module/Makefile | 4 ++++ > kernel/module/main.c | 1 + > kernel/module/stubs.c | 9 +++++++++ > 6 files changed, 18 insertions(+), 9 deletions(-) > > diff --git a/include/linux/module.h b/include/linux/module.h > index 96cc98568eea..4c7bd7f9f889 100644 > --- a/include/linux/module.h > +++ b/include/linux/module.h > @@ -658,10 +658,6 @@ static inline bool within_module(unsigned long addr, > const struct module *mod) > /* Search for module by name: must be in a RCU critical section. */ > struct module *find_module(const char *name); > > -extern void __noreturn __module_put_and_kthread_exit(struct module *mod, > - long code); > -#define module_put_and_kthread_exit(code) > __module_put_and_kthread_exit(THIS_MODULE, code) > - > #ifdef CONFIG_MODULE_UNLOAD > int module_refcount(struct module *mod); > void __symbol_put(const char *symbol); > @@ -850,8 +846,6 @@ static inline int unregister_module_notifier(struct > notifier_block *nb) > return 0; > } > > -#define module_put_and_kthread_exit(code) kthread_exit(code) > - > static inline void print_modules(void) > { > } > @@ -879,6 +873,9 @@ static inline void module_for_each_mod(int(*func)(struct > module *mod, void *data > } > #endif /* CONFIG_MODULES */ > > +void __noreturn __module_put_and_kthread_exit(struct module *mod, long code); > +#define module_put_and_kthread_exit(code) > __module_put_and_kthread_exit(THIS_MODULE, code) > + > #ifdef CONFIG_SYSFS > extern struct kset *module_kset; > extern const struct kobj_type module_ktype; > diff --git a/kernel/Makefile b/kernel/Makefile > index 1e1a31673577..08a94594975d 100644 > --- a/kernel/Makefile > +++ b/kernel/Makefile > @@ -58,7 +58,7 @@ obj-y += liveupdate/ > obj-y += dma/ > obj-y += entry/ > obj-y += unwind/ > -obj-$(CONFIG_MODULES) += module/ > +obj-y += module/ > > obj-$(CONFIG_KCMP) += kcmp.o > obj-$(CONFIG_FREEZER) += freezer.o > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index 72a3f5998dd2..be70f10e4968 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -20417,9 +20417,7 @@ BTF_ID(func, __ia32_sys_exit_group) > BTF_ID(func, __kunit_abort) > BTF_ID(func, kunit_try_catch_throw) > #endif > -#ifdef CONFIG_MODULES > BTF_ID(func, __module_put_and_kthread_exit) > -#endif > #ifdef CONFIG_X86_64 > BTF_ID(func, __x64_sys_exit) > BTF_ID(func, __x64_sys_exit_group) > diff --git a/kernel/module/Makefile b/kernel/module/Makefile > index 50ffcc413b54..72fd2972eacf 100644 > --- a/kernel/module/Makefile > +++ b/kernel/module/Makefile > @@ -7,6 +7,7 @@ > # and produce insane amounts of uninteresting coverage. > KCOV_INSTRUMENT_main.o := n > > +ifeq ($(CONFIG_MODULES),y) > obj-y += main.o > obj-y += strict_rwx.o > obj-y += kmod.o > @@ -23,3 +24,6 @@ obj-$(CONFIG_KGDB_KDB) += kdb.o > obj-$(CONFIG_MODVERSIONS) += version.o > obj-$(CONFIG_MODULE_UNLOAD_TAINT_TRACKING) += tracking.o > obj-$(CONFIG_MODULE_STATS) += stats.o > +else > +obj-y += stubs.o > +endif > diff --git a/kernel/module/main.c b/kernel/module/main.c > index d0e1e0bd2ad0..a8bf803afa81 100644 > --- a/kernel/module/main.c > +++ b/kernel/module/main.c > @@ -60,6 +60,7 @@ > #include <linux/codetag.h> > #include <linux/debugfs.h> > #include <linux/execmem.h> > +#include <linux/kthread.h> > #include <uapi/linux/module.h> > #include "internal.h" > > diff --git a/kernel/module/stubs.c b/kernel/module/stubs.c > new file mode 100644 > index 000000000000..1385c87e8169 > --- /dev/null > +++ b/kernel/module/stubs.c > @@ -0,0 +1,9 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > + > +#include <linux/kthread.h> > +#include <linux/module.h> > + > +void __noreturn __module_put_and_kthread_exit(struct module *mod, long code) > +{ > + kthread_exit(code); > +} > > --- > base-commit: 93f51579e7df248780214094418f205253383cc5 > change-id: 20260918-module-stubs-dccefe41dace
Hi Petr, I noticed your response to Sashiko [1]. I agree. Marking the stub function with "__used __retain" in kernel/module/stubs.c (e.g. as per "#define __bpf_kfunc __used __retain __noclone noinline") should be sufficient. Thank you. Reviewed-by: Aaron Tomlin <[email protected]> [1]: https://lore.kernel.org/sashiko-reviews/[email protected]/ Kind regards, -- Aaron Tomlin

