Page MenuHomeFreeBSD

D28136.id83306.diff
No OneTemporary

D28136.id83306.diff

diff --git a/sys/dev/usb/net/if_usie.c b/sys/dev/usb/net/if_usie.c
--- a/sys/dev/usb/net/if_usie.c
+++ b/sys/dev/usb/net/if_usie.c
@@ -483,6 +483,7 @@
usbd_transfer_unsetup(sc->sc_if_xfer, USIE_IF_N_XFER);
bpfdetach(sc->sc_ifp);
if_detach(sc->sc_ifp);
+ if_slow_drain(sc->sc_ifp);
if_free(sc->sc_ifp);
sc->sc_ifp = NULL;
}
diff --git a/sys/dev/usb/net/uhso.c b/sys/dev/usb/net/uhso.c
--- a/sys/dev/usb/net/uhso.c
+++ b/sys/dev/usb/net/uhso.c
@@ -693,8 +693,9 @@
uhso_if_stop(sc);
bpfdetach(sc->sc_ifp);
if_detach(sc->sc_ifp);
- if_free(sc->sc_ifp);
mtx_unlock(&sc->sc_mtx);
+ if_slow_drain(sc->sc_ifp);
+ if_free(sc->sc_ifp);
usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX);
}
diff --git a/sys/dev/usb/net/usb_ethernet.c b/sys/dev/usb/net/usb_ethernet.c
--- a/sys/dev/usb/net/usb_ethernet.c
+++ b/sys/dev/usb/net/usb_ethernet.c
@@ -292,6 +292,7 @@
/* free unit */
free_unr(ueunit, ue->ue_unit);
if (ue->ue_ifp != NULL) {
+ if_slow_drain(ue->ue_ifp);
if_free(ue->ue_ifp);
ue->ue_ifp = NULL;
}
@@ -311,6 +312,9 @@
ifp = ue->ue_ifp;
if (ifp != NULL) {
+ /* drain all IOCTLs */
+ if_slow_drain(ifp);
+
/* we are not running any more */
UE_LOCK(ue);
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
diff --git a/sys/dev/usb/usb_pf.c b/sys/dev/usb/usb_pf.c
--- a/sys/dev/usb/usb_pf.c
+++ b/sys/dev/usb/usb_pf.c
@@ -232,6 +232,7 @@
USB_BUS_UNLOCK(ubus);
bpfdetach(ifp);
if_detach(ifp);
+ if_slow_drain(ifp);
if_free(ifp);
ifc_free_unit(ifc, unit);
diff --git a/sys/net/if.c b/sys/net/if.c
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -645,6 +645,8 @@
ifq_init(&ifp->if_snd, ifp);
refcount_init(&ifp->if_refcount, 1); /* Index reference. */
+ refcount_init(&ifp->if_slowref, 1);
+
for (int i = 0; i < IFCOUNTERS; i++)
ifp->if_counters[i] = counter_u64_alloc(M_WAITOK);
ifp->if_get_counter = if_get_counter_default;
@@ -753,6 +755,32 @@
NET_EPOCH_CALL(if_destroy, &ifp->if_epoch_ctx);
}
+/*
+ * Keep track of slow path configuration events.
+ * Returns true on success and false on failure.
+ */
+bool
+if_slow_ref(struct ifnet *ifp)
+{
+ return (refcount_acquire_if_not_zero(&ifp->if_slowref));
+}
+
+void
+if_slow_drain(struct ifnet *ifp)
+{
+ if (refcount_release(&ifp->if_slowref))
+ return;
+
+ while (refcount_load(&ifp->if_slowref) != 0)
+ pause("W", hz);
+}
+
+void
+if_slow_unref(struct ifnet *ifp)
+{
+ (void) refcount_release(&ifp->if_slowref);
+}
+
void
ifq_init(struct ifaltq *ifq, struct ifnet *ifp)
{
@@ -2459,8 +2487,8 @@
/*
* Hardware specific interface ioctls.
*/
-int
-ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
+static inline int
+ifhwioctl_sub(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
{
struct ifreq *ifr;
int error = 0, do_ifup = 0;
@@ -2887,6 +2915,19 @@
return (error);
}
+int
+ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
+{
+ int error;
+
+ if (if_slow_ref(ifp) == false)
+ return (ENXIO);
+ error = ifhwioctl_sub(cmd, ifp, data, td);
+ if_slow_unref(ifp);
+ return (error);
+}
+
+
#ifdef COMPAT_FREEBSD32
struct ifconf32 {
int32_t ifc_len;
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -313,6 +313,7 @@
void *if_linkmib; /* link-type-specific MIB data */
size_t if_linkmiblen; /* length of above data */
u_int if_refcount; /* reference count */
+ u_int if_slowref; /* reference count (slow path) */
/* These fields are shared with struct if_data. */
uint8_t if_type; /* ethernet, tokenring, etc */
@@ -660,6 +661,9 @@
int if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
void if_ref(struct ifnet *);
void if_rele(struct ifnet *);
+bool if_slow_ref(struct ifnet *) __result_use_check;
+void if_slow_drain(struct ifnet *);
+void if_slow_unref(struct ifnet *);
int if_setlladdr(struct ifnet *, const u_char *, int);
int if_tunnel_check_nesting(struct ifnet *, struct mbuf *, uint32_t, int);
void if_up(struct ifnet *);

File Metadata

Mime Type
text/plain
Expires
Wed, Dec 31, 8:34 AM (4 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27406729
Default Alt Text
D28136.id83306.diff (3 KB)

Event Timeline