Avoid INVARIANTS panic destroying an in-use tap(4)

The requirement (implied by the KASSERT in tap_destroy) that the tap is
closed isn't valid; destroy_dev will block in devdrn while other threads
are in d_* functions.

Note: if_tun had the same issue, addressed in SVN revisions r186391,
r186483 and r186497.  The use of the condvar there appears to be
redundant with the functionality provided by destroy_dev.

Sponsored by:	ADARA Networks
Reviewed by:	dwhite
MFC after:	2 weeks
This commit is contained in:
emaste 2012-09-25 22:10:14 +00:00
parent b79f4497f4
commit e89f1e2950
2 changed files with 2 additions and 5 deletions

View File

@ -213,14 +213,10 @@ tap_destroy(struct tap_softc *tp)
{
struct ifnet *ifp = tp->tap_ifp;
/* Unlocked read. */
KASSERT(!(tp->tap_flags & TAP_OPEN),
("%s flags is out of sync", ifp->if_xname));
CURVNET_SET(ifp->if_vnet);
destroy_dev(tp->tap_dev);
seldrain(&tp->tap_rsel);
knlist_destroy(&tp->tap_rsel.si_note);
destroy_dev(tp->tap_dev);
ether_ifdetach(ifp);
if_free(ifp);

View File

@ -64,6 +64,7 @@ struct tap_softc {
SLIST_ENTRY(tap_softc) tap_next; /* next device in chain */
struct cdev *tap_dev;
struct mtx tap_mtx; /* per-softc mutex */
struct cv tap_cv; /* protect ref'd dev destroy */
};
#endif /* !_NET_IF_TAPVAR_H_ */