bug: Use RCU instead RCU-sched to protect module_bug_list.

The list module_bug_list relies on module_mutex for writer
synchronisation. The list is already RCU style.
The list removal is synchronized with modules' synchronize_rcu() in
free_module().

Use RCU read lock protection instead of RCU-sched.

Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20250108090457.512198-29-bigeasy@linutronix.de
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
This commit is contained in:
Sebastian Andrzej Siewior 2025-01-08 10:04:57 +01:00 committed by Petr Pavlu
parent 3983da398c
commit f47d2a3f75

View File

@ -66,23 +66,19 @@ static LIST_HEAD(module_bug_list);
static struct bug_entry *module_find_bug(unsigned long bugaddr) static struct bug_entry *module_find_bug(unsigned long bugaddr)
{ {
struct bug_entry *bug;
struct module *mod; struct module *mod;
struct bug_entry *bug = NULL;
rcu_read_lock_sched(); guard(rcu)();
list_for_each_entry_rcu(mod, &module_bug_list, bug_list) { list_for_each_entry_rcu(mod, &module_bug_list, bug_list) {
unsigned i; unsigned i;
bug = mod->bug_table; bug = mod->bug_table;
for (i = 0; i < mod->num_bugs; ++i, ++bug) for (i = 0; i < mod->num_bugs; ++i, ++bug)
if (bugaddr == bug_addr(bug)) if (bugaddr == bug_addr(bug))
goto out; return bug;
} }
bug = NULL; return NULL;
out:
rcu_read_unlock_sched();
return bug;
} }
void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
@ -235,11 +231,11 @@ void generic_bug_clear_once(void)
#ifdef CONFIG_MODULES #ifdef CONFIG_MODULES
struct module *mod; struct module *mod;
rcu_read_lock_sched(); scoped_guard(rcu) {
list_for_each_entry_rcu(mod, &module_bug_list, bug_list) list_for_each_entry_rcu(mod, &module_bug_list, bug_list)
clear_once_table(mod->bug_table, clear_once_table(mod->bug_table,
mod->bug_table + mod->num_bugs); mod->bug_table + mod->num_bugs);
rcu_read_unlock_sched(); }
#endif #endif
clear_once_table(__start___bug_table, __stop___bug_table); clear_once_table(__start___bug_table, __stop___bug_table);