Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=cb2a52052cebe4716e83b9d2e53682ba00f67de6
Commit:     cb2a52052cebe4716e83b9d2e53682ba00f67de6
Parent:     1a1b285c24e1468afe82b09330dde5192a6e0013
Author:     Rusty Russell <[EMAIL PROTECTED]>
AuthorDate: Mon Jan 14 00:55:03 2008 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Mon Jan 14 08:52:22 2008 -0800

    modules: de-mutex more symbol lookup paths in the module code
    
    Kyle McMartin reports sysrq_timer_list_show() can hit the module mutex
    from hard interrupt context.  These paths don't need to though, since we
    long ago changed all the module list manipulation to occur via
    stop_machine().
    
    Disabling preemption is enough.
    
    Signed-off-by: Rusty Russell <[EMAIL PROTECTED]>
    Cc: Ingo Molnar <[EMAIL PROTECTED]>
    Cc: Kyle McMartin <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 kernel/module.c |   29 ++++++++++++++++++-----------
 1 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 91fe695..c2e3e2e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2214,29 +2214,34 @@ static const char *get_ksymbol(struct module *mod,
 /* For kallsyms to ask for address resolution.  NULL means not found.
    We don't lock, as this is used for oops resolution and races are a
    lesser concern. */
+/* FIXME: Risky: returns a pointer into a module w/o lock */
 const char *module_address_lookup(unsigned long addr,
                                  unsigned long *size,
                                  unsigned long *offset,
                                  char **modname)
 {
        struct module *mod;
+       const char *ret = NULL;
 
+       preempt_disable();
        list_for_each_entry(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size)
                    || within(addr, mod->module_core, mod->core_size)) {
                        if (modname)
                                *modname = mod->name;
-                       return get_ksymbol(mod, addr, size, offset);
+                       ret = get_ksymbol(mod, addr, size, offset);
+                       break;
                }
        }
-       return NULL;
+       preempt_enable();
+       return ret;
 }
 
 int lookup_module_symbol_name(unsigned long addr, char *symname)
 {
        struct module *mod;
 
-       mutex_lock(&module_mutex);
+       preempt_disable();
        list_for_each_entry(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size) ||
                    within(addr, mod->module_core, mod->core_size)) {
@@ -2246,12 +2251,12 @@ int lookup_module_symbol_name(unsigned long addr, char 
*symname)
                        if (!sym)
                                goto out;
                        strlcpy(symname, sym, KSYM_NAME_LEN);
-                       mutex_unlock(&module_mutex);
+                       preempt_enable();
                        return 0;
                }
        }
 out:
-       mutex_unlock(&module_mutex);
+       preempt_enable();
        return -ERANGE;
 }
 
@@ -2260,7 +2265,7 @@ int lookup_module_symbol_attrs(unsigned long addr, 
unsigned long *size,
 {
        struct module *mod;
 
-       mutex_lock(&module_mutex);
+       preempt_disable();
        list_for_each_entry(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size) ||
                    within(addr, mod->module_core, mod->core_size)) {
@@ -2273,12 +2278,12 @@ int lookup_module_symbol_attrs(unsigned long addr, 
unsigned long *size,
                                strlcpy(modname, mod->name, MODULE_NAME_LEN);
                        if (name)
                                strlcpy(name, sym, KSYM_NAME_LEN);
-                       mutex_unlock(&module_mutex);
+                       preempt_enable();
                        return 0;
                }
        }
 out:
-       mutex_unlock(&module_mutex);
+       preempt_enable();
        return -ERANGE;
 }
 
@@ -2287,7 +2292,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long 
*value, char *type,
 {
        struct module *mod;
 
-       mutex_lock(&module_mutex);
+       preempt_disable();
        list_for_each_entry(mod, &modules, list) {
                if (symnum < mod->num_symtab) {
                        *value = mod->symtab[symnum].st_value;
@@ -2296,12 +2301,12 @@ int module_get_kallsym(unsigned int symnum, unsigned 
long *value, char *type,
                                KSYM_NAME_LEN);
                        strlcpy(module_name, mod->name, MODULE_NAME_LEN);
                        *exported = is_exported(name, mod);
-                       mutex_unlock(&module_mutex);
+                       preempt_enable();
                        return 0;
                }
                symnum -= mod->num_symtab;
        }
-       mutex_unlock(&module_mutex);
+       preempt_enable();
        return -ERANGE;
 }
 
@@ -2324,6 +2329,7 @@ unsigned long module_kallsyms_lookup_name(const char 
*name)
        unsigned long ret = 0;
 
        /* Don't lock: we're in enough trouble already. */
+       preempt_disable();
        if ((colon = strchr(name, ':')) != NULL) {
                *colon = '\0';
                if ((mod = find_module(name)) != NULL)
@@ -2334,6 +2340,7 @@ unsigned long module_kallsyms_lookup_name(const char 
*name)
                        if ((ret = mod_find_symname(mod, name)) != 0)
                                break;
        }
+       preempt_enable();
        return ret;
 }
 #endif /* CONFIG_KALLSYMS */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to