View | Details | Raw Unified | Return to bug 252608 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/dev/usb/net/if_usie.c (+1 lines)
Lines 483-488 usie_detach(device_t self) Link Here
483
		usbd_transfer_unsetup(sc->sc_if_xfer, USIE_IF_N_XFER);
483
		usbd_transfer_unsetup(sc->sc_if_xfer, USIE_IF_N_XFER);
484
		bpfdetach(sc->sc_ifp);
484
		bpfdetach(sc->sc_ifp);
485
		if_detach(sc->sc_ifp);
485
		if_detach(sc->sc_ifp);
486
		if_slow_drain(sc->sc_ifp);
486
		if_free(sc->sc_ifp);
487
		if_free(sc->sc_ifp);
487
		sc->sc_ifp = NULL;
488
		sc->sc_ifp = NULL;
488
	}
489
	}
(-)b/sys/dev/usb/net/uhso.c (-1 / +2 lines)
Lines 693-700 uhso_detach(device_t self) Link Here
693
		uhso_if_stop(sc);
693
		uhso_if_stop(sc);
694
		bpfdetach(sc->sc_ifp);
694
		bpfdetach(sc->sc_ifp);
695
		if_detach(sc->sc_ifp);
695
		if_detach(sc->sc_ifp);
696
		if_free(sc->sc_ifp);
697
		mtx_unlock(&sc->sc_mtx);
696
		mtx_unlock(&sc->sc_mtx);
697
		if_slow_drain(sc->sc_ifp);
698
		if_free(sc->sc_ifp);
698
		usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX);
699
		usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX);
699
	}
700
	}
700
701
(-)b/sys/dev/usb/net/usb_ethernet.c (+4 lines)
Lines 292-297 ue_attach_post_task(struct usb_proc_msg *_task) Link Here
292
	/* free unit */
292
	/* free unit */
293
	free_unr(ueunit, ue->ue_unit);
293
	free_unr(ueunit, ue->ue_unit);
294
	if (ue->ue_ifp != NULL) {
294
	if (ue->ue_ifp != NULL) {
295
		if_slow_drain(ue->ue_ifp);
295
		if_free(ue->ue_ifp);
296
		if_free(ue->ue_ifp);
296
		ue->ue_ifp = NULL;
297
		ue->ue_ifp = NULL;
297
	}
298
	}
Lines 311-316 uether_ifdetach(struct usb_ether *ue) Link Here
311
	ifp = ue->ue_ifp;
312
	ifp = ue->ue_ifp;
312
313
313
	if (ifp != NULL) {
314
	if (ifp != NULL) {
315
		/* drain all IOCTLs */
316
		if_slow_drain(ifp);
317
314
		/* we are not running any more */
318
		/* we are not running any more */
315
		UE_LOCK(ue);
319
		UE_LOCK(ue);
316
		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
320
		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
(-)b/sys/dev/usb/usb_pf.c (+1 lines)
Lines 232-237 usbpf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp) Link Here
232
	USB_BUS_UNLOCK(ubus);
232
	USB_BUS_UNLOCK(ubus);
233
	bpfdetach(ifp);
233
	bpfdetach(ifp);
234
	if_detach(ifp);
234
	if_detach(ifp);
235
	if_slow_drain(ifp);
235
	if_free(ifp);
236
	if_free(ifp);
236
	ifc_free_unit(ifc, unit);
237
	ifc_free_unit(ifc, unit);
237
238
(-)b/sys/net/if.c (-2 / +44 lines)
Lines 645-650 if_alloc_domain(u_char type, int numa_domain) Link Here
645
	ifq_init(&ifp->if_snd, ifp);
645
	ifq_init(&ifp->if_snd, ifp);
646
646
647
	refcount_init(&ifp->if_refcount, 1);	/* Index reference. */
647
	refcount_init(&ifp->if_refcount, 1);	/* Index reference. */
648
	refcount_init(&ifp->if_slowref, 1);
649
648
	for (int i = 0; i < IFCOUNTERS; i++)
650
	for (int i = 0; i < IFCOUNTERS; i++)
649
		ifp->if_counters[i] = counter_u64_alloc(M_WAITOK);
651
		ifp->if_counters[i] = counter_u64_alloc(M_WAITOK);
650
	ifp->if_get_counter = if_get_counter_default;
652
	ifp->if_get_counter = if_get_counter_default;
Lines 753-758 if_rele(struct ifnet *ifp) Link Here
753
	NET_EPOCH_CALL(if_destroy, &ifp->if_epoch_ctx);
755
	NET_EPOCH_CALL(if_destroy, &ifp->if_epoch_ctx);
754
}
756
}
755
757
758
/*
759
 * Keep track of slow path configuration events.
760
 * Returns true on success and false on failure.
761
 */
