From owner-svn-src-stable-9@FreeBSD.ORG Thu Mar 28 20:48:41 2013 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 34CDB4C7; Thu, 28 Mar 2013 20:48:41 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 0CF49233; Thu, 28 Mar 2013 20:48:41 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r2SKmel6094665; Thu, 28 Mar 2013 20:48:40 GMT (envelope-from emaste@svn.freebsd.org) Received: (from emaste@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r2SKmeUL094662; Thu, 28 Mar 2013 20:48:40 GMT (envelope-from emaste@svn.freebsd.org) Message-Id: <201303282048.r2SKmeUL094662@svn.freebsd.org> From: Ed Maste Date: Thu, 28 Mar 2013 20:48:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r248852 - in stable/9/sys: net netinet netinet6 X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Mar 2013 20:48:41 -0000 Author: emaste Date: Thu Mar 28 20:48:40 2013 New Revision: 248852 URL: http://svnweb.freebsd.org/changeset/base/248852 Log: MFC r244183 by glebius: Fix problem in r238990 (MFC'd in r240313). The LLE_LINKED flag should be tested prior to entering llentry_free(), and in case if we lose the race, we should simply perform LLE_FREE_LOCKED(). Otherwise, if the race is lost by the thread performing arptimer(), it will remove two references from the lle instead of one. Reported by: Ian FREISLICH Modified: stable/9/sys/net/if_llatbl.c stable/9/sys/netinet/if_ether.c stable/9/sys/netinet6/nd6.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/net/ (props changed) Modified: stable/9/sys/net/if_llatbl.c ============================================================================== --- stable/9/sys/net/if_llatbl.c Thu Mar 28 20:37:07 2013 (r248851) +++ stable/9/sys/net/if_llatbl.c Thu Mar 28 20:48:40 2013 (r248852) @@ -112,12 +112,6 @@ llentry_free(struct llentry *lle) IF_AFDATA_WLOCK_ASSERT(lle->lle_tbl->llt_ifp); LLE_WLOCK_ASSERT(lle); - /* XXX: guard against race with other llentry_free(). */ - if (!(lle->la_flags & LLE_LINKED)) { - LLE_FREE_LOCKED(lle); - return (0); - } - LIST_REMOVE(lle, lle_next); lle->la_flags &= ~(LLE_VALID | LLE_LINKED); Modified: stable/9/sys/netinet/if_ether.c ============================================================================== --- stable/9/sys/netinet/if_ether.c Thu Mar 28 20:37:07 2013 (r248851) +++ stable/9/sys/netinet/if_ether.c Thu Mar 28 20:48:40 2013 (r248852) @@ -169,7 +169,6 @@ arptimer(void *arg) { struct llentry *lle = (struct llentry *)arg; struct ifnet *ifp; - size_t pkts_dropped; if (lle->la_flags & LLE_STATIC) { LLE_WUNLOCK(lle); @@ -186,11 +185,20 @@ arptimer(void *arg) IF_AFDATA_LOCK(ifp); LLE_WLOCK(lle); - LLE_REMREF(lle); - pkts_dropped = llentry_free(lle); + /* Guard against race with other llentry_free(). */ + if (lle->la_flags & LLE_LINKED) { + size_t pkts_dropped; + + LLE_REMREF(lle); + pkts_dropped = llentry_free(lle); + ARPSTAT_ADD(dropped, pkts_dropped); + } else + LLE_FREE_LOCKED(lle); + IF_AFDATA_UNLOCK(ifp); - ARPSTAT_ADD(dropped, pkts_dropped); + ARPSTAT_INC(timeouts); + CURVNET_RESTORE(); } Modified: stable/9/sys/netinet6/nd6.c ============================================================================== --- stable/9/sys/netinet6/nd6.c Thu Mar 28 20:37:07 2013 (r248851) +++ stable/9/sys/netinet6/nd6.c Thu Mar 28 20:48:40 2013 (r248852) @@ -1111,8 +1111,14 @@ nd6_free(struct llentry *ln, int gc) LLE_WUNLOCK(ln); IF_AFDATA_LOCK(ifp); LLE_WLOCK(ln); - LLE_REMREF(ln); - llentry_free(ln); + + /* Guard against race with other llentry_free(). */ + if (ln->la_flags & LLE_LINKED) { + LLE_REMREF(ln); + llentry_free(ln); + } else + LLE_FREE_LOCKED(ln); + IF_AFDATA_UNLOCK(ifp); return (next);