From owner-svn-src-head@FreeBSD.ORG Tue Dec 16 23:06:37 2008 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 62DC0106567B; Tue, 16 Dec 2008 23:06:37 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B31948FC14; Tue, 16 Dec 2008 23:06:36 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id mBGN6auE049993; Tue, 16 Dec 2008 23:06:36 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mBGN6agp049992; Tue, 16 Dec 2008 23:06:36 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <200812162306.mBGN6agp049992@svn.freebsd.org> From: Kip Macy Date: Tue, 16 Dec 2008 23:06:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r186196 - head/sys/netinet6 X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Dec 2008 23:06:38 -0000 Author: kmacy Date: Tue Dec 16 23:06:36 2008 New Revision: 186196 URL: http://svn.freebsd.org/changeset/base/186196 Log: - Simplify handling of the deferring of mbuf transmit until after lle lock drop - add a couple of comments to clarify intent Modified: head/sys/netinet6/nd6.c Modified: head/sys/netinet6/nd6.c ============================================================================== --- head/sys/netinet6/nd6.c Tue Dec 16 22:16:34 2008 (r186195) +++ head/sys/netinet6/nd6.c Tue Dec 16 23:06:36 2008 (r186196) @@ -1407,7 +1407,7 @@ nd6_cache_lladdr(struct ifnet *ifp, stru int newstate = 0; uint16_t router = 0; struct sockaddr_in6 sin6; - struct mbuf *tail = NULL, *chain = NULL; + struct mbuf *chain = NULL; int static_route = 0; IF_AFDATA_UNLOCK_ASSERT(ifp); @@ -1526,11 +1526,14 @@ nd6_cache_lladdr(struct ifnet *ifp, stru * just set the 2nd argument as the * 1st one. */ - nd6_output_lle(ifp, ifp, m_hold, L3_ADDR_SIN6(ln), NULL, ln, &tail); - if ((tail != NULL) && chain == (NULL)) - chain = tail; + nd6_output_lle(ifp, ifp, m_hold, L3_ADDR_SIN6(ln), NULL, ln, &chain); } - if (chain) + /* + * If we have mbufs in the chain we need to do + * deferred transmit. Copy the address from the + * llentry before dropping the lock down below. + */ + if (chain != NULL) memcpy(&sin6, L3_ADDR_SIN6(ln), sizeof(sin6)); } } else if (ln->ln_state == ND6_LLINFO_INCOMPLETE) { @@ -1706,7 +1709,7 @@ nd6_output(struct ifnet *ifp, struct ifn int nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0, struct sockaddr_in6 *dst, struct rtentry *rt0, struct llentry *lle, - struct mbuf **tail) + struct mbuf **chain) { INIT_VNET_INET6(curvnet); struct mbuf *m = m0; @@ -1720,7 +1723,7 @@ nd6_output_lle(struct ifnet *ifp, struct LLE_WLOCK_ASSERT(lle); - KASSERT(tail != NULL, (" lle locked but no tail pointer passed")); + KASSERT(chain != NULL, (" lle locked but no mbuf chain pointer passed")); } #endif if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr)) @@ -1888,12 +1891,25 @@ nd6_output_lle(struct ifnet *ifp, struct #ifdef MAC mac_netinet6_nd6_send(ifp, m); #endif + /* + * We were passed in a pointer to an lle with the lock held + * this means that we can't call if_output as we will + * recurse on the lle lock - so what we do is we create + * a list of mbufs to send and transmit them in the caller + * after the lock is dropped + */ if (lle != NULL) { - if (*tail == NULL) - *tail = m; - else { - (*tail)->m_nextpkt = m; - *tail = m; + if (*chain == NULL) + *chain = m; + else { + struct mbuf *m = *chain; + + /* + * append mbuf to end of deferred chain + */ + while (m->m_nextpkt != NULL) + m = m->m_nextpkt; + m->m_nextpkt = m; } return (error); }