diff options
author | Peter Zijlstra <peterz@infradead.org> | 2015-05-26 21:39:35 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-05-27 22:01:52 -0400 |
commit | 0be964be0d45084245673c971d72a4b51690231d (patch) | |
tree | c3d0f0497d325c28f344adda9c3305e75e550c60 /lib | |
parent | bed831f9a251968272dae10a83b512c7db256ef0 (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.c | 7 |
1 files changed, 5 insertions, 2 deletions
@@ -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; |
79 | out: | 79 | out: |
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 | ||
114 | void module_bug_cleanup(struct module *mod) | 116 | void 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 | ||