Print this page
8381 Convert ipsec_alg_lock from mutex to rwlock

@@ -19,10 +19,11 @@
  * CDDL HEADER END
  */
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
  */
 
 #include <sys/types.h>
 #include <sys/stream.h>
 #include <sys/stropts.h>

@@ -3196,11 +3197,11 @@
                  */
                 newbie->ipsa_kcfauthkey.ck_format = CRYPTO_KEY_RAW;
                 newbie->ipsa_kcfauthkey.ck_length = newbie->ipsa_authkeybits;
                 newbie->ipsa_kcfauthkey.ck_data = newbie->ipsa_authkey;
 
-                mutex_enter(&ipss->ipsec_alg_lock);
+                rw_enter(&ipss->ipsec_alg_lock, RW_READER);
                 alg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
                     [newbie->ipsa_auth_alg];
                 if (alg != NULL && ALG_VALID(alg)) {
                         newbie->ipsa_amech.cm_type = alg->alg_mech_type;
                         newbie->ipsa_amech.cm_param =

@@ -3209,11 +3210,11 @@
                         newbie->ipsa_mac_len = (size_t)alg->alg_datalen;
                 } else {
                         newbie->ipsa_amech.cm_type = CRYPTO_MECHANISM_INVALID;
                 }
                 error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_AUTH);
-                mutex_exit(&ipss->ipsec_alg_lock);
+                rw_exit(&ipss->ipsec_alg_lock);
                 if (error != 0) {
                         mutex_exit(&newbie->ipsa_lock);
                         /*
                          * An error here indicates that alg is the wrong type
                          * (IE: not authentication) or its not in the alg tables

@@ -3226,11 +3227,11 @@
                         goto error;
                 }
         }
 
         if (ekey != NULL) {
-                mutex_enter(&ipss->ipsec_alg_lock);
+                rw_enter(&ipss->ipsec_alg_lock, RW_READER);
                 async = async || (ipss->ipsec_algs_exec_mode[IPSEC_ALG_ENCR] ==
                     IPSEC_ALGS_EXEC_ASYNC);
                 alg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
                     [newbie->ipsa_encr_alg];
 

@@ -3259,11 +3260,11 @@
                         newbie->ipsa_emech.cm_param = NULL;
                         newbie->ipsa_emech.cm_param_len = 0;
                 } else {
                         newbie->ipsa_emech.cm_type = CRYPTO_MECHANISM_INVALID;
                 }
-                mutex_exit(&ipss->ipsec_alg_lock);
+                rw_exit(&ipss->ipsec_alg_lock);
 
                 /*
                  * The byte stream following the sadb_key_t is made up of:
                  * key bytes, [salt bytes], [IV initial value]
                  * All of these have variable length. The IV is typically

@@ -3371,13 +3372,13 @@
                  */
                 newbie->ipsa_kcfencrkey.ck_format = CRYPTO_KEY_RAW;
                 newbie->ipsa_kcfencrkey.ck_length = newbie->ipsa_encrkeybits;
                 newbie->ipsa_kcfencrkey.ck_data = newbie->ipsa_encrkey;
 
-                mutex_enter(&ipss->ipsec_alg_lock);
+                rw_enter(&ipss->ipsec_alg_lock, RW_READER);
                 error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_ENCR);
-                mutex_exit(&ipss->ipsec_alg_lock);
+                rw_exit(&ipss->ipsec_alg_lock);
                 if (error != 0) {
                         mutex_exit(&newbie->ipsa_lock);
                         /* See above for error explanation. */
                         *diagnostic = SADB_X_DIAGNOSTIC_BAD_CTX;
                         goto error;

@@ -5279,22 +5280,22 @@
         /*
          * Normalize vs. crypto framework's limits.  This way, you can specify
          * a stronger policy, and when the framework loads a stronger version,
          * you can just keep plowing w/o rewhacking your SPD.
          */
-        mutex_enter(&ipss->ipsec_alg_lock);
+        rw_enter(&ipss->ipsec_alg_lock, RW_READER);
         algp = ipss->ipsec_alglists[(algtype == SADB_X_ALGTYPE_AUTH) ?
             IPSEC_ALG_AUTH : IPSEC_ALG_ENCR][alg];
         if (algp == NULL) {
-                mutex_exit(&ipss->ipsec_alg_lock);
+                rw_exit(&ipss->ipsec_alg_lock);
                 return (NULL);  /* Algorithm doesn't exist.  Fail gracefully. */
         }
         if (minbits < algp->alg_ef_minbits)
                 minbits = algp->alg_ef_minbits;
         if (maxbits > algp->alg_ef_maxbits)
                 maxbits = algp->alg_ef_maxbits;
-        mutex_exit(&ipss->ipsec_alg_lock);
+        rw_exit(&ipss->ipsec_alg_lock);
 
         algdesc->sadb_x_algdesc_reserved = SADB_8TO1(algp->alg_saltlen);
         algdesc->sadb_x_algdesc_satype = satype;
         algdesc->sadb_x_algdesc_algtype = algtype;
         algdesc->sadb_x_algdesc_alg = alg;

@@ -5772,11 +5773,11 @@
             sizeof (sadb_address_t) + sizeof (sadb_prop_t);
 
         /* Make sure there's enough to cover both AF_INET and AF_INET6. */
         allocsize += 2 * sizeof (struct sockaddr_in6);
 
-        mutex_enter(&ipss->ipsec_alg_lock);
+        rw_enter(&ipss->ipsec_alg_lock, RW_READER);
         /* NOTE:  The lock is now held through to this function's return. */
         allocsize += ipss->ipsec_nalgs[IPSEC_ALG_AUTH] *
             ipss->ipsec_nalgs[IPSEC_ALG_ENCR] * sizeof (sadb_comb_t);
 
         if (tunnel_mode) {

@@ -5787,11 +5788,11 @@
         }
 
         msgmp = allocb(allocsize, BPRI_HI);
         if (msgmp == NULL) {
                 freeb(pfkeymp);
-                mutex_exit(&ipss->ipsec_alg_lock);
+                rw_exit(&ipss->ipsec_alg_lock);
                 return (NULL);
         }
 
         pfkeymp->b_cont = msgmp;
         cur = msgmp->b_rptr;

@@ -5810,11 +5811,11 @@
         default:
                 /* This should never happen unless we have kernel bugs. */
                 cmn_err(CE_WARN,
                     "sadb_setup_acquire:  corrupt ACQUIRE record.\n");
                 ASSERT(0);
-                mutex_exit(&ipss->ipsec_alg_lock);
+                rw_exit(&ipss->ipsec_alg_lock);
                 return (NULL);
         }
 
         samsg->sadb_msg_version = PF_KEY_V2;
         samsg->sadb_msg_type = SADB_ACQUIRE;

@@ -5857,11 +5858,11 @@
         /* XXXMLS Insert sensitivity information here. */
 
         if (cur != NULL)
                 samsg->sadb_msg_len = SADB_8TO64(cur - msgmp->b_rptr);
         else
-                mutex_exit(&ipss->ipsec_alg_lock);
+                rw_exit(&ipss->ipsec_alg_lock);
 
         return (pfkeymp);
 }
 
 /*

@@ -7188,11 +7189,11 @@
         crypto_key_t *key;
         crypto_ctx_template_t *sa_tmpl;
         int rv;
         ipsec_stack_t   *ipss = sa->ipsa_netstack->netstack_ipsec;
 
-        ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
+        ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
         ASSERT(MUTEX_HELD(&sa->ipsa_lock));
 
         /* get pointers to the algorithm info, context template, and key */
         switch (alg_type) {
         case IPSEC_ALG_AUTH: