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>