summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2008-12-05 16:47:30 +0000
committerjhb <jhb@FreeBSD.org>2008-12-05 16:47:30 +0000
commit0f1a8aa0116553ec40fabee2f4dbda0c8ccd852c (patch)
treebc48edf62c21c5ab7dd0d350384090ef84220711 /sys
parent8653cc8d0834a1f243b961e3353cfc2ff6358e94 (diff)
downloadFreeBSD-src-0f1a8aa0116553ec40fabee2f4dbda0c8ccd852c.zip
FreeBSD-src-0f1a8aa0116553ec40fabee2f4dbda0c8ccd852c.tar.gz
When the SYSINIT() to load a module invokes the MOD_LOAD event successfully,
move that module to the head of the associated linker file's list of modules. The end result is that once all the modules are loaded, they are sorted in the reverse of their load order. This causes the kernel linker to invoke the MOD_QUIESCE and MOD_UNLOAD events in the reverse of the order that MOD_LOAD was invoked. This means that the ordering of MOD_LOAD events that is set by the SI_* paramters to DECLARE_MODULE() are now honored in the same order they would be for SYSUNINIT() for the MOD_QUIESCE and MOD_UNLOAD events. MFC after: 1 month
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_module.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c
index fef7f87..9c53bf6 100644
--- a/sys/kern/kern_module.c
+++ b/sys/kern/kern_module.c
@@ -130,6 +130,21 @@ module_register_init(const void *arg)
printf("module_register_init: MOD_LOAD (%s, %p, %p) error"
" %d\n", data->name, (void *)data->evhand, data->priv,
error);
+ } else {
+ MOD_XLOCK;
+ if (mod->file) {
+ /*
+ * Once a module is succesfully loaded, move
+ * it to the head of the module list for this
+ * linker file. This resorts the list so that
+ * when the kernel linker iterates over the
+ * modules to unload them, it will unload them
+ * in the reverse order they were loaded.
+ */
+ TAILQ_REMOVE(&mod->file->modules, mod, flink);
+ TAILQ_INSERT_HEAD(&mod->file->modules, mod, flink);
+ }
+ MOD_XUNLOCK;
}
mtx_unlock(&Giant);
}
OpenPOWER on IntegriCloud