PERFORCE change 168604 for review
Marko Zec
zec at FreeBSD.org
Thu Sep 17 11:16:34 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=168604
Change 168604 by zec at 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);
More information about the p4-projects
mailing list