lkml.org 
[lkml]   [2010]   [Feb]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 07/10] module: __rcu annotations
Date
These are partial, because the modules list is used
inconsistently with RCU. We actually pass a list_head
of an RCU protected list into another function.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
include/linux/module.h | 4 ++--
kernel/module.c | 20 +++++++++++++-------
2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/include/linux/module.h b/include/linux/module.h
index 6cb1a3c..94ce22e 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -6,7 +6,7 @@
* Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
* Rewritten again by Rusty Russell, 2002
*/
-#include <linux/list.h>
+#include <linux/rculist.h>
#include <linux/stat.h>
#include <linux/compiler.h>
#include <linux/cache.h>
@@ -238,7 +238,7 @@ struct module
enum module_state state;

/* Member of list of modules */
- struct list_head list;
+ struct rcu_list_head list;

/* Unique handle for this module */
char name[MODULE_NAME_LEN];
diff --git a/kernel/module.c b/kernel/module.c
index f82386b..d8b7603 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -78,7 +78,7 @@ EXPORT_TRACEPOINT_SYMBOL(module_get);
* (delete uses stop_machine/add uses RCU list operations). */
DEFINE_MUTEX(module_mutex);
EXPORT_SYMBOL_GPL(module_mutex);
-static LIST_HEAD(modules);
+static LIST_HEAD_RCU(modules);

/* Block module loading/unloading? */
int modules_disabled = 0;
@@ -360,10 +360,12 @@ struct module *find_module(const char *name)
{
struct module *mod;

- list_for_each_entry(mod, &modules, list) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(mod, &modules, list) {
if (strcmp(mod->name, name) == 0)
return mod;
}
+ rcu_read_unlock();
return NULL;
}
EXPORT_SYMBOL_GPL(find_module);
@@ -544,7 +546,8 @@ static void module_unload_free(struct module *mod)
{
struct module *i;

- list_for_each_entry(i, &modules, list) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(i, &modules, list) {
struct module_use *use;

list_for_each_entry(use, &i->modules_which_use_me, list) {
@@ -559,6 +562,7 @@ static void module_unload_free(struct module *mod)
}
}
}
+ rcu_read_unlock();
}

#ifdef CONFIG_MODULE_FORCE_UNLOAD
@@ -1368,7 +1372,7 @@ static void mod_kobject_remove(struct module *mod)
static int __unlink_module(void *_mod)
{
struct module *mod = _mod;
- list_del(&mod->list);
+ list_del_rcu(&mod->list);
return 0;
}

@@ -2718,7 +2722,8 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
unsigned int i;
int ret;

- list_for_each_entry(mod, &modules, list) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(mod, &modules, list) {
for (i = 0; i < mod->num_symtab; i++) {
ret = fn(data, mod->strtab + mod->symtab[i].st_name,
mod, mod->symtab[i].st_value);
@@ -2726,6 +2731,7 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
return ret;
}
}
+ rcu_read_unlock();
return 0;
}
#endif /* CONFIG_KALLSYMS */
@@ -2768,12 +2774,12 @@ static char *module_flags(struct module *mod, char *buf)
static void *m_start(struct seq_file *m, loff_t *pos)
{
mutex_lock(&module_mutex);
- return seq_list_start(&modules, *pos);
+ return seq_list_start((struct list_head *)&modules, *pos);
}

static void *m_next(struct seq_file *m, void *p, loff_t *pos)
{
- return seq_list_next(p, &modules, pos);
+ return seq_list_next(p, (struct list_head *)&modules, pos);
}

static void m_stop(struct seq_file *m, void *p)
--
1.6.3.3


\
 
 \ /
  Last update: 2010-02-24 21:07    [W:0.103 / U:0.880 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site