Linux Kernel Architecture

(Jacob Rumans) #1

Chapter7:Modules


{
struct module_use *use;

list_for_each_entry(use, &b->modules_which_use_me, list) {
if (use->module_which_uses == a) {
return 1;
}
}
return 0;
}

If A depends on B, themodules_which_use_melist of B must contain a pointer to themoduleinstance of A.
This is why the kernel looks through the list step by step and checks the pointers inmodule_which_uses.
If a matching entry is found — in other words, if the dependency really exists — 1 is returned; otherwise,
the function terminates and returns 0.

use_moduleis used to establish the relation between A and B — module A needs module B to function
correctly. It is implemented as follows:

kernel/module.c
/* Module a uses b */
static int use_module(struct module *a, struct module *b)
{
struct module_use *use;
...
if (b == NULL || already_uses(a, b)) return 1;

if (!strong_try_module_get(b))
return 0;

use = kmalloc(sizeof(*use), GFP_ATOMIC);
if (!use) {
printk("%s: out of memory loading\n", a->name);
module_put(b);
return 0;
}

use->module_which_uses = a;
list_add(&use->list, &b->modules_which_use_me);
...
return 1;
}

already_usesfirst checks whether the relation has already been established. If so, the function can
return immediately (aNULLpointer as a dependent module is also interpreted as meaning that the
relation already exists). If not, the reference counter of B is incremented so that it can no longer be
removed — after all, A insists on its presence. Thestrong_try_module_getused for this purpose is a
wrapper around the aforementionedtry_module_getfunction; it deals with the situation in which the
module is in the process of being loaded:

kernel/module.c
static inline int strong_try_module_get(struct module *mod)
{
if (mod && mod->state == MODULE_STATE_COMING)
Free download pdf