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>

@@ -245,13 +246,13 @@
                 netstack_rele(ns);
                 return (-1);
         }
         ekp = (ah_kstats_t *)kp->ks_data;
 
-        mutex_enter(&ipss->ipsec_alg_lock);
+        rw_enter(&ipss->ipsec_alg_lock, RW_READER);
         ekp->ah_stat_num_aalgs.value.ui64 = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
-        mutex_exit(&ipss->ipsec_alg_lock);
+        rw_exit(&ipss->ipsec_alg_lock);
 
         netstack_rele(ns);
         return (0);
 }
 

@@ -571,11 +572,11 @@
          * Allocate the PF_KEY message that follows KEYSOCK_OUT.
          * The alg reader lock needs to be held while allocating
          * the variable part (i.e. the algorithms) of the message.
          */
 
-        mutex_enter(&ipss->ipsec_alg_lock);
+        rw_enter(&ipss->ipsec_alg_lock, RW_READER);
 
         /*
          * Return only valid algorithms, so the number of algorithms
          * to send up may be less than the number of algorithm entries
          * in the table.

@@ -593,11 +594,11 @@
                 allocsize += (num_aalgs * sizeof (*saalg));
                 allocsize += sizeof (*sasupp);
         }
         mp->b_cont = allocb(allocsize, BPRI_HI);
         if (mp->b_cont == NULL) {
-                mutex_exit(&ipss->ipsec_alg_lock);
+                rw_exit(&ipss->ipsec_alg_lock);
                 freemsg(mp);
                 return (B_FALSE);
         }
 
         mp->b_cont->b_wptr += allocsize;

@@ -640,11 +641,11 @@
                                     "ah_register_out()!  Missed #%d.\n", i);
 #endif /* DEBUG */
                 nextext = (sadb_ext_t *)saalg;
         }
 
-        mutex_exit(&ipss->ipsec_alg_lock);
+        rw_exit(&ipss->ipsec_alg_lock);
 
         if (sens_tsl != NULL) {
                 sens = (sadb_sens_t *)nextext;
                 sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY,
                     sens_tsl, sens_len);

@@ -1121,36 +1122,36 @@
          * if I did, I'd do them here, before I sent the weak key
          * check up to the algorithm.
          */
 
         /* verify that there is a mapping for the specified algorithm */
-        mutex_enter(&ipss->ipsec_alg_lock);
+        rw_enter(&ipss->ipsec_alg_lock, RW_READER);
         aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH][assoc->sadb_sa_auth];
         if (aalg == NULL || !ALG_VALID(aalg)) {
-                mutex_exit(&ipss->ipsec_alg_lock);
+                rw_exit(&ipss->ipsec_alg_lock);
                 ah1dbg(ahstack, ("Couldn't find auth alg #%d.\n",
                     assoc->sadb_sa_auth));
                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_AALG;
                 return (EINVAL);
         }
         ASSERT(aalg->alg_mech_type != CRYPTO_MECHANISM_INVALID);
 
         /* sanity check key sizes */
         if (!ipsec_valid_key_size(key->sadb_key_bits, aalg)) {
-                mutex_exit(&ipss->ipsec_alg_lock);
+                rw_exit(&ipss->ipsec_alg_lock);
                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_AKEYBITS;
                 return (EINVAL);
         }
 
         /* check key and fix parity if needed */
         if (ipsec_check_key(aalg->alg_mech_type, key, B_TRUE,
             diagnostic) != 0) {
-                mutex_exit(&ipss->ipsec_alg_lock);
+                rw_exit(&ipss->ipsec_alg_lock);
                 return (EINVAL);
         }
 
-        mutex_exit(&ipss->ipsec_alg_lock);
+        rw_exit(&ipss->ipsec_alg_lock);
 
         return (ah_add_sa_finish(mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
             diagnostic, ahstack));
 }
 

@@ -1747,11 +1748,11 @@
         ipsec_action_t *ap;
         ipsec_prot_t *prot;
         ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
         ipsec_stack_t   *ipss = ns->netstack_ipsec;
 
-        ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
+        ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
 
         prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
         prop->sadb_prop_len = SADB_8TO64(sizeof (sadb_prop_t));
         *(uint32_t *)(&prop->sadb_prop_replay) = 0;     /* Quick zero-out! */
 

@@ -1859,11 +1860,11 @@
         if (pfkeymp == NULL) {
                 ah0dbg(("sadb_setup_acquire failed.\n"));
                 mutex_exit(&acqrec->ipsacq_lock);
                 return;
         }
-        ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
+        ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
         combs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
         msgmp = pfkeymp->b_cont;
         samsg = (sadb_msg_t *)(msgmp->b_rptr);
 
         /* Insert proposal here. */

@@ -1871,11 +1872,11 @@
         prop = (sadb_prop_t *)(((uint64_t *)samsg) + samsg->sadb_msg_len);
         ah_insert_prop(prop, acqrec, combs, ns);
         samsg->sadb_msg_len += prop->sadb_prop_len;
         msgmp->b_wptr += SADB_64TO8(samsg->sadb_msg_len);
 
-        mutex_exit(&ipss->ipsec_alg_lock);
+        rw_exit(&ipss->ipsec_alg_lock);
 
         /*
          * Must mutex_exit() before sending PF_KEY message up, in
          * order to avoid recursive mutex_enter() if there are no registered
          * listeners.