Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Dec 2008 01:56:56 +0000 (UTC)
From:      Qing Li <qingli@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r186391 - head/sys/net
Message-ID:  <200812220156.mBM1uutQ047908@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: qingli
Date: Mon Dec 22 01:56:56 2008
New Revision: 186391
URL: http://svn.freebsd.org/changeset/base/186391

Log:
  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.
  
  Reviewed by: 	  Kip Macy

Modified:
  head/sys/net/if_tun.c

Modified: head/sys/net/if_tun.c
==============================================================================
--- head/sys/net/if_tun.c	Mon Dec 22 00:53:47 2008	(r186390)
+++ head/sys/net/if_tun.c	Mon Dec 22 01:56:56 2008	(r186391)
@@ -57,6 +57,7 @@
 #include <net/if_tun.h>
 
 #include <sys/queue.h>
+#include <sys/condvar.h>
 
 #include <security/mac/mac_framework.h>
 
@@ -93,6 +94,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)
 
@@ -253,8 +255,9 @@ 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);
 
 	CURVNET_SET(TUN2IFP(tp)->if_vnet);
 	dev = tp->tun_dev;
@@ -264,6 +267,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);
 	CURVNET_RESTORE();
 }
@@ -365,6 +369,7 @@ tuncreate(const char *name, struct cdev 
 
 	sc = malloc(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);
@@ -449,6 +454,7 @@ tunclose(struct cdev *dev, int foo, int 
 	mtx_lock(&tp->tun_mtx);
 	tp->tun_flags &= ~TUN_OPEN;
 	tp->tun_pid = 0;
+	mtx_unlock(&tp->tun_mtx);
 
 	/*
 	 * junk all pending output
@@ -457,7 +463,6 @@ tunclose(struct cdev *dev, int foo, int 
 	s = splimp();
 	IFQ_PURGE(&ifp->if_snd);
 	splx(s);
-	mtx_unlock(&tp->tun_mtx);
 
 	if (ifp->if_flags & IFF_UP) {
 		s = splimp();
@@ -486,10 +491,14 @@ tunclose(struct cdev *dev, int foo, int 
 	if_link_state_change(ifp, LINK_STATE_DOWN);
 	CURVNET_RESTORE();
 
+	mtx_lock(&tp->tun_mtx);
 	funsetown(&tp->tun_sigio);
 	selwakeuppri(&tp->tun_rsel, PZERO + 1);
 	KNOTE_UNLOCKED(&tp->tun_rsel.si_note, 0);
 	TUNDEBUG (ifp, "closed\n");
+
+	cv_broadcast(&tp->tun_cv);
+	mtx_unlock(&tp->tun_mtx);
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812220156.mBM1uutQ047908>