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