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 */
>