From: Andrew Morton Give it a chance of building on most architectures Cc: Andi Kleen Cc: Ingo Molnar Signed-off-by: Andrew Morton --- kernel/module.c | 58 ++++++++++++++++++++++++++-------------------- 1 files changed, 33 insertions(+), 25 deletions(-) diff -puN kernel/module.c~x86_64-mm-module-locks-raw-spinlock-hack-hack-hack kernel/module.c --- a/kernel/module.c~x86_64-mm-module-locks-raw-spinlock-hack-hack-hack +++ a/kernel/module.c @@ -59,7 +59,25 @@ #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) /* Protects module list */ +#ifdef CONFIG_LOCKDEP static raw_spinlock_t modlist_lock = __RAW_SPIN_LOCK_UNLOCKED; +#define raw_spin_lock_irqsave(lock, flags) \ + do { \ + raw_local_save_flags(flags); \ + __raw_spin_lock(lock); \ + } while (0) +#define raw_spin_unlock_irqrestore(lock, flags) \ + do { \ + __raw_spin_unlock(lock); \ + raw_local_irq_restore(flags); \ + } while (0) +#else +static DEFINE_SPINLOCK(modlist_lock); +#define raw_spin_lock_irqsave(lock, flags) \ + spin_lock_irqsave(lock, flags) +#define raw_spin_unlock_irqrestore(lock, flags) \ + spin_unlock_irqrestore(lock, flags) +#endif /* List of modules, protected by module_mutex AND modlist_lock */ static DEFINE_MUTEX(module_mutex); @@ -751,13 +769,11 @@ void __symbol_put(const char *symbol) unsigned long flags; const unsigned long *crc; - raw_local_save_flags(flags); - __raw_spin_lock(&modlist_lock); + raw_spin_lock_irqsave(&modlist_lock, flags); if (!__find_symbol(symbol, &owner, &crc, 1)) BUG(); module_put(owner); - __raw_spin_unlock(&modlist_lock); - raw_local_irq_restore(flags); + raw_spin_unlock_irqrestore(&modlist_lock, flags); } EXPORT_SYMBOL(__symbol_put); @@ -1136,13 +1152,11 @@ void *__symbol_get(const char *symbol) unsigned long value, flags; const unsigned long *crc; - raw_local_save_flags(flags); - __raw_spin_lock(&modlist_lock); + raw_spin_lock_irqsave(&modlist_lock, flags); value = __find_symbol(symbol, &owner, &crc, 1); if (value && !strong_try_module_get(owner)) value = 0; - __raw_spin_unlock(&modlist_lock); - raw_local_irq_restore(flags); + raw_spin_unlock_irqrestore(&modlist_lock, flags); return (void *)value; } @@ -2145,8 +2159,7 @@ const struct exception_table_entry *sear const struct exception_table_entry *e = NULL; struct module *mod; - raw_local_save_flags(flags); - __raw_spin_lock(&modlist_lock); + raw_spin_lock_irqsave(&modlist_lock, flags); list_for_each_entry(mod, &modules, list) { if (mod->num_exentries == 0) continue; @@ -2157,8 +2170,7 @@ const struct exception_table_entry *sear if (e) break; } - __raw_spin_unlock(&modlist_lock); - raw_local_irq_restore(flags); + raw_spin_unlock_irqrestore(&modlist_lock, flags); /* Now, if we found one, we are running inside it now, hence we cannot unload the module, hence no refcnt needed. */ @@ -2172,20 +2184,19 @@ int is_module_address(unsigned long addr { unsigned long flags; struct module *mod; - int ret = 0; - raw_local_save_flags(flags); - __raw_spin_lock(&modlist_lock); + raw_spin_lock_irqsave(&modlist_lock, flags); + list_for_each_entry(mod, &modules, list) { if (within(addr, mod->module_core, mod->core_size)) { - ret = 1; - break; + raw_spin_unlock_irqrestore(&modlist_lock, flags); + return 1; } } - __raw_spin_unlock(&modlist_lock); - raw_local_irq_restore(flags); - return ret; + raw_spin_unlock_irqrestore(&modlist_lock, flags); + + return 0; } @@ -2206,12 +2217,9 @@ struct module *module_text_address(unsig struct module *mod; unsigned long flags; - /* This is called from lockdep */ - raw_local_save_flags(flags); - __raw_spin_lock(&modlist_lock); + raw_spin_lock_irqsave(&modlist_lock, flags); mod = __module_text_address(addr); - __raw_spin_unlock(&modlist_lock); - raw_local_irq_restore(flags); + raw_spin_unlock_irqrestore(&modlist_lock, flags); return mod; } _