PERFORCE change 123300 for review
Marko Zec
zec at FreeBSD.org
Wed Jul 11 00:11:26 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=123300
Change 123300 by zec at zec_tpx32 on 2007/07/11 00:11:03
Change the way the registration of vnet "modules" is handled,
and in particular the initialization / cleanup ordering.
Previously, the modules were responsible for declaring whether
their initialization routines should be called before or
after network protocol domain initialization. This change
allows for protocol domains to be registered as vnet modules
as well, which simplifies the initialization process and should
do a better job at capturing the init ordering as set by the
standard SYSINIT and DOMAIN_SET macros in a non-virtualized
kernel.
A vnet module can now be registered for initialization in
multiple instances; however, each instance must be registered
with a unique calling argument (a void *). This capability is
leveraged to allow a single handler to be registered in multiple
instances; i.e. net_init_domain() is registered as a vnet module
once for each protocol domain.
Affected files ...
.. //depot/projects/vimage/src/sys/kern/kern_vimage.c#22 edit
.. //depot/projects/vimage/src/sys/kern/uipc_domain.c#3 edit
.. //depot/projects/vimage/src/sys/net/if.c#14 edit
.. //depot/projects/vimage/src/sys/net/if_gif.c#5 edit
.. //depot/projects/vimage/src/sys/net/if_loop.c#13 edit
.. //depot/projects/vimage/src/sys/net/route.c#8 edit
.. //depot/projects/vimage/src/sys/netgraph/ng_base.c#9 edit
.. //depot/projects/vimage/src/sys/netinet/if_ether.c#11 edit
.. //depot/projects/vimage/src/sys/netinet/ip_fw2.c#18 edit
.. //depot/projects/vimage/src/sys/sys/vimage.h#18 edit
Differences ...
==== //depot/projects/vimage/src/sys/kern/kern_vimage.c#22 (text+ko) ====
@@ -82,31 +82,45 @@
int last_vi_id = 0;
-static struct vnet_modlink vnet_modules[VNET_MOD_MAX];
static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head;
void vnet_mod_register(modinfo)
struct vnet_modinfo *modinfo;
{
+ vnet_mod_register_multi(modinfo, NULL, NULL);
+}
+
+void vnet_mod_register_multi(modinfo, iarg, iname)
+ struct vnet_modinfo *modinfo;
+ void *iarg;
+ char *iname;
+{
+ struct vnet_modlink *vml;
+
+ /* Do not register the same module instance more than once */
+ TAILQ_FOREACH(vml, &vnet_modlink_head, mod_le)
+ if (vml->modinfo == modinfo && vml->iarg == iarg)
+ break;
+ if (vml != NULL)
+ panic("attempt to register already registered vnet module");
+ vml = malloc(sizeof(struct vnet_modlink), M_VIMAGE, 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.
*/
-
VNET_ASSERT(modinfo->id > 0 || modinfo->id < VNET_MOD_MAX);
- VNET_ASSERT(vnet_modules[modinfo->id].modinfo == NULL);
- VNET_ASSERT(modinfo->i_attach == NULL || (modinfo->i_attach &&
- ((modinfo->flags & VNET_MFLAG_ORDER_1ST) ||
- (modinfo->flags & VNET_MFLAG_ORDER_2ND))));
+ VNET_ASSERT((iarg == NULL) ^ (iname == NULL));
- vnet_modules[modinfo->id].modinfo = modinfo;
- TAILQ_INSERT_TAIL(&vnet_modlink_head,
- &vnet_modules[modinfo->id], mod_le);
+ vml->modinfo = modinfo;
+ vml->iarg = iarg;
+ vml->iname = iname;
+ TAILQ_INSERT_TAIL(&vnet_modlink_head, vml, mod_le);
if (modinfo->i_attach) {
VNET_ITERLOOP_BEGIN_QUIET();
- modinfo->i_attach();
+ modinfo->i_attach(iarg);
VNET_ITERLOOP_END();
}
}
@@ -114,17 +128,30 @@
void vnet_mod_deregister(modinfo)
struct vnet_modinfo *modinfo;
{
- VNET_ASSERT(vnet_modules[modinfo->id].modinfo == modinfo)
+ vnet_mod_deregister_multi(modinfo, NULL, NULL);
+}
+
+void vnet_mod_deregister_multi(modinfo, iarg, iname)
+ struct vnet_modinfo *modinfo;
+ void *iarg;
+ char *iname;
+{
+ struct vnet_modlink *vml;
+
+ TAILQ_FOREACH(vml, &vnet_modlink_head, mod_le)
+ if (vml->modinfo == modinfo && vml->iarg == iarg)
+ break;
+ if (vml == NULL)
+ panic("cannot deregister unregistered vnet module");
if (modinfo->i_detach) {
VNET_ITERLOOP_BEGIN_QUIET();
- modinfo->i_detach();
+ modinfo->i_detach(iarg);
VNET_ITERLOOP_END();
}
- vnet_modules[modinfo->id].modinfo = NULL;
- TAILQ_REMOVE(&vnet_modlink_head,
- &vnet_modules[modinfo->id], mod_le);
+ TAILQ_REMOVE(&vnet_modlink_head, vml, mod_le);
+ free(vml, M_VIMAGE);
}
struct vimage *vnet2vimage(vnet)
@@ -384,20 +411,19 @@
struct kld_sym_lookup *lookup;
char *symstr;
{
- int i;
+ struct vnet_modlink *vml;
- for (i = 0; i < VNET_MOD_MAX; i++) {
+ TAILQ_FOREACH(vml, &vnet_modlink_head, mod_le) {
struct vnet_symmap *mapentry;
- if (vnet_modules[i].modinfo == NULL ||
- vnet_modules[i].modinfo->symmap == NULL)
+ if (vml->modinfo->symmap == NULL)
continue;
- for (mapentry = vnet_modules[i].modinfo->symmap;
+ for (mapentry = vml->modinfo->symmap;
mapentry->name != NULL; mapentry++) {
if (strcmp(symstr, mapentry->name) == 0) {
lookup->symvalue =
- (int) curvnet->mod_data[i];
+ (int) curvnet->mod_data[vml->modinfo->id];
lookup->symvalue += mapentry->offset;
lookup->symsize = mapentry->size;
return 0;
@@ -418,8 +444,7 @@
struct vnet *vnet;
struct vprocg *vprocg;
struct vcpu *vcpu;
- struct domain *dp;
- struct vnet_modlink *modlnk_i;
+ struct vnet_modlink *vml;
/*
* XXX don't forget the locking
@@ -461,42 +486,11 @@
CURVNET_SET_QUIET(vnet);
/*
- * Attach modules with ORDER_1ST flag set
+ * Initialize / attach module instances.
*/
- TAILQ_FOREACH(modlnk_i, &vnet_modlink_head, mod_le)
- if (modlnk_i->modinfo->i_attach != NULL &&
- modlnk_i->modinfo->flags & VNET_MFLAG_ORDER_1ST) {
- VNET_ASSERT(!(modlnk_i->modinfo->flags & \
- VNET_MFLAG_ORDER_2ND));
- modlnk_i->modinfo->i_attach();
- }
-
- /*
- * Attach protocol domains.
- */
- for (dp = domains; dp; dp = dp->dom_next) {
- struct protosw *pr;
- for (pr = dp->dom_protosw;
- pr < dp->dom_protoswNPROTOSW; pr++) {
- if (pr->pr_usrreqs == 0)
- panic("domaininit: %ssw[%d] has no usrreqs!",
- dp->dom_name,
- (int)(pr - dp->dom_protosw));
- if (pr->pr_init)
- pr->pr_init();
- }
- }
-
- /*
- * Attach modules with ORDER_2ND flag set
- */
- TAILQ_FOREACH(modlnk_i, &vnet_modlink_head, mod_le)
- if (modlnk_i->modinfo->i_attach != NULL &&
- modlnk_i->modinfo->flags & VNET_MFLAG_ORDER_2ND) {
- VNET_ASSERT(!(modlnk_i->modinfo->flags & \
- VNET_MFLAG_ORDER_1ST));
- modlnk_i->modinfo->i_attach();
- }
+ TAILQ_FOREACH(vml, &vnet_modlink_head, mod_le)
+ if (vml->modinfo->i_attach != NULL)
+ vml->modinfo->i_attach(vml->iarg);
CURVNET_RESTORE();
@@ -522,8 +516,7 @@
struct vprocg *vprocg = vip->v_procg;
struct vcpu *vcpu = vip->v_cpu;
struct ifnet *ifp, *nifp;
- struct vnet_modlink *modlnk_i;
- struct domain *dp;
+ struct vnet_modlink *vml;
CURVNET_SET_QUIET(vnet);
INIT_VNET_NET(vnet);
@@ -552,36 +545,11 @@
ifp->if_xname);
/*
- * Detach modules with ORDER_2ND flag set
+ * Detach / free per-module state instances.
*/
- TAILQ_FOREACH_REVERSE(modlnk_i, &vnet_modlink_head, vnet_modlink_head, mod_le)
- if (modlnk_i->modinfo->i_detach != NULL &&
- modlnk_i->modinfo->flags & VNET_MFLAG_ORDER_2ND) {
- VNET_ASSERT(!(modlnk_i->modinfo->flags & \
- VNET_MFLAG_ORDER_1ST));
- modlnk_i->modinfo->i_detach();
- }
-
- /*
- * Detach protocol domains
- */
- for (dp = domains; dp; dp = dp->dom_next) {
- struct protosw *pr;
- for (pr = dp->dom_protoswNPROTOSW; pr > dp->dom_protosw;)
- if ((--pr)->pr_destroy)
- (*pr->pr_destroy)();
- }
-
- /*
- * Detach modules with ORDER_1ST flag set
- */
- TAILQ_FOREACH_REVERSE(modlnk_i, &vnet_modlink_head, vnet_modlink_head, mod_le)
- if (modlnk_i->modinfo->i_detach != NULL &&
- modlnk_i->modinfo->flags & VNET_MFLAG_ORDER_1ST) {
- VNET_ASSERT(!(modlnk_i->modinfo->flags & \
- VNET_MFLAG_ORDER_2ND));
- modlnk_i->modinfo->i_detach();
- }
+ TAILQ_FOREACH_REVERSE(vml, &vnet_modlink_head, vnet_modlink_head, mod_le)
+ if (vml->modinfo->i_detach)
+ vml->modinfo->i_detach(vml->iarg);
#if 0
free((caddr_t)vnet->ifnet_addrs, M_IFADDR);
==== //depot/projects/vimage/src/sys/kern/uipc_domain.c#3 (text+ko) ====
@@ -29,6 +29,8 @@
* @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93
*/
+#include "opt_vimage.h"
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/kern/uipc_domain.c,v 1.49 2007/05/16 20:41:07 rwatson Exp $");
@@ -43,6 +45,7 @@
#include <sys/mutex.h>
#include <sys/socketvar.h>
#include <sys/systm.h>
+#include <sys/vimage.h>
#include <vm/uma.h>
/*
@@ -64,6 +67,8 @@
SYSINIT(domainfin, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST, domainfinalize,
NULL)
+static int net_init_domain(void *);
+
static struct callout pffast_callout;
static struct callout pfslow_callout;
@@ -100,6 +105,14 @@
.pru_sopoll = pru_sopoll_notsupp,
};
+#ifdef VIMAGE
+static struct vnet_modinfo vnet_domain_modinfo = {
+ .id = VNET_MOD_DOMAIN,
+ .name = "domain",
+ .i_attach = net_init_domain
+};
+#endif
+
static void
protosw_init(struct protosw *pr)
{
@@ -132,9 +145,10 @@
* Note: you cant unload it again because a socket may be using it.
* XXX can't fail at this time.
*/
-static void
-net_init_domain(struct domain *dp)
+static int
+net_init_domain(void *arg)
{
+ struct domain *dp = arg;
struct protosw *pr;
if (dp->dom_init)
@@ -148,6 +162,7 @@
max_datalen = MHLEN - max_hdr;
if (max_datalen < 1)
panic("%s: max_datalen < 1", __func__);
+ return 0;
}
/*
@@ -183,7 +198,11 @@
"domainfinalize()\n", dp->dom_name);
#endif
mtx_unlock(&dom_mtx);
+#ifdef VIMAGE
+ vnet_mod_register_multi(&vnet_domain_modinfo, dp, dp->dom_name);
+#else
net_init_domain(dp);
+#endif
}
static void
==== //depot/projects/vimage/src/sys/net/if.c#14 (text+ko) ====
@@ -137,9 +137,9 @@
extern void nd6_setmtu(struct ifnet *);
#endif
-static int vnet_net_iattach(void);
+static int vnet_net_iattach(void *);
#ifdef VIMAGE
-static int vnet_net_idetach(void);
+static int vnet_net_idetach(void *);
#endif
int ifqmaxlen = IFQ_MAXLEN;
@@ -175,7 +175,6 @@
static struct vnet_modinfo vnet_net_modinfo = {
.id = VNET_MOD_NET,
- .flags = VNET_MFLAG_ORDER_1ST,
.name = "net",
.symmap = vnet_net_symmap,
.i_attach = vnet_net_iattach,
@@ -332,7 +331,7 @@
#ifdef VIMAGE
vnet_mod_register(&vnet_net_modinfo);
#else
- vnet_net_iattach();
+ vnet_net_iattach(NULL);
#endif
IFNET_LOCK_INIT();
#ifdef VIMAGE
@@ -348,7 +347,8 @@
}
static int
-vnet_net_iattach()
+vnet_net_iattach(unused)
+ void *unused;
{
#ifdef VIMAGE
struct vnet_net *vnet_net;
@@ -376,7 +376,8 @@
#ifdef VIMAGE
static int
-vnet_net_idetach()
+vnet_net_idetach(unused)
+ void *unused;
{
INIT_VNET_NET(curvnet);
==== //depot/projects/vimage/src/sys/net/if_gif.c#5 (text+ko) ====
@@ -148,9 +148,7 @@
#ifdef VIMAGE
static struct vnet_modinfo vnet_gif_modinfo = {
.id = VNET_MOD_GIF,
- .flags = VNET_MFLAG_ORDER_2ND,
.name = "gif",
- .symmap = NULL,
.i_attach = vnet_gif_iattach,
.i_detach = vnet_gif_idetach
};
==== //depot/projects/vimage/src/sys/net/if_loop.c#13 (text+ko) ====
@@ -106,9 +106,9 @@
struct sockaddr *dst, struct rtentry *rt);
static int lo_clone_create(struct if_clone *, int, caddr_t);
static void lo_clone_destroy(struct ifnet *);
-static int vnet_loif_iattach(void);
+static int vnet_loif_iattach(void *);
#ifdef VIMAGE
-static int vnet_loif_idetach(void);
+static int vnet_loif_idetach(void *);
#endif
#ifndef VIMAGE
@@ -183,15 +183,14 @@
#ifdef VIMAGE
static struct vnet_modinfo vnet_loif_modinfo = {
.id = VNET_MOD_LOIF,
- .flags = VNET_MFLAG_ORDER_2ND,
.name = "loif",
- .symmap = NULL,
.i_attach = vnet_loif_iattach,
.i_detach = vnet_loif_idetach
};
#endif
-static int vnet_loif_iattach(void)
+static int vnet_loif_iattach(unused)
+ void *unused;
{
INIT_VNET_NET(curvnet);
@@ -208,7 +207,8 @@
}
#ifdef VIMAGE
-static int vnet_loif_idetach(void)
+static int vnet_loif_idetach(unused)
+ void *unused;
{
INIT_VNET_NET(curvnet);
struct lo_softc *sc, *nsc;
@@ -243,7 +243,7 @@
#ifdef VIMAGE
vnet_mod_register(&vnet_loif_modinfo);
#else
- vnet_loif_iattach();
+ vnet_loif_iattach(NULL);
#endif
break;
case MOD_UNLOAD:
==== //depot/projects/vimage/src/sys/net/route.c#8 (text+ko) ====
@@ -60,9 +60,9 @@
static void rt_maskedcopy(struct sockaddr *,
struct sockaddr *, struct sockaddr *);
-static int rtable_init(void);
+static int rtable_init(void *);
#ifdef VIMAGE
-static int rtable_idetach(void);
+static int rtable_idetach(void *);
#endif
/* compare two sockaddr structures */
@@ -83,7 +83,6 @@
#ifdef VIMAGE
static struct vnet_modinfo vnet_rtable_modinfo = {
.id = VNET_MOD_RTABLE,
- .flags = VNET_MFLAG_ORDER_2ND,
.name = "rtable",
.i_attach = rtable_init,
.i_detach = rtable_idetach
@@ -91,7 +90,8 @@
#endif
static int
-rtable_init()
+rtable_init(unused)
+ void *unused;
{
INIT_VNET_NET(curvnet);
@@ -105,7 +105,8 @@
#ifdef VIMAGE
static int
-rtable_idetach()
+rtable_idetach(unused)
+ void *unused;
{
INIT_VNET_NET(curvnet);
@@ -129,7 +130,7 @@
#ifdef VIMAGE
vnet_mod_register(&vnet_rtable_modinfo);
#else
- rtable_init();
+ rtable_init(NULL);
#endif
}
==== //depot/projects/vimage/src/sys/netgraph/ng_base.c#9 (text+ko) ====
@@ -255,11 +255,8 @@
static struct vnet_modinfo vnet_netgraph_modinfo = {
.id = VNET_MOD_NETGRAPH,
- .flags = VNET_MFLAG_ORDER_2ND,
.name = "netgraph",
- .symmap = NULL,
.i_attach = vnet_netgraph_iattach,
- .i_detach = NULL,
};
#endif
==== //depot/projects/vimage/src/sys/netinet/if_ether.c#11 (text+ko) ====
@@ -119,7 +119,7 @@
"Enable proxy ARP for all suitable requests");
static void arp_init(void);
-static int arp_iattach(void);
+static int arp_iattach(void *);
static void arp_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
static void arprequest(struct ifnet *,
struct in_addr *, struct in_addr *, u_char *);
@@ -134,9 +134,7 @@
#ifdef VIMAGE
static struct vnet_modinfo vnet_arp_modinfo = {
.id = VNET_MOD_ARP,
- .flags = VNET_MFLAG_ORDER_2ND,
.name = "arp",
- .symmap = NULL,
.i_attach = arp_iattach,
.i_detach = NULL,
};
@@ -983,7 +981,8 @@
}
static int
-arp_iattach(void)
+arp_iattach(unused)
+ void *unused;
{
INIT_VNET_INET(curvnet);
@@ -1001,7 +1000,7 @@
#ifdef VIMAGE
vnet_mod_register(&vnet_arp_modinfo);
#else
- arp_iattach();
+ arp_iattach(NULL);
#endif
arpintrq.ifq_maxlen = 50;
mtx_init(&arpintrq.ifq_mtx, "arp_inq", NULL, MTX_DEF);
==== //depot/projects/vimage/src/sys/netinet/ip_fw2.c#18 (text+ko) ====
@@ -118,9 +118,7 @@
#ifdef VIMAGE
static struct vnet_modinfo vnet_ipfw_modinfo = {
.id = VNET_MOD_IPFW,
- .flags = VNET_MFLAG_ORDER_2ND,
.name = "ipfw",
- .symmap = NULL,
.i_attach = vnet_ipfw_iattach,
.i_detach = vnet_ipfw_idetach,
};
==== //depot/projects/vimage/src/sys/sys/vimage.h#18 (text+ko) ====
@@ -76,9 +76,10 @@
#define VNET_MOD_PF 10
#define VNET_MOD_ALTQ 11
#define VNET_MOD_GIF 16
-#define VNET_MOD_ARP 29
-#define VNET_MOD_RTABLE 30
-#define VNET_MOD_LOIF 31
+#define VNET_MOD_ARP 28
+#define VNET_MOD_RTABLE 29
+#define VNET_MOD_LOIF 30
+#define VNET_MOD_DOMAIN 31
#define VNET_MOD_DYNAMIC_START 32
#define VNET_MOD_MAX 64
@@ -110,27 +111,23 @@
int size;
};
-typedef int vnet_attach_t(void);
-typedef int vnet_detach_t(void);
-typedef int vnet_start_t(void);
-typedef int vnet_stop_t(void);
+typedef int vnet_attach_t(void *);
+typedef int vnet_detach_t(void *);
-#define VNET_MFLAG_ORDER_1ST 0x0001
-#define VNET_MFLAG_ORDER_2ND 0x0002
-
struct vnet_modinfo {
- int id;
- int flags;
- char *name;
- struct vnet_symmap *symmap;
- /* Per-instance method hooks */
- vnet_attach_t *i_attach;
- vnet_detach_t *i_detach;
+ int id;
+ int flags;
+ char *name;
+ struct vnet_symmap *symmap;
+ vnet_attach_t *i_attach;
+ vnet_detach_t *i_detach;
};
struct vnet_modlink {
- TAILQ_ENTRY(vnet_modlink) mod_le;
- struct vnet_modinfo *modinfo;
+ TAILQ_ENTRY(vnet_modlink) mod_le;
+ struct vnet_modinfo *modinfo;
+ void *iarg;
+ char *iname;
};
#define VSYM(base, sym) ((base)->_##sym)
@@ -260,6 +257,8 @@
#ifdef VIMAGE
void vnet_mod_register(struct vnet_modinfo *);
void vnet_mod_deregister(struct vnet_modinfo *);
+void vnet_mod_register_multi(struct vnet_modinfo *, void *, char*);
+void vnet_mod_deregister_multi(struct vnet_modinfo *, void *, char*);
void printcpuinfo(struct vprocg *);
struct vimage *vi_alloc(char *, int, int, int);
More information about the p4-projects
mailing list