]> www.infradead.org Git - users/hch/misc.git/commitdiff
module: Use RCU in find_module_all().
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Wed, 8 Jan 2025 09:04:35 +0000 (10:04 +0100)
committerPetr Pavlu <petr.pavlu@suse.com>
Mon, 10 Mar 2025 10:54:44 +0000 (11:54 +0100)
The modules list and module::kallsyms can be accessed under RCU
assumption.

Remove module_assert_mutex_or_preempt() from find_module_all() so it can
be used under RCU protection without warnings. Update its callers to use
RCU protection instead of preempt_disable().

Cc: Jiri Kosina <jikos@kernel.org>
Cc: Joe Lawrence <joe.lawrence@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Miroslav Benes <mbenes@suse.cz>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: linux-trace-kernel@vger.kernel.org
Cc: live-patching@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20250108090457.512198-7-bigeasy@linutronix.de
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
include/linux/module.h
kernel/livepatch/core.c
kernel/module/kallsyms.c
kernel/module/main.c
kernel/trace/trace_kprobe.c

index 30e5b19bafa983e70e2a0509e0ccc3d7f58a7d6f..0516f5ea9153b36cffab3c373a71b50b6e2d61e4 100644 (file)
@@ -666,7 +666,7 @@ static inline bool within_module(unsigned long addr, const struct module *mod)
        return within_module_init(addr, mod) || within_module_core(addr, mod);
 }
 
-/* Search for module by name: must be in a RCU-sched critical section. */
+/* 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,
index 0cd39954d5a10f0eb5d64770c6fd39b0335ca4a3..abea193977d21961e4ac02241825824efed54134 100644 (file)
@@ -59,7 +59,7 @@ static void klp_find_object_module(struct klp_object *obj)
        if (!klp_is_module(obj))
                return;
 
-       rcu_read_lock_sched();
+       guard(rcu)();
        /*
         * We do not want to block removal of patched modules and therefore
         * we do not take a reference here. The patches are removed by
@@ -75,8 +75,6 @@ static void klp_find_object_module(struct klp_object *obj)
         */
        if (mod && mod->klp_alive)
                obj->mod = mod;
-
-       rcu_read_unlock_sched();
 }
 
 static bool klp_initialized(void)
index 4eef518204eb540d98e03e2965bcb17c4ffd8de1..3cba9f933b24fc09de0f8dafb75dfbfc37c85320 100644 (file)
@@ -450,6 +450,7 @@ unsigned long module_kallsyms_lookup_name(const char *name)
        unsigned long ret;
 
        /* Don't lock: we're in enough trouble already. */
+       guard(rcu)();
        preempt_disable();
        ret = __module_kallsyms_lookup_name(name);
        preempt_enable();
index 5f661d5343ac7bfd5af8bb560b5c4fa19d171dde..cdd403b940b0daf14cb5a1e5adceacbe40036d59 100644 (file)
@@ -374,16 +374,14 @@ bool find_symbol(struct find_symbol_arg *fsa)
 }
 
 /*
- * Search for module by name: must hold module_mutex (or preempt disabled
- * for read-only access).
+ * Search for module by name: must hold module_mutex (or RCU for read-only
+ * access).
  */
 struct module *find_module_all(const char *name, size_t len,
                               bool even_unformed)
 {
        struct module *mod;
 
-       module_assert_mutex_or_preempt();
-
        list_for_each_entry_rcu(mod, &modules, list,
                                lockdep_is_held(&module_mutex)) {
                if (!even_unformed && mod->state == MODULE_STATE_UNFORMED)
index d8d5f18a141adc780d4a6448591af6780283105d..48057531ee4ebbb9f43121562ff8d3236f59d938 100644 (file)
@@ -124,9 +124,8 @@ static nokprobe_inline bool trace_kprobe_module_exist(struct trace_kprobe *tk)
        if (!p)
                return true;
        *p = '\0';
-       rcu_read_lock_sched();
-       ret = !!find_module(tk->symbol);
-       rcu_read_unlock_sched();
+       scoped_guard(rcu)
+               ret = !!find_module(tk->symbol);
        *p = ':';
 
        return ret;
@@ -796,12 +795,10 @@ static struct module *try_module_get_by_name(const char *name)
 {
        struct module *mod;
 
-       rcu_read_lock_sched();
+       guard(rcu)();
        mod = find_module(name);
        if (mod && !try_module_get(mod))
                mod = NULL;
-       rcu_read_unlock_sched();
-
        return mod;
 }
 #else