2007-08-30 17:51:07

by Matti Linnanvuori

[permalink] [raw]
Subject: [Bugme-new] [Bug 8957] New: Exported functions and variables

I thought I had seen that bug. Module init function execution does not seem serialized enough, so the init function of one module seems to be able to be called in parallel with several other modules in turn being loaded, executing their init functions and even becoming live first class citizens.
Function sys_init_module in
Linux 2.6.22.x and 2.6.23-rc4 kernel/module.c does not hold module_mutex when executing the init functions of the modules.




__________________________________
Alles was der Gesundheit und Entspannung dient. BE A BETTER MEDIZINMANN! http://www.yahoo.de/clever


2007-08-31 15:53:48

by Satyam Sharma

[permalink] [raw]
Subject: Re: [Bugme-new] [Bug 8957] New: Exported functions and variables

Hi Matti,


On Thu, 30 Aug 2007, Matti Linnanvuori wrote:
>
> I thought I had seen that bug. Module init function execution does not
> seem serialized enough, so the init function of one module seems to be
> able to be called in parallel with several other modules in turn being
> loaded, executing their init functions and even becoming live first
> class citizens.
> Function sys_init_module in
> Linux 2.6.22.x and 2.6.23-rc4 kernel/module.c does not hold module_mutex
> when executing the init functions of the modules.

Sure, there's nothing to prevent one module's module_init() from being
concurrently executed with the module_init() of another -- but that's OK.
Anyway, I tested this out with:

Module A
========

/***** mod_a.c *****/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/spinlock.h>

static spinlock_t mylock;

static void mod_a_func(void)
{
spin_lock(&mylock);
printk(KERN_INFO "inside mod_a_func\n");
spin_unlock(&mylock);
}
EXPORT_SYMBOL(mod_a_func);

static int __init mod_a_init(void)
{
printk(KERN_INFO "module_init begin ...");
ssleep(10);
spin_lock_init(&mylock);
printk(KERN_INFO "... module_init done\n");
return 0;
}

static void __exit mod_a_exit(void)
{
printk(KERN_INFO "exiting\n");
}

module_init(mod_a_init);
module_exit(mod_a_exit);
MODULE_LICENSE("GPL");
/***** mod_a.c *****/

Module B
========

/***** mod_b.c *****/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>

extern void mod_a_func(void);

static int __init mod_b_init(void)
{
mod_a_func();
return 0;
}

static void __exit mod_b_exit(void)
{
}

module_init(mod_b_init);
module_exit(mod_b_exit);
MODULE_LICENSE("GPL");
/***** mod_b.c *****/

Test result:
============

Module B refuses to load (could not resolve the symbol mod_a_func) unless
the module_init() of Module A has finished completely. The following log
was obtained by running "insmod ./mod_b.ko" repeatedly on one xterm, while
another xterm was then used to do "insmod ./mod_a.ko":

mod_b: Unknown symbol mod_a_func
mod_b: Unknown symbol mod_a_func
module_init begin ...<4>mod_b: Unknown symbol mod_a_func
mod_b: Unknown symbol mod_a_func
last message repeated 4 times
... module_init done
inside mod_a_func


So the title of your bug report "Exported functions and variables should
not be reachable by the outside of the module until module_init finishes"
sounds to be already true to me, so let us know if bugzilla #8957 can be
closed or not ;-)


Thanks,

Satyam