Print this page
5045 use atomic_{inc,dec}_* instead of atomic_add_*


  83 #include <inet/ipdrop.h>
  84 #include <inet/ip_netinfo.h>
  85 #include <sys/squeue_impl.h>
  86 #include <sys/squeue.h>
  87 
  88 #include <inet/ipclassifier.h>
  89 #include <inet/sctp_ip.h>
  90 #include <inet/sctp/sctp_impl.h>
  91 #include <inet/udp_impl.h>
  92 #include <sys/sunddi.h>
  93 
  94 #include <sys/tsol/label.h>
  95 #include <sys/tsol/tnet.h>
  96 
  97 /*
  98  * Release a reference on ip_xmit_attr.
  99  * The reference is acquired by conn_get_ixa()
 100  */
 101 #define IXA_REFRELE(ixa)                                        \
 102 {                                                               \
 103         if (atomic_add_32_nv(&(ixa)->ixa_refcnt, -1) == 0)       \
 104                 ixa_inactive(ixa);                              \
 105 }
 106 
 107 #define IXA_REFHOLD(ixa)                                        \
 108 {                                                               \
 109         ASSERT((ixa)->ixa_refcnt != 0);                              \
 110         atomic_add_32(&(ixa)->ixa_refcnt, 1);                    \
 111 }
 112 
 113 /*
 114  * When we need to handle a transmit side asynchronous operation, then we need
 115  * to save sufficient information so that we can call the fragment and postfrag
 116  * functions. That information is captured in an mblk containing this structure.
 117  *
 118  * Since this is currently only used for IPsec, we include information for
 119  * the kernel crypto framework.
 120  */
 121 typedef struct ixamblk_s {
 122         boolean_t       ixm_inbound;    /* B_FALSE */
 123         iaflags_t       ixm_flags;      /* ixa_flags */
 124         netstackid_t    ixm_stackid;    /* Verify it didn't go away */
 125         uint_t          ixm_ifindex;    /* Used to find the nce */
 126         in6_addr_t      ixm_nceaddr_v6; /* Used to find nce */
 127 #define ixm_nceaddr_v4  V4_PART_OF_V6(ixm_nceaddr_v6)
 128         uint32_t        ixm_fragsize;
 129         uint_t          ixm_pktlen;
 130         uint16_t        ixm_ip_hdr_length; /* Points to ULP header */


 737 
 738         irm = (iramblk_t *)mp->b_rptr;
 739         ASSERT(irm->irm_inbound);
 740         return (B_TRUE);
 741 #else
 742         return (DB_TYPE(mp) == M_BREAK);
 743 #endif
 744 }
 745 
 746 static ip_xmit_attr_t *
 747 conn_get_ixa_impl(conn_t *connp, boolean_t replace, int kmflag)
 748 {
 749         ip_xmit_attr_t  *ixa;
 750         ip_xmit_attr_t  *oldixa;
 751 
 752         mutex_enter(&connp->conn_lock);
 753         ixa = connp->conn_ixa;
 754 
 755         /* At least one references for the conn_t */
 756         ASSERT(ixa->ixa_refcnt >= 1);
 757         if (atomic_add_32_nv(&ixa->ixa_refcnt, 1) == 2) {
 758                 /* No other thread using conn_ixa */
 759                 mutex_exit(&connp->conn_lock);
 760                 return (ixa);
 761         }
 762         ixa = kmem_alloc(sizeof (*ixa), kmflag);
 763         if (ixa == NULL) {
 764                 mutex_exit(&connp->conn_lock);
 765                 ixa_refrele(connp->conn_ixa);
 766                 return (NULL);
 767         }
 768         ixa_safe_copy(connp->conn_ixa, ixa);
 769 
 770         /* Make sure we drop conn_lock before any refrele */
 771         if (replace) {
 772                 ixa->ixa_refcnt++;   /* No atomic needed - not visible */
 773                 oldixa = connp->conn_ixa;
 774                 connp->conn_ixa = ixa;
 775                 mutex_exit(&connp->conn_lock);
 776                 IXA_REFRELE(oldixa);    /* Undo refcnt from conn_t */
 777         } else {


 839  * Return a ip_xmit_attr_t to use with a conn_t that is based on but
 840  * separate from conn_ixa.
 841  *
 842  * This "safe" copy has the pointers set to NULL
 843  * (since the pointers might be changed by another thread using
 844  * conn_ixa). The caller needs to check for NULL pointers to see
 845  * if ip_set_destination needs to be called to re-establish the pointers.
 846  */
 847 ip_xmit_attr_t *
 848 conn_get_ixa_exclusive(conn_t *connp)
 849 {
 850         ip_xmit_attr_t *ixa;
 851 
 852         mutex_enter(&connp->conn_lock);
 853         ixa = connp->conn_ixa;
 854 
 855         /* At least one references for the conn_t */
 856         ASSERT(ixa->ixa_refcnt >= 1);
 857 
 858         /* Make sure conn_ixa doesn't disappear while we copy it */
 859         atomic_add_32(&ixa->ixa_refcnt, 1);
 860 
 861         ixa = kmem_alloc(sizeof (*ixa), KM_NOSLEEP);
 862         if (ixa == NULL) {
 863                 mutex_exit(&connp->conn_lock);
 864                 ixa_refrele(connp->conn_ixa);
 865                 return (NULL);
 866         }
 867         ixa_safe_copy(connp->conn_ixa, ixa);
 868         mutex_exit(&connp->conn_lock);
 869         IXA_REFRELE(connp->conn_ixa);
 870         return (ixa);
 871 }
 872 
 873 void
 874 ixa_safe_copy(ip_xmit_attr_t *src, ip_xmit_attr_t *ixa)
 875 {
 876         bcopy(src, ixa, sizeof (*ixa));
 877         ixa->ixa_refcnt = 1;
 878         /*
 879          * Clear any pointers that have references and might be changed




  83 #include <inet/ipdrop.h>
  84 #include <inet/ip_netinfo.h>
  85 #include <sys/squeue_impl.h>
  86 #include <sys/squeue.h>
  87 
  88 #include <inet/ipclassifier.h>
  89 #include <inet/sctp_ip.h>
  90 #include <inet/sctp/sctp_impl.h>
  91 #include <inet/udp_impl.h>
  92 #include <sys/sunddi.h>
  93 
  94 #include <sys/tsol/label.h>
  95 #include <sys/tsol/tnet.h>
  96 
  97 /*
  98  * Release a reference on ip_xmit_attr.
  99  * The reference is acquired by conn_get_ixa()
 100  */
 101 #define IXA_REFRELE(ixa)                                        \
 102 {                                                               \
 103         if (atomic_dec_32_nv(&(ixa)->ixa_refcnt) == 0)   \
 104                 ixa_inactive(ixa);                              \
 105 }
 106 
 107 #define IXA_REFHOLD(ixa)                                        \
 108 {                                                               \
 109         ASSERT((ixa)->ixa_refcnt != 0);                              \
 110         atomic_inc_32(&(ixa)->ixa_refcnt);                       \
 111 }
 112 
 113 /*
 114  * When we need to handle a transmit side asynchronous operation, then we need
 115  * to save sufficient information so that we can call the fragment and postfrag
 116  * functions. That information is captured in an mblk containing this structure.
 117  *
 118  * Since this is currently only used for IPsec, we include information for
 119  * the kernel crypto framework.
 120  */
 121 typedef struct ixamblk_s {
 122         boolean_t       ixm_inbound;    /* B_FALSE */
 123         iaflags_t       ixm_flags;      /* ixa_flags */
 124         netstackid_t    ixm_stackid;    /* Verify it didn't go away */
 125         uint_t          ixm_ifindex;    /* Used to find the nce */
 126         in6_addr_t      ixm_nceaddr_v6; /* Used to find nce */
 127 #define ixm_nceaddr_v4  V4_PART_OF_V6(ixm_nceaddr_v6)
 128         uint32_t        ixm_fragsize;
 129         uint_t          ixm_pktlen;
 130         uint16_t        ixm_ip_hdr_length; /* Points to ULP header */


 737 
 738         irm = (iramblk_t *)mp->b_rptr;
 739         ASSERT(irm->irm_inbound);
 740         return (B_TRUE);
 741 #else
 742         return (DB_TYPE(mp) == M_BREAK);
 743 #endif
 744 }
 745 
 746 static ip_xmit_attr_t *
 747 conn_get_ixa_impl(conn_t *connp, boolean_t replace, int kmflag)
 748 {
 749         ip_xmit_attr_t  *ixa;
 750         ip_xmit_attr_t  *oldixa;
 751 
 752         mutex_enter(&connp->conn_lock);
 753         ixa = connp->conn_ixa;
 754 
 755         /* At least one references for the conn_t */
 756         ASSERT(ixa->ixa_refcnt >= 1);
 757         if (atomic_inc_32_nv(&ixa->ixa_refcnt) == 2) {
 758                 /* No other thread using conn_ixa */
 759                 mutex_exit(&connp->conn_lock);
 760                 return (ixa);
 761         }
 762         ixa = kmem_alloc(sizeof (*ixa), kmflag);
 763         if (ixa == NULL) {
 764                 mutex_exit(&connp->conn_lock);
 765                 ixa_refrele(connp->conn_ixa);
 766                 return (NULL);
 767         }
 768         ixa_safe_copy(connp->conn_ixa, ixa);
 769 
 770         /* Make sure we drop conn_lock before any refrele */
 771         if (replace) {
 772                 ixa->ixa_refcnt++;   /* No atomic needed - not visible */
 773                 oldixa = connp->conn_ixa;
 774                 connp->conn_ixa = ixa;
 775                 mutex_exit(&connp->conn_lock);
 776                 IXA_REFRELE(oldixa);    /* Undo refcnt from conn_t */
 777         } else {


 839  * Return a ip_xmit_attr_t to use with a conn_t that is based on but
 840  * separate from conn_ixa.
 841  *
 842  * This "safe" copy has the pointers set to NULL
 843  * (since the pointers might be changed by another thread using
 844  * conn_ixa). The caller needs to check for NULL pointers to see
 845  * if ip_set_destination needs to be called to re-establish the pointers.
 846  */
 847 ip_xmit_attr_t *
 848 conn_get_ixa_exclusive(conn_t *connp)
 849 {
 850         ip_xmit_attr_t *ixa;
 851 
 852         mutex_enter(&connp->conn_lock);
 853         ixa = connp->conn_ixa;
 854 
 855         /* At least one references for the conn_t */
 856         ASSERT(ixa->ixa_refcnt >= 1);
 857 
 858         /* Make sure conn_ixa doesn't disappear while we copy it */
 859         atomic_inc_32(&ixa->ixa_refcnt);
 860 
 861         ixa = kmem_alloc(sizeof (*ixa), KM_NOSLEEP);
 862         if (ixa == NULL) {
 863                 mutex_exit(&connp->conn_lock);
 864                 ixa_refrele(connp->conn_ixa);
 865                 return (NULL);
 866         }
 867         ixa_safe_copy(connp->conn_ixa, ixa);
 868         mutex_exit(&connp->conn_lock);
 869         IXA_REFRELE(connp->conn_ixa);
 870         return (ixa);
 871 }
 872 
 873 void
 874 ixa_safe_copy(ip_xmit_attr_t *src, ip_xmit_attr_t *ixa)
 875 {
 876         bcopy(src, ixa, sizeof (*ixa));
 877         ixa->ixa_refcnt = 1;
 878         /*
 879          * Clear any pointers that have references and might be changed