Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Sep 2009 11:16:33 GMT
From:      Marko Zec <zec@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 168604 for review
Message-ID:  <200909171116.n8HBGXMH067132@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=168604

Change 168604 by zec@zec_tpx32 on 2009/09/17 11:15:37

	Before a vnet can be safely shut down it must hold no ifnets
	of its own except lo0.  ng_eiface and ng_iface are currently
	prone to leave ifnet instances behind, hence leading to
	panics on vnet destroy.  This change introduces per-vnet
	lists of ng_eiface vnets, which is traversed and cleaned up
	early in vnet destroy sequence.
	
	So as an result we no longer get a panic on vnet destroy in
	vnet_ng_eiface_uninit(), but someplace else in mcast code, yeah!

Affected files ...

.. //depot/projects/vimage/src/sys/netgraph/ng_eiface.c#35 edit

Differences ...

==== //depot/projects/vimage/src/sys/netgraph/ng_eiface.c#35 (text+ko) ====

@@ -79,9 +79,20 @@
 	int		unit;		/* Interface unit number */
 	node_p		node;		/* Our netgraph node */
 	hook_p		ether;		/* Hook for ethernet stream */
+	LIST_ENTRY(ng_eiface_private) le; /* All eiface nodes in a vnet */
 };
 typedef struct ng_eiface_private *priv_p;
 
+#ifdef VIMAGE
+/* Per-vnet list of eiface nodes */
+static VNET_DEFINE(LIST_HEAD(, ng_eiface_private), ng_eiface_list);
+#define	V_ng_eiface_list		VNET(ng_eiface_list)
+
+static struct sx ng_eiface_list_sxlock;
+#define NG_EIFACE_LIST_WLOCK()    sx_xlock(&ng_eiface_list_sxlock);
+#define NG_EIFACE_LIST_WUNLOCK()  sx_xunlock(&ng_eiface_list_sxlock);
+#endif
+
 /* Interface methods */
 static void	ng_eiface_init(void *xsc);
 static void	ng_eiface_start(struct ifnet *ifp);
@@ -362,6 +373,11 @@
 	/* Link together node and private info */
 	NG_NODE_SET_PRIVATE(node, priv);
 	priv->node = node;
+#ifdef VIMAGE
+	NG_EIFACE_LIST_WLOCK();
+	LIST_INSERT_HEAD(&V_ng_eiface_list, priv, le);
+	NG_EIFACE_LIST_WUNLOCK();
+#endif
 
 	/* Initialize interface structure */
 	if_initname(ifp, NG_EIFACE_EIFACE_NAME, priv->unit);
@@ -560,6 +576,11 @@
 	ether_ifdetach(ifp);
 	if_free(ifp);
 	CURVNET_RESTORE();
+#ifdef VIMAGE
+	NG_EIFACE_LIST_WLOCK();
+	LIST_REMOVE(priv, le);
+	NG_EIFACE_LIST_WUNLOCK();
+#endif
 	free_unr(V_ng_eiface_unit, priv->unit);
 	free(priv, M_NETGRAPH);
 	NG_NODE_SET_PRIVATE(node, NULL);
@@ -589,7 +610,15 @@
 
 	switch (event) {
 	case MOD_LOAD:
+#ifdef VIMAGE
+		sx_init_flags(&ng_eiface_list_sxlock, "ng_eiface_sxlock",
+		    SX_RECURSE);
+#endif
+		break;
 	case MOD_UNLOAD:
+#ifdef VIMAGE
+		sx_destroy(&ng_eiface_list_sxlock);
+#endif
 		break;
 	default:
 		error = EOPNOTSUPP;
@@ -602,6 +631,9 @@
 vnet_ng_eiface_init(const void *unused)
 {
 
+#ifdef VIMAGE
+	LIST_INIT(&V_ng_eiface_list);
+#endif
 	V_ng_eiface_unit = new_unrhdr(0, 0xffff, NULL);
 }
 VNET_SYSINIT(vnet_ng_eiface_init, SI_SUB_PSEUDO, SI_ORDER_ANY,
@@ -610,19 +642,18 @@
 static void
 vnet_ng_eiface_uninit(const void *unused)
 {
-#ifdef VIMAGE_NOTYET
-	node_p node;
+#ifdef VIMAGE
+	priv_p node_p, nnode_p;
 
-	do {
-		LIST_FOREACH(node, &V_ng_nodelist, nd_nodes)
-			if (node->nd_type == &typestruct)
-				break;
-		if (node != NULL)
-			ng_rmnode_self(node);
-	} while (node != NULL);
+	NG_EIFACE_LIST_WLOCK();
+	LIST_FOREACH_SAFE(node_p, &V_ng_eiface_list, le, nnode_p) {
+		if (node_p->node->nd_type == &typestruct)
+			ng_rmnode_self(node_p->node);
+	}
+	NG_EIFACE_LIST_WUNLOCK();
 #endif
 
 	delete_unrhdr(V_ng_eiface_unit);
 }
-VNET_SYSUNINIT(vnet_ng_eiface_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY,
+VNET_SYSUNINIT(vnet_ng_eiface_uninit, SI_SUB_PSEUDO, SI_ORDER_FIRST,
    vnet_ng_eiface_uninit, NULL);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200909171116.n8HBGXMH067132>