On 27/09/15(Sun) 15:51, David Gwynne wrote: > this uses the refcnt api to do the heavy lifting. > > i think we have all the if_get/if_put calls we need, so this should > be safe at this point. > > if anyone wants to test, can you try detaching or destroying > interfaces and check that the ifconfig call that does it doesnt end > up blocking forever?
The ifconfig call *or* the USB task thread. > ok? ok mpi@ > > Index: if.c > =================================================================== > RCS file: /cvs/src/sys/net/if.c,v > retrieving revision 1.380 > diff -u -p -r1.380 if.c > --- if.c 13 Sep 2015 18:15:03 -0000 1.380 > +++ if.c 27 Sep 2015 05:49:11 -0000 > @@ -279,11 +279,7 @@ if_idxmap_insert(struct ifnet *ifp) > struct srp *map; > unsigned int index, i; > > - /* > - * give the ifp an initial refcnt of 1 to ensure it will not > - * be freed until if_idxmap_remove returns. > - */ > - ifp->if_refcnt = 1; > + refcnt_init(&ifp->if_refcnt); > > /* the kernel lock guarantees serialised modifications to if_idxmap */ > KERNEL_ASSERT_LOCKED(); > @@ -345,7 +341,7 @@ if_idxmap_remove(struct ifnet *ifp) > { > struct if_map *if_map; > struct srp *map; > - unsigned int index, r; > + unsigned int index; > > index = ifp->if_index; > > @@ -362,10 +358,8 @@ if_idxmap_remove(struct ifnet *ifp) > if_idxmap.count--; > /* end of if_idxmap modifications */ > > - /* release the initial ifp refcnt */ > - r = atomic_dec_int_nv(&ifp->if_refcnt); > - if (r != 0) > - printf("%s: refcnt %u\n", ifp->if_xname, r); > + /* sleep until the last reference is released */ > + refcnt_finalize(&ifp->if_refcnt, "ifidxrm"); > } > > void > @@ -1554,7 +1544,7 @@ if_get(unsigned int index) > struct ifnet * > if_ref(struct ifnet *ifp) > { > - atomic_inc_int(&ifp->if_refcnt); > + refcnt_take(&ifp->if_refcnt); > > return (ifp); > } > @@ -1565,7 +1555,7 @@ if_put(struct ifnet *ifp) > if (ifp == NULL) > return; > > - atomic_dec_int(&ifp->if_refcnt); > + refcnt_rele_wake(&ifp->if_refcnt); > } > > /* > Index: if_var.h > =================================================================== > RCS file: /cvs/src/sys/net/if_var.h,v > retrieving revision 1.43 > diff -u -p -r1.43 if_var.h > --- if_var.h 13 Sep 2015 17:53:44 -0000 1.43 > +++ if_var.h 27 Sep 2015 05:49:11 -0000 > @@ -39,6 +39,7 @@ > #include <sys/queue.h> > #include <sys/mbuf.h> > #include <sys/srp.h> > +#include <sys/refcnt.h> > #ifdef _KERNEL > #include <net/hfsc.h> > #endif > @@ -119,7 +120,7 @@ TAILQ_HEAD(ifnet_head, ifnet); /* the a > > struct ifnet { /* and the entries */ > void *if_softc; /* lower-level data for this if */ > - unsigned int if_refcnt; > + struct refcnt if_refcnt; > TAILQ_ENTRY(ifnet) if_list; /* all struct ifnets are chained */ > TAILQ_ENTRY(ifnet) if_txlist; /* list of ifnets ready to tx */ > TAILQ_HEAD(, ifaddr) if_addrlist; /* linked list of addresses per if */ >