762
bool
763
if_slow_ref(struct ifnet *ifp)
764
{
765
	return (refcount_acquire_if_not_zero(&ifp->if_slowref));
766
}
767
768
void
769
if_slow_drain(struct ifnet *ifp)
770
{
771
	if (refcount_release(&ifp->if_slowref))
772
		return;
773
774
	while (refcount_load(&ifp->if_slowref) != 0)
775
		pause("W", hz);
776
}
777
778
void
779
if_slow_unref(struct ifnet *ifp)
780
{
781
	if (refcount_release(&ifp->if_slowref))
782
		return;
783
}
784
756
void
785
void
757
ifq_init(struct ifaltq *ifq, struct ifnet *ifp)
786
ifq_init(struct ifaltq *ifq, struct ifnet *ifp)
758
{
787
{
Lines 2459-2466 ifr_data_get_ptr(void *ifrp) Link Here
2459
/*
2488
/*
2460
 * Hardware specific interface ioctls.
2489
 * Hardware specific interface ioctls.
2461
 */
2490
 */
2462
int
2491
static inline int
2463
ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
2492
ifhwioctl_sub(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
2464
{
2493
{
2465
	struct ifreq *ifr;
2494
	struct ifreq *ifr;
2466
	int error = 0, do_ifup = 0;
2495
	int error = 0, do_ifup = 0;
Lines 2887-2892 ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) Link Here
2887
	return (error);
2916
	return (error);
2888
}
2917
}
2889
2918
2919
int
2920
ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
2921
{
2922
	int error;
2923
2924
	if (if_slow_ref(ifp) == false)
2925
		return (ENXIO);
2926
	error = ifhwioctl_sub(cmd, ifp, data, td);
2927
	if_slow_unref(ifp);
2928
	return (error);
2929
}
2930
2931
2890
#ifdef COMPAT_FREEBSD32
2932
#ifdef COMPAT_FREEBSD32
2891
struct ifconf32 {
2933
struct ifconf32 {
2892
	int32_t	ifc_len;
2934
	int32_t	ifc_len;
(-)b/sys/net/if_var.h (+4 lines)
Lines 312-317 struct ifnet { Link Here
312
	void	*if_linkmib;		/* link-type-specific MIB data */
312
	void	*if_linkmib;		/* link-type-specific MIB data */
313
	size_t	if_linkmiblen;		/* length of above data */
313
	size_t	if_linkmiblen;		/* length of above data */
314
	u_int	if_refcount;		/* reference count */
314
	u_int	if_refcount;		/* reference count */
315
  	u_int	if_slowref;		/* reference count (slow path) */
315
316
316
	/* These fields are shared with struct if_data. */
317
	/* These fields are shared with struct if_data. */
317
	uint8_t		if_type;	/* ethernet, tokenring, etc */
318
	uint8_t		if_type;	/* ethernet, tokenring, etc */
Lines 658-663 void if_link_state_change(struct ifnet *, int); Link Here
658
int	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
659
int	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
659
void	if_ref(struct ifnet *);
660
void	if_ref(struct ifnet *);
660
void	if_rele(struct ifnet *);
661
void	if_rele(struct ifnet *);
662
bool	if_slow_ref(struct ifnet *) __result_use_check;
663
void	if_slow_drain(struct ifnet *);
664
void	if_slow_unref(struct ifnet *);
661
int	if_setlladdr(struct ifnet *, const u_char *, int);
665
int	if_setlladdr(struct ifnet *, const u_char *, int);
662
int	if_tunnel_check_nesting(struct ifnet *, struct mbuf *, uint32_t, int);
666
int	if_tunnel_check_nesting(struct ifnet *, struct mbuf *, uint32_t, int);
663
void	if_up(struct ifnet *);
667
void	if_up(struct ifnet *);

Return to bug 252608