svn commit: r213895 - stable/7/sys/net
Bjoern A. Zeeb
bz at FreeBSD.org
Fri Oct 15 15:06:32 UTC 2010
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 <net/if_tun.h>
#include <sys/queue.h>
+#include <sys/condvar.h>
#include <security/mac/mac_framework.h>
@@ -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);
}
More information about the svn-src-stable
mailing list