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().
Unified · Split
| @@ -666,7 +666,7 @@ static inline bool within_module(unsigned long addr, const struct module *mod) · 665 unmodified lines | ||
| 666 | 666 | return within_module_init(addr, mod) || within_module_core(addr, mod); |
| 667 | 667 | } |
| 668 | 668 | |
| 669 | −/* Search for module by name: must be in a RCU-sched critical section. */ | |
| 669 | +/* Search for module by name: must be in a RCU critical section. */ | |
| 670 | 670 | struct module *find_module(const char *name); |
| 671 | 671 | |
| 672 | 672 | extern void __noreturn __module_put_and_kthread_exit(struct module *mod, |
| @@ -59,7 +59,7 @@ static void klp_find_object_module(struct klp_object *obj) · 58 unmodified lines | ||
| 59 | 59 | if (!klp_is_module(obj)) |
| 60 | 60 | return; |
| 61 | 61 | |
| 62 | − rcu_read_lock_sched(); | |
| 62 | + guard(rcu)(); | |
| 63 | 63 | /* |
| 64 | 64 | * We do not want to block removal of patched modules and therefore |
| 65 | 65 | * 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) · 9 unmodified lines | ||
| 75 | 75 | */ |
| 76 | 76 | if (mod && mod->klp_alive) |
| 77 | 77 | obj->mod = mod; |
| 78 | − | |
| 79 | − rcu_read_unlock_sched(); | |
| 80 | 78 | } |
| 81 | 79 | |
| 82 | 80 | static bool klp_initialized(void) |
| @@ -450,6 +450,7 @@ unsigned long module_kallsyms_lookup_name(const char *name) · 449 unmodified lines | ||
| 450 | 450 | unsigned long ret; |
| 451 | 451 | |
| 452 | 452 | /* Don't lock: we're in enough trouble already. */ |
| 453 | + guard(rcu)(); | |
| 453 | 454 | preempt_disable(); |
| 454 | 455 | ret = __module_kallsyms_lookup_name(name); |
| 455 | 456 | preempt_enable(); |
| @@ -374,16 +374,14 @@ bool find_symbol(struct find_symbol_arg *fsa) · 373 unmodified lines | ||
| 374 | 374 | } |
| 375 | 375 | |
| 376 | 376 | /* |
| 377 | − * Search for module by name: must hold module_mutex (or preempt disabled | |
| 378 | − * for read-only access). | |
| 377 | + * Search for module by name: must hold module_mutex (or RCU for read-only | |
| 378 | + * access). | |
| 379 | 379 | */ |
| 380 | 380 | struct module *find_module_all(const char *name, size_t len, |
| 381 | 381 | bool even_unformed) |
| 382 | 382 | { |
| 383 | 383 | struct module *mod; |
| 384 | 384 | |
| 385 | − module_assert_mutex_or_preempt(); | |
| 386 | − | |
| 387 | 385 | list_for_each_entry_rcu(mod, &modules, list, |
| 388 | 386 | lockdep_is_held(&module_mutex)) { |
| 389 | 387 | if (!even_unformed && mod->state == MODULE_STATE_UNFORMED) |
| @@ -124,9 +124,8 @@ static nokprobe_inline bool trace_kprobe_module_exist(struct trace_kprobe *tk) · 123 unmodified lines | ||
| 124 | 124 | if (!p) |
| 125 | 125 | return true; |
| 126 | 126 | *p = '\0'; |
| 127 | − rcu_read_lock_sched(); | |
| 128 | − ret = !!find_module(tk->symbol); | |
| 129 | − rcu_read_unlock_sched(); | |
| 127 | + scoped_guard(rcu) | |
| 128 | + ret = !!find_module(tk->symbol); | |
| 130 | 129 | *p = ':'; |
| 131 | 130 | |
| 132 | 131 | return ret; |
| @@ -796,12 +795,10 @@ static struct module *try_module_get_by_name(const char *name) · 663 unmodified lines | ||
| 796 | 795 | { |
| 797 | 796 | struct module *mod; |
| 798 | 797 | |
| 799 | − rcu_read_lock_sched(); | |
| 798 | + guard(rcu)(); | |
| 800 | 799 | mod = find_module(name); |
| 801 | 800 | if (mod && !try_module_get(mod)) |
| 802 | 801 | mod = NULL; |
| 803 | − rcu_read_unlock_sched(); | |
| 804 | − | |
| 805 | 802 | return mod; |
| 806 | 803 | } |
| 807 | 804 | #else |