Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

module: Use RCU in find_symbol().

module_assert_mutex_or_preempt() is not needed in find_symbol(). The
function checks for RCU-sched or the module_mutex to be acquired. The
list_for_each_entry_rcu() below does the same check.

Remove module_assert_mutex_or_preempt() from try_add_tainted_module().
Use RCU protection to invoke find_symbol() and update callers.

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-11-bigeasy@linutronix.de
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>

authored by

Sebastian Andrzej Siewior and committed by
Petr Pavlu
2ff49f89 435bbcc3

+19 -25
+12 -18
kernel/module/main.c
··· 331 331 332 332 /* 333 333 * Find an exported symbol and return it, along with, (optional) crc and 334 - * (optional) module which owns it. Needs preempt disabled or module_mutex. 334 + * (optional) module which owns it. Needs RCU or module_mutex. 335 335 */ 336 336 bool find_symbol(struct find_symbol_arg *fsa) 337 337 { ··· 344 344 }; 345 345 struct module *mod; 346 346 unsigned int i; 347 - 348 - module_assert_mutex_or_preempt(); 349 347 350 348 for (i = 0; i < ARRAY_SIZE(arr); i++) 351 349 if (find_exported_symbol_in_section(&arr[i], NULL, fsa)) ··· 810 812 .gplok = true, 811 813 }; 812 814 813 - preempt_disable(); 815 + guard(rcu)(); 814 816 BUG_ON(!find_symbol(&fsa)); 815 817 module_put(fsa.owner); 816 - preempt_enable(); 817 818 } 818 819 EXPORT_SYMBOL(__symbol_put); 819 820 ··· 1366 1369 .warn = true, 1367 1370 }; 1368 1371 1369 - preempt_disable(); 1370 - if (!find_symbol(&fsa)) 1371 - goto fail; 1372 - if (fsa.license != GPL_ONLY) { 1373 - pr_warn("failing symbol_get of non-GPLONLY symbol %s.\n", 1374 - symbol); 1375 - goto fail; 1372 + scoped_guard(rcu) { 1373 + if (!find_symbol(&fsa)) 1374 + return NULL; 1375 + if (fsa.license != GPL_ONLY) { 1376 + pr_warn("failing symbol_get of non-GPLONLY symbol %s.\n", 1377 + symbol); 1378 + return NULL; 1379 + } 1380 + if (strong_try_module_get(fsa.owner)) 1381 + return NULL; 1376 1382 } 1377 - if (strong_try_module_get(fsa.owner)) 1378 - goto fail; 1379 - preempt_enable(); 1380 1383 return (void *)kernel_symbol_value(fsa.sym); 1381 - fail: 1382 - preempt_enable(); 1383 - return NULL; 1384 1384 } 1385 1385 EXPORT_SYMBOL_GPL(__symbol_get); 1386 1386
+7 -7
kernel/module/version.c
··· 79 79 .name = "module_layout", 80 80 .gplok = true, 81 81 }; 82 + bool have_symbol; 82 83 83 84 /* 84 85 * Since this should be found in kernel (which can't be removed), no 85 - * locking is necessary -- use preempt_disable() to placate lockdep. 86 + * locking is necessary. Regardless use a RCU read section to keep 87 + * lockdep happy. 86 88 */ 87 - preempt_disable(); 88 - if (!find_symbol(&fsa)) { 89 - preempt_enable(); 90 - BUG(); 91 - } 92 - preempt_enable(); 89 + scoped_guard(rcu) 90 + have_symbol = find_symbol(&fsa); 91 + BUG_ON(!have_symbol); 92 + 93 93 return check_version(info, "module_layout", mod, fsa.crc); 94 94 } 95 95