From owner-svn-src-projects@freebsd.org Sun Apr 24 16:36:34 2016 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2846AB1B6CB for ; Sun, 24 Apr 2016 16:36:34 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 03F1A10C7; Sun, 24 Apr 2016 16:36:33 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u3OGaXSn077512; Sun, 24 Apr 2016 16:36:33 GMT (envelope-from bz@FreeBSD.org) Received: (from bz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u3OGaX8w077511; Sun, 24 Apr 2016 16:36:33 GMT (envelope-from bz@FreeBSD.org) Message-Id: <201604241636.u3OGaX8w077511@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bz set sender to bz@FreeBSD.org using -f From: "Bjoern A. Zeeb" Date: Sun, 24 Apr 2016 16:36:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r298547 - projects/vnet/sys/net X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 Apr 2016 16:36:34 -0000 Author: bz Date: Sun Apr 24 16:36:33 2016 New Revision: 298547 URL: https://svnweb.freebsd.org/changeset/base/298547 Log: Remove the "shutdown" argument again to if_detach_internal(). Using the sysuninit state we do not need this anymore and this simplifies the logic. Make sure we always call the dom_ifdetach handler, aas this is the only place this can happen. Sponsored by: The FreeBSD Foundation Modified: projects/vnet/sys/net/if.c Modified: projects/vnet/sys/net/if.c ============================================================================== --- projects/vnet/sys/net/if.c Sun Apr 24 16:33:25 2016 (r298546) +++ projects/vnet/sys/net/if.c Sun Apr 24 16:36:33 2016 (r298547) @@ -174,9 +174,9 @@ static int if_getgroup(struct ifgroupreq static int if_getgroupmembers(struct ifgroupreq *); static void if_delgroups(struct ifnet *); static void if_attach_internal(struct ifnet *, int, struct if_clone *); -static int if_detach_internal(struct ifnet *, int, int, struct if_clone **); +static int if_detach_internal(struct ifnet *, int, struct if_clone **); #ifdef VIMAGE -static void if_vmove(struct ifnet *, struct vnet *, int); +static void if_vmove(struct ifnet *, struct vnet *); #endif #ifdef INET6 @@ -397,7 +397,7 @@ vnet_if_return(const void *unused __unus /* Return all inherited interfaces to their parent vnets. */ TAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) { if (ifp->if_home_vnet != ifp->if_vnet) - if_vmove(ifp, ifp->if_home_vnet, 1); + if_vmove(ifp, ifp->if_home_vnet); } } VNET_SYSUNINIT(vnet_if_return, SI_SUB_INIT_IF, SI_ORDER_ANY, @@ -904,7 +904,7 @@ if_detach(struct ifnet *ifp) { CURVNET_SET_QUIET(ifp->if_vnet); - if_detach_internal(ifp, 0, 0, NULL); + if_detach_internal(ifp, 0, NULL); CURVNET_RESTORE(); } @@ -919,15 +919,16 @@ if_detach(struct ifnet *ifp) * the cloned interfaces are destoyed as first thing of teardown. */ static int -if_detach_internal(struct ifnet *ifp, int vmove, int shutdown, - struct if_clone **ifcp) +if_detach_internal(struct ifnet *ifp, int vmove, struct if_clone **ifcp) { struct ifaddr *ifa; int i; struct domain *dp; struct ifnet *iter; - int found = 0; + int found = 0, shutdown; + shutdown = (ifp->if_vnet->vnet_state > SI_SUB_VNET && + ifp->if_vnet->vnet_state < SI_SUB_VNET_DONE) ? 1 : 0; IFNET_WLOCK(); TAILQ_FOREACH(iter, &V_ifnet, if_link) if (iter == ifp) { @@ -956,23 +957,51 @@ if_detach_internal(struct ifnet *ifp, in #endif } - /* The one thing we have to do. */ - if_delgroups(ifp); + /* + * At this point we know the interface still was on the ifnet list + * and we removed it so we are in a stable state. + */ /* - * Remove/wait for pending events. + * In any case (destroy or vmove) detach us from the groups + * and remove/wait for pending events on the taskq. + * XXX-BZ in theory an interface could still enqueue a taskq change? */ - taskqueue_drain(taskqueue_swi, &ifp->if_linktask); + if_delgroups(ifp); - if (!vmove && !shutdown && - ifp->if_vnet->vnet_state <= SI_SUB_PSEUDO_DONE) - return (ENOENT); + taskqueue_drain(taskqueue_swi, &ifp->if_linktask); - /* Check if this is a cloned interface or not. */ + /* + * Check if this is a cloned interface or not. Must do even if + * shutting down as a if_vmove_reclaim() would move the ifp and + * the if_clone_addgroup() will have a corrupted string overwise + * from a gibberish pointer. + */ if (vmove && ifcp != NULL) *ifcp = if_clone_findifc(ifp); /* + * On VNET shutdown abort here as the stack teardown will do all + * the work top-down for us. + */ + if (shutdown) { + /* + * In case of a vmove we are done here without error. + * If we would signal an error it would lead to the same + * abort as if we did not find the ifnet anymore. + * if_detach() calls us in void context and does not care + * about an early abort notification, so life is splendid :) + */ + goto finish_vnet_shutdown; + } + + /* + * At this point we are not tearing down a VNET and are either + * going to destroy or vmove the interface and have to cleanup + * accordingly. + */ + + /* * Remove routes and flush queues. */ if_down(ifp); @@ -986,7 +1015,7 @@ if_detach_internal(struct ifnet *ifp, in if_purgeaddrs(ifp); #ifdef INET - in_ifdetach(ifp, !shutdown); + in_ifdetach(ifp, 1); #endif #ifdef INET6 @@ -996,10 +1025,9 @@ if_detach_internal(struct ifnet *ifp, in * routes are expected to be removed by the IPv6-specific kernel API. * Otherwise, the kernel will detect some inconsistency and bark it. */ - in6_ifdetach(ifp, !shutdown); + in6_ifdetach(ifp, 1); #endif - if (!shutdown) - if_purgemaddrs(ifp); + if_purgemaddrs(ifp); /* Announce that the interface is gone. */ rt_ifannouncemsg(ifp, IFAN_DEPARTURE); @@ -1029,9 +1057,9 @@ if_detach_internal(struct ifnet *ifp, in } } - if (!shutdown) - rt_flushifroutes(ifp); + rt_flushifroutes(ifp); +finish_vnet_shutdown: /* * We cannot hold the lock over dom_ifdetach calls as they might * sleep, for example trying to drain a callout, thus open up the @@ -1059,7 +1087,7 @@ if_detach_internal(struct ifnet *ifp, in * and finally find an unused if_xname for the target vnet. */ static void -if_vmove(struct ifnet *ifp, struct vnet *new_vnet, int shutdown) +if_vmove(struct ifnet *ifp, struct vnet *new_vnet) { struct if_clone *ifc; int rc; @@ -1077,7 +1105,7 @@ if_vmove(struct ifnet *ifp, struct vnet * mark as dead etc. so that the ifnet can be reattached later. * If we cannot find it, we lost the race to someone else. */ - rc = if_detach_internal(ifp, 1, shutdown, &ifc); + rc = if_detach_internal(ifp, 1, &ifc); if (rc != 0) return; @@ -1152,7 +1180,7 @@ if_vmove_loan(struct thread *td, struct } /* Move the interface into the child jail/vnet. */ - if_vmove(ifp, pr->pr_vnet, 0); + if_vmove(ifp, pr->pr_vnet); /* Report the new if_xname back to the userland. */ sprintf(ifname, "%s", ifp->if_xname); @@ -1195,7 +1223,7 @@ if_vmove_reclaim(struct thread *td, char } /* Get interface back from child jail/vnet. */ - if_vmove(ifp, vnet_dst, 0); + if_vmove(ifp, vnet_dst); CURVNET_RESTORE(); /* Report the new if_xname back to the userland. */