From owner-svn-src-all@FreeBSD.ORG Fri Oct 15 15:06:32 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 62B23106564A; Fri, 15 Oct 2010 15:06:32 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 50CC78FC13; Fri, 15 Oct 2010 15:06:32 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o9FF6WOI065165; Fri, 15 Oct 2010 15:06:32 GMT (envelope-from bz@svn.freebsd.org) Received: (from bz@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o9FF6WxG065163; Fri, 15 Oct 2010 15:06:32 GMT (envelope-from bz@svn.freebsd.org) Message-Id: <201010151506.o9FF6WxG065163@svn.freebsd.org> From: "Bjoern A. Zeeb" Date: Fri, 15 Oct 2010 15:06:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r213895 - stable/7/sys/net X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Oct 2010 15:06:32 -0000 Author: bz Date: Fri Oct 15 15:06:32 2010 New Revision: 213895 URL: http://svn.freebsd.org/changeset/base/213895 Log: MFC r186391,186483,186497 (qingli, kmacy 21 months ago): r186391: Provide a condition variable to delay the cloned interface destroy operation until the referenced clone device has been closed by the process properly. The behavior is now consistently with the previous release. r186483: - Close a race during which the open flag could be cleared but the tun_softc would still be referenced by adding a separate TUN_CLOSED flag that is set after tunclose is done referencing it. - drop the tun_mtx after the flag check to avoid holding it across if_detach which can recurse in to if_tun.c r186497: The "tun?" dev need not be opened at all. One is allowed to perform the following operations, e.g.: 1) ifconfig tun0 create 2) ifconfig tun0 10.1.1.1 10.1.1.2 3) route add -net 192.103.54.0/24 -iface tun0 4) ifconfig tun0 destroy If cv wait on the TUN_CLOSED flag, then the last operation (4) will block forever. Revert the previous changes and fix the mtx_unlock() leak. PR: kern/116837 Submitted by: Mikolaj Golub (to.my.trociny gmail.com) (Not used the patch, just did the MFC) Modified: stable/7/sys/net/if_tun.c Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/net/if_tun.c ============================================================================== --- stable/7/sys/net/if_tun.c Fri Oct 15 15:00:30 2010 (r213894) +++ stable/7/sys/net/if_tun.c Fri Oct 15 15:06:32 2010 (r213895) @@ -56,6 +56,7 @@ #include #include +#include #include @@ -92,6 +93,7 @@ struct tun_softc { struct sigio *tun_sigio; /* information for async I/O */ struct selinfo tun_rsel; /* read select */ struct mtx tun_mtx; /* protect mutable softc fields */ + struct cv tun_cv; /* protect against ref'd dev destroy */ }; #define TUN2IFP(sc) ((sc)->tun_ifp) @@ -242,8 +244,11 @@ tun_destroy(struct tun_softc *tp) struct cdev *dev; /* Unlocked read. */ - KASSERT((tp->tun_flags & TUN_OPEN) == 0, - ("tununits is out of sync - unit %d", TUN2IFP(tp)->if_dunit)); + mtx_lock(&tp->tun_mtx); + if ((tp->tun_flags & TUN_OPEN) != 0) + cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx); + else + mtx_unlock(&tp->tun_mtx); dev = tp->tun_dev; bpfdetach(TUN2IFP(tp)); @@ -252,6 +257,7 @@ tun_destroy(struct tun_softc *tp) destroy_dev(dev); knlist_destroy(&tp->tun_rsel.si_note); mtx_destroy(&tp->tun_mtx); + cv_destroy(&tp->tun_cv); free(tp, M_TUN); } @@ -353,6 +359,7 @@ tuncreate(const char *name, struct cdev MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO); mtx_init(&sc->tun_mtx, "tun_mtx", NULL, MTX_DEF); + cv_init(&sc->tun_cv, "tun_condvar"); sc->tun_flags = TUN_INITED; sc->tun_dev = dev; mtx_lock(&tunmtx); @@ -472,6 +479,8 @@ tunclose(struct cdev *dev, int foo, int selwakeuppri(&tp->tun_rsel, PZERO + 1); KNOTE_LOCKED(&tp->tun_rsel.si_note, 0); TUNDEBUG (ifp, "closed\n"); + + cv_broadcast(&tp->tun_cv); mtx_unlock(&tp->tun_mtx); return (0); }