summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_vimage.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_vimage.c')
-rw-r--r--sys/kern/kern_vimage.c212
1 files changed, 7 insertions, 205 deletions
diff --git a/sys/kern/kern_vimage.c b/sys/kern/kern_vimage.c
index b5742df..fa2d1f4 100644
--- a/sys/kern/kern_vimage.c
+++ b/sys/kern/kern_vimage.c
@@ -52,12 +52,6 @@ __FBSDID("$FreeBSD$");
MALLOC_DEFINE(M_VNET, "vnet", "network stack control block");
-static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head;
-static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head;
-static void vnet_mod_complete_registration(struct vnet_modlink *);
-static int vnet_mod_constructor(struct vnet_modlink *);
-static int vnet_mod_destructor(struct vnet_modlink *);
-
struct rwlock vnet_rwlock;
struct sx vnet_sxlock;
@@ -130,185 +124,10 @@ vi_if_move(struct thread *td, struct ifnet *ifp, char *ifname, int jid)
return (error);
}
-
-/*
- * Kernel interfaces and handlers.
- */
-
-void
-vnet_mod_register(const struct vnet_modinfo *vmi)
-{
-
- vnet_mod_register_multi(vmi, NULL, NULL);
-}
-
-void
-vnet_mod_register_multi(const struct vnet_modinfo *vmi, void *iarg,
- char *iname)
-{
- struct vnet_modlink *vml, *vml_iter;
-
- /* Do not register the same {module, iarg} pair more than once. */
- TAILQ_FOREACH(vml_iter, &vnet_modlink_head, vml_mod_le)
- if (vml_iter->vml_modinfo == vmi && vml_iter->vml_iarg == iarg)
- break;
- if (vml_iter != NULL)
- panic("registering an already registered vnet module: %s",
- vml_iter->vml_modinfo->vmi_name);
- vml = malloc(sizeof(struct vnet_modlink), M_VNET, M_NOWAIT);
-
- /*
- * XXX we support only statically assigned module IDs at the time.
- * In principle modules should be able to get a dynamically
- * assigned ID at registration time.
- *
- * If a module is registered in multiple instances, then each
- * instance must have both iarg and iname set.
- */
- if (vmi->vmi_id >= VNET_MOD_MAX)
- panic("invalid vnet module ID: %d", vmi->vmi_id);
- if (vmi->vmi_name == NULL)
- panic("vnet module with no name: %d", vmi->vmi_id);
- if ((iarg == NULL) ^ (iname == NULL))
- panic("invalid vnet module instance: %s", vmi->vmi_name);
-
- vml->vml_modinfo = vmi;
- vml->vml_iarg = iarg;
- vml->vml_iname = iname;
-
- /* Check whether the module we depend on is already registered. */
- if (vmi->vmi_dependson != vmi->vmi_id) {
- TAILQ_FOREACH(vml_iter, &vnet_modlink_head, vml_mod_le)
- if (vml_iter->vml_modinfo->vmi_id ==
- vmi->vmi_dependson)
- break; /* Depencency found, we are done. */
- if (vml_iter == NULL) {
-#ifdef DEBUG_ORDERING
- printf("dependency %d missing for vnet mod %s,"
- "postponing registration\n",
- vmi->vmi_dependson, vmi->vmi_name);
-#endif /* DEBUG_ORDERING */
- TAILQ_INSERT_TAIL(&vnet_modpending_head, vml,
- vml_mod_le);
- return;
- }
- }
-
- vnet_mod_complete_registration(vml);
-}
-
-void
-vnet_mod_complete_registration(struct vnet_modlink *vml)
-{
- VNET_ITERATOR_DECL(vnet_iter);
- struct vnet_modlink *vml_iter;
-
- TAILQ_INSERT_TAIL(&vnet_modlink_head, vml, vml_mod_le);
-
- VNET_FOREACH(vnet_iter) {
- CURVNET_SET_QUIET(vnet_iter);
- vnet_mod_constructor(vml);
- CURVNET_RESTORE();
- }
-
- /* Check for pending modules depending on us. */
- do {
- TAILQ_FOREACH(vml_iter, &vnet_modpending_head, vml_mod_le)
- if (vml_iter->vml_modinfo->vmi_dependson ==
- vml->vml_modinfo->vmi_id)
- break;
- if (vml_iter != NULL) {
-#ifdef DEBUG_ORDERING
- printf("vnet mod %s now registering,"
- "dependency %d loaded\n",
- vml_iter->vml_modinfo->vmi_name,
- vml->vml_modinfo->vmi_id);
-#endif /* DEBUG_ORDERING */
- TAILQ_REMOVE(&vnet_modpending_head, vml_iter,
- vml_mod_le);
- vnet_mod_complete_registration(vml_iter);
- }
- } while (vml_iter != NULL);
-}
-
-void
-vnet_mod_deregister(const struct vnet_modinfo *vmi)
-{
-
- vnet_mod_deregister_multi(vmi, NULL, NULL);
-}
-
-void
-vnet_mod_deregister_multi(const struct vnet_modinfo *vmi, void *iarg,
- char *iname)
-{
- VNET_ITERATOR_DECL(vnet_iter);
- struct vnet_modlink *vml;
-
- TAILQ_FOREACH(vml, &vnet_modlink_head, vml_mod_le)
- if (vml->vml_modinfo == vmi && vml->vml_iarg == iarg)
- break;
- if (vml == NULL)
- panic("cannot deregister unregistered vnet module %s",
- vmi->vmi_name);
-
- VNET_FOREACH(vnet_iter) {
- CURVNET_SET_QUIET(vnet_iter);
- vnet_mod_destructor(vml);
- CURVNET_RESTORE();
- }
-
- TAILQ_REMOVE(&vnet_modlink_head, vml, vml_mod_le);
- free(vml, M_VNET);
-}
-
-static int
-vnet_mod_constructor(struct vnet_modlink *vml)
-{
- const struct vnet_modinfo *vmi = vml->vml_modinfo;
-
-#ifdef DEBUG_ORDERING
- printf("instantiating vnet_%s", vmi->vmi_name);
- if (vml->vml_iarg)
- printf("/%s", vml->vml_iname);
- printf(": ");
- if (vmi->vmi_iattach != NULL)
- printf("iattach()");
- printf("\n");
-#endif
-
- if (vmi->vmi_iattach != NULL)
- vmi->vmi_iattach(vml->vml_iarg);
-
- return (0);
-}
-
-static int
-vnet_mod_destructor(struct vnet_modlink *vml)
-{
- const struct vnet_modinfo *vmi = vml->vml_modinfo;
-
-#ifdef DEBUG_ORDERING
- printf("destroying vnet_%s", vmi->vmi_name);
- if (vml->vml_iarg)
- printf("/%s", vml->vml_iname);
- printf(": ");
- if (vmi->vmi_idetach != NULL)
- printf("idetach(); ");
- printf("\n");
-#endif
-
- if (vmi->vmi_idetach)
- vmi->vmi_idetach(vml->vml_iarg);
-
- return (0);
-}
-
struct vnet *
vnet_alloc(void)
{
struct vnet *vnet;
- struct vnet_modlink *vml;
vnet = malloc(sizeof(struct vnet), M_VNET, M_WAITOK | M_ZERO);
vnet->vnet_magic_n = VNET_MAGIC_N;
@@ -316,11 +135,12 @@ vnet_alloc(void)
/* Initialize / attach vnet module instances. */
CURVNET_SET_QUIET(vnet);
- TAILQ_FOREACH(vml, &vnet_modlink_head, vml_mod_le)
- vnet_mod_constructor(vml);
+
+ sx_xlock(&vnet_sxlock);
+ vnet_sysinit();
CURVNET_RESTORE();
- VNET_LIST_WLOCK();
+ rw_wlock(&vnet_rwlock);
LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le);
VNET_LIST_WUNLOCK();
@@ -331,14 +151,13 @@ void
vnet_destroy(struct vnet *vnet)
{
struct ifnet *ifp, *nifp;
- struct vnet_modlink *vml;
KASSERT(vnet->vnet_sockcnt == 0,
("%s: vnet still has sockets", __func__));
VNET_LIST_WLOCK();
LIST_REMOVE(vnet, vnet_le);
- VNET_LIST_WUNLOCK();
+ rw_wunlock(&vnet_rwlock);
CURVNET_SET_QUIET(vnet);
@@ -348,10 +167,8 @@ vnet_destroy(struct vnet *vnet)
if_vmove(ifp, ifp->if_home_vnet);
}
- /* Detach / free per-module state instances. */
- TAILQ_FOREACH_REVERSE(vml, &vnet_modlink_head,
- vnet_modlink_head, vml_mod_le)
- vnet_mod_destructor(vml);
+ vnet_sysuninit();
+ sx_xunlock(&vnet_sxlock);
CURVNET_RESTORE();
@@ -387,9 +204,6 @@ static void
vnet0_init(void *arg)
{
- TAILQ_INIT(&vnet_modlink_head);
- TAILQ_INIT(&vnet_modpending_head);
-
/*
* We MUST clear curvnet in vi_init_done() before going SMP,
* otherwise CURVNET_SET() macros would scream about unnecessary
@@ -402,20 +216,8 @@ SYSINIT(vnet0_init, SI_SUB_VNET, SI_ORDER_FIRST, vnet0_init, NULL);
static void
vnet_init_done(void *unused)
{
- struct vnet_modlink *vml_iter;
curvnet = NULL;
-
- if (TAILQ_EMPTY(&vnet_modpending_head))
- return;
-
- printf("vnet modules with unresolved dependencies:\n");
- TAILQ_FOREACH(vml_iter, &vnet_modpending_head, vml_mod_le)
- printf(" %d:%s depending on %d\n",
- vml_iter->vml_modinfo->vmi_id,
- vml_iter->vml_modinfo->vmi_name,
- vml_iter->vml_modinfo->vmi_dependson);
- panic("going nowhere without my vnet modules!");
}
SYSINIT(vnet_init_done, SI_SUB_VNET_DONE, SI_ORDER_FIRST, vnet_init_done,
OpenPOWER on IntegriCloud