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

Reply via email to