summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2015-05-26 21:39:35 -0400
committerRusty Russell <rusty@rustcorp.com.au>2015-05-27 22:01:52 -0400
commit0be964be0d45084245673c971d72a4b51690231d (patch)
treec3d0f0497d325c28f344adda9c3305e75e550c60 /lib
parentbed831f9a251968272dae10a83b512c7db256ef0 (diff)
module: Sanitize RCU usage and locking
Currently the RCU usage in module is an inconsistent mess of RCU and RCU-sched, this is broken for CONFIG_PREEMPT where synchronize_rcu() does not imply synchronize_sched(). Most usage sites use preempt_{dis,en}able() which is RCU-sched, but (most of) the modification sites use synchronize_rcu(). With the exception of the module bug list, which actually uses RCU. Convert everything over to RCU-sched. Furthermore add lockdep asserts to all sites, because it's not at all clear to me the required locking is observed, esp. on exported functions. Cc: Rusty Russell <rusty@rustcorp.com.au> Acked-by: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'lib')
-rw-r--r--lib/bug.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/lib/bug.c b/lib/bug.c
index 0c3bd9552b6f..cff145f032a5 100644
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -66,7 +66,7 @@ static const struct bug_entry *module_find_bug(unsigned long bugaddr)
66 struct module *mod; 66 struct module *mod;
67 const struct bug_entry *bug = NULL; 67 const struct bug_entry *bug = NULL;
68 68
69 rcu_read_lock(); 69 rcu_read_lock_sched();
70 list_for_each_entry_rcu(mod, &module_bug_list, bug_list) { 70 list_for_each_entry_rcu(mod, &module_bug_list, bug_list) {
71 unsigned i; 71 unsigned i;
72 72
@@ -77,7 +77,7 @@ static const struct bug_entry *module_find_bug(unsigned long bugaddr)
77 } 77 }
78 bug = NULL; 78 bug = NULL;
79out: 79out:
80 rcu_read_unlock(); 80 rcu_read_unlock_sched();
81 81
82 return bug; 82 return bug;
83} 83}
@@ -88,6 +88,8 @@ void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
88 char *secstrings; 88 char *secstrings;
89 unsigned int i; 89 unsigned int i;
90 90
91 lockdep_assert_held(&module_mutex);
92
91 mod->bug_table = NULL; 93 mod->bug_table = NULL;
92 mod->num_bugs = 0; 94 mod->num_bugs = 0;
93 95
@@ -113,6 +115,7 @@ void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
113 115
114void module_bug_cleanup(struct module *mod) 116void module_bug_cleanup(struct module *mod)
115{ 117{
118 lockdep_assert_held(&module_mutex);
116 list_del_rcu(&mod->bug_list); 119 list_del_rcu(&mod->bug_list);
117} 120}
118 121