Skip to content

Commit

Permalink
module: initialize module dynamic debug later
Browse files Browse the repository at this point in the history
We should initialize the module dynamic debug datastructures
only after determining that the module is not loaded yet. This
fixes a bug that introduced in 2.6.35-rc2, where when a trying
to load a module twice, we also load it's dynamic printing data
twice which causes all sorts of nasty issues. Also handle
the dynamic debug cleanup later on failure.

Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (removed a #ifdef)
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Yehuda Sadeh authored and torvalds committed Jul 5, 2010
1 parent e3668dd commit ff49d74
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 11 deletions.
4 changes: 2 additions & 2 deletions include/linux/dynamic_debug.h
Expand Up @@ -40,7 +40,7 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
const char *modname);

#if defined(CONFIG_DYNAMIC_DEBUG)
extern int ddebug_remove_module(char *mod_name);
extern int ddebug_remove_module(const char *mod_name);

#define __dynamic_dbg_enabled(dd) ({ \
int __ret = 0; \
Expand Down Expand Up @@ -73,7 +73,7 @@ extern int ddebug_remove_module(char *mod_name);

#else

static inline int ddebug_remove_module(char *mod)
static inline int ddebug_remove_module(const char *mod)
{
return 0;
}
Expand Down
23 changes: 15 additions & 8 deletions kernel/module.c
Expand Up @@ -2062,6 +2062,12 @@ static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num)
#endif
}

static void dynamic_debug_remove(struct _ddebug *debug)
{
if (debug)
ddebug_remove_module(debug->modname);
}

static void *module_alloc_update_bounds(unsigned long size)
{
void *ret = module_alloc(size);
Expand Down Expand Up @@ -2124,6 +2130,8 @@ static noinline struct module *load_module(void __user *umod,
void *ptr = NULL; /* Stops spurious gcc warning */
unsigned long symoffs, stroffs, *strmap;
void __percpu *percpu;
struct _ddebug *debug = NULL;
unsigned int num_debug = 0;

mm_segment_t old_fs;

Expand Down Expand Up @@ -2476,15 +2484,9 @@ static noinline struct module *load_module(void __user *umod,
kfree(strmap);
strmap = NULL;

if (!mod->taints) {
struct _ddebug *debug;
unsigned int num_debug;

if (!mod->taints)
debug = section_objs(hdr, sechdrs, secstrings, "__verbose",
sizeof(*debug), &num_debug);
if (debug)
dynamic_debug_setup(debug, num_debug);
}

err = module_finalize(hdr, sechdrs, mod);
if (err < 0)
Expand Down Expand Up @@ -2526,10 +2528,13 @@ static noinline struct module *load_module(void __user *umod,
goto unlock;
}

if (debug)
dynamic_debug_setup(debug, num_debug);

/* Find duplicate symbols */
err = verify_export_symbols(mod);
if (err < 0)
goto unlock;
goto ddebug;

list_add_rcu(&mod->list, &modules);
mutex_unlock(&module_mutex);
Expand Down Expand Up @@ -2557,6 +2562,8 @@ static noinline struct module *load_module(void __user *umod,
mutex_lock(&module_mutex);
/* Unlink carefully: kallsyms could be walking list. */
list_del_rcu(&mod->list);
ddebug:
dynamic_debug_remove(debug);
unlock:
mutex_unlock(&module_mutex);
synchronize_sched();
Expand Down
2 changes: 1 addition & 1 deletion lib/dynamic_debug.c
Expand Up @@ -692,7 +692,7 @@ static void ddebug_table_free(struct ddebug_table *dt)
* Called in response to a module being unloaded. Removes
* any ddebug_table's which point at the module.
*/
int ddebug_remove_module(char *mod_name)
int ddebug_remove_module(const char *mod_name)
{
struct ddebug_table *dt, *nextdt;
int ret = -ENOENT;
Expand Down

0 comments on commit ff49d74

Please sign in to comment.