Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netipsec Assemble global lists and related locks into ca...



details:   https://anonhg.NetBSD.org/src/rev/35295ffcccee
branches:  trunk
changeset: 825927:35295ffcccee
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Mon Aug 07 03:21:58 2017 +0000

description:
Assemble global lists and related locks into cache lines (NFCI)

Also rename variable names from *tree to *list because they are
just lists, not trees.

Suggested by riastradh@

diffstat:

 sys/netipsec/key.c   |  303 ++++++++++++++++++++++++++------------------------
 sys/netipsec/keydb.h |    4 +-
 2 files changed, 161 insertions(+), 146 deletions(-)

diffs (truncated from 788 to 300 lines):

diff -r 7a01d24529f6 -r 35295ffcccee sys/netipsec/key.c
--- a/sys/netipsec/key.c        Mon Aug 07 03:20:02 2017 +0000
+++ b/sys/netipsec/key.c        Mon Aug 07 03:21:58 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: key.c,v 1.207 2017/08/07 03:20:02 ozaki-r Exp $        */
+/*     $NetBSD: key.c,v 1.208 2017/08/07 03:21:58 ozaki-r Exp $        */
 /*     $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $        */
 /*     $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $   */
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.207 2017/08/07 03:20:02 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.208 2017/08/07 03:21:58 ozaki-r Exp $");
 
 /*
  * This code is referd to RFC 2367
@@ -137,17 +137,17 @@
 
 /*
  * Locking notes on SPD:
- * - Modifications to the sptree must be done with holding key_sp_mtx
+ * - Modifications to the key_spd.splist must be done with holding key_spd.lock
  *   which is a adaptive mutex
- * - Read accesses to the sptree must be in critical sections of pserialize(9)
+ * - Read accesses to the key_spd.splist must be in critical sections of pserialize(9)
  * - SP's lifetime is managed by localcount(9)
- * - An SP that has been inserted to the sptree is initially referenced by none,
- *   i.e., a reference from the pstree isn't counted
+ * - An SP that has been inserted to the key_spd.splist is initially referenced by none,
+ *   i.e., a reference from the key_spd.splist isn't counted
  * - When an SP is being destroyed, we change its state as DEAD, wait for
  *   references to the SP to be released, and then deallocate the SP
  *   (see key_unlink_sp)
  * - Getting an SP
- *   - Normally we get an SP from the sptree by incrementing the reference count
+ *   - Normally we get an SP from the key_spd.splist by incrementing the reference count
  *     of the SP
  *   - We can gain another reference from a held SP only if we check its state
  *     and take its reference in a critical section of pserialize
@@ -156,7 +156,7 @@
  * - Updating member variables of an SP
  *   - Most member variables of an SP are immutable
  *   - Only sp->state and sp->lastused can be changed
- *   - sp->state of an SP is updated only when destroying it under key_sp_mtx
+ *   - sp->state of an SP is updated only when destroying it under key_spd.lock
  * - SP caches
  *   - SPs can be cached in PCBs
  *   - The lifetime of the caches is controlled by the global generation counter
@@ -172,7 +172,7 @@
  *   - Userland programs can set a policy to a socket by
  *     setsockopt(IP_IPSEC_POLICY)
  *   - Such policies (SPs) are set to a socket (PCB) and also inserted to
- *     the key_socksplist list (not the sptree)
+ *     the key_spd.socksplist list (not the key_spd.splist)
  *   - Such a policy is destroyed when a corresponding socket is destroed,
  *     however, a socket can be destroyed in softint so we cannot destroy
  *     it directly instead we just mark it DEAD and delay the destruction
@@ -192,17 +192,42 @@
 
 static u_int32_t acq_seq = 0;
 
-static struct pslist_head sptree[IPSEC_DIR_MAX];               /* SPD */
-static struct pslist_head sahtree;                             /* SAD */
-static LIST_HEAD(_regtree, secreg) regtree[SADB_SATYPE_MAX + 1];
-                                                       /* registed list */
+static pserialize_t key_psz;
+
+/* SPD */
+static struct {
+       kmutex_t lock;
+       kcondvar_t cv;
+       struct pslist_head splist[IPSEC_DIR_MAX];
+       /*
+        * The list has SPs that are set to a socket via
+        * setsockopt(IP_IPSEC_POLICY) from userland. See ipsec_set_policy.
+        */
+       struct pslist_head socksplist;
+} key_spd __cacheline_aligned;
+
+/* SAD */
+static struct {
+       kmutex_t lock;
+       struct pslist_head sahlist;
+} key_sad __cacheline_aligned;
+
+/* Misc data */
+static struct {
+       kmutex_t lock;
+       /* registed list */
+       LIST_HEAD(_reglist, secreg) reglist[SADB_SATYPE_MAX + 1];
 #ifndef IPSEC_NONBLOCK_ACQUIRE
-static LIST_HEAD(_acqtree, secacq) acqtree;            /* acquiring list */
+       /* acquiring list */
+       LIST_HEAD(_acqlist, secacq) acqlist;
 #endif
 #ifdef notyet
-static LIST_HEAD(_spacqtree, secspacq) spacqtree;      /* SP acquiring list */
+       /* SP acquiring list */
+       LIST_HEAD(_spacqlist, secspacq) spacqlist;
 #endif
-
+} key_misc __cacheline_aligned;
+
+/* Macros for key_spd.splist */
 #define SPLIST_ENTRY_INIT(sp)                                          \
        PSLIST_ENTRY_INIT((sp), pslist_entry)
 #define SPLIST_ENTRY_DESTROY(sp)                                       \
@@ -210,21 +235,22 @@
 #define SPLIST_WRITER_REMOVE(sp)                                       \
        PSLIST_WRITER_REMOVE((sp), pslist_entry)
 #define SPLIST_READER_EMPTY(dir)                                       \
-       (PSLIST_READER_FIRST(&sptree[(dir)], struct secpolicy,          \
+       (PSLIST_READER_FIRST(&key_spd.splist[(dir)], struct secpolicy,  \
                             pslist_entry) == NULL)
 #define SPLIST_READER_FOREACH(sp, dir)                                 \
-       PSLIST_READER_FOREACH((sp), &sptree[(dir)], struct secpolicy,   \
-                             pslist_entry)
+       PSLIST_READER_FOREACH((sp), &key_spd.splist[(dir)],             \
+                             struct secpolicy, pslist_entry)
 #define SPLIST_WRITER_FOREACH(sp, dir)                                 \
-       PSLIST_WRITER_FOREACH((sp), &sptree[(dir)], struct secpolicy,   \
-                             pslist_entry)
+       PSLIST_WRITER_FOREACH((sp), &key_spd.splist[(dir)],             \
+                             struct secpolicy, pslist_entry)
 #define SPLIST_WRITER_INSERT_AFTER(sp, new)                            \
        PSLIST_WRITER_INSERT_AFTER((sp), (new), pslist_entry)
 #define SPLIST_WRITER_EMPTY(dir)                                       \
-       (PSLIST_WRITER_FIRST(&sptree[(dir)], struct secpolicy,          \
+       (PSLIST_WRITER_FIRST(&key_spd.splist[(dir)], struct secpolicy,  \
                             pslist_entry) == NULL)
 #define SPLIST_WRITER_INSERT_HEAD(dir, sp)                             \
-       PSLIST_WRITER_INSERT_HEAD(&sptree[(dir)], (sp), pslist_entry)
+       PSLIST_WRITER_INSERT_HEAD(&key_spd.splist[(dir)], (sp),         \
+                                 pslist_entry)
 #define SPLIST_WRITER_NEXT(sp)                                         \
        PSLIST_WRITER_NEXT((sp), struct secpolicy, pslist_entry)
 #define SPLIST_WRITER_INSERT_TAIL(dir, new)                            \
@@ -243,6 +269,15 @@
                }                                                       \
        } while (0)
 
+/* Macros for key_spd.socksplist */
+#define SOCKSPLIST_WRITER_FOREACH(sp)                                  \
+       PSLIST_WRITER_FOREACH((sp), &key_spd.socksplist,                \
+                             struct secpolicy, pslist_entry)
+#define SOCKSPLIST_READER_EMPTY()                                      \
+       (PSLIST_READER_FIRST(&key_spd.socksplist, struct secpolicy,     \
+                            pslist_entry) == NULL)
+
+/* Macros for key_sad.sahlist */
 #define SAHLIST_ENTRY_INIT(sah)                                                \
        PSLIST_ENTRY_INIT((sah), pslist_entry)
 #define SAHLIST_ENTRY_DESTROY(sah)                                     \
@@ -250,38 +285,39 @@
 #define SAHLIST_WRITER_REMOVE(sah)                                     \
        PSLIST_WRITER_REMOVE((sah), pslist_entry)
 #define SAHLIST_READER_FOREACH(sah)                                    \
-       PSLIST_READER_FOREACH((sah), &sahtree, struct secashead,        \
+       PSLIST_READER_FOREACH((sah), &key_sad.sahlist, struct secashead,\
                              pslist_entry)
 #define SAHLIST_WRITER_FOREACH(sah)                                    \
-       PSLIST_WRITER_FOREACH((sah), &sahtree, struct secashead,        \
+       PSLIST_WRITER_FOREACH((sah), &key_sad.sahlist, struct secashead,\
                              pslist_entry)
 #define SAHLIST_WRITER_INSERT_HEAD(sah)                                        \
-       PSLIST_WRITER_INSERT_HEAD(&sahtree, (sah), pslist_entry)
-
+       PSLIST_WRITER_INSERT_HEAD(&key_sad.sahlist, (sah), pslist_entry)
+
+/* Macros for key_sad.sahlist#savlist */
 #define SAVLIST_ENTRY_INIT(sav)                                                \
        PSLIST_ENTRY_INIT((sav), pslist_entry)
 #define SAVLIST_ENTRY_DESTROY(sav)                                     \
        PSLIST_ENTRY_DESTROY((sav), pslist_entry)
 #define SAVLIST_READER_FIRST(sah, state)                               \
-       PSLIST_READER_FIRST(&(sah)->savtree[(state)], struct secasvar,  \
+       PSLIST_READER_FIRST(&(sah)->savlist[(state)], struct secasvar,  \
                            pslist_entry)
 #define SAVLIST_WRITER_REMOVE(sav)                                     \
        PSLIST_WRITER_REMOVE((sav), pslist_entry)
 #define SAVLIST_READER_FOREACH(sav, sah, state)                                \
-       PSLIST_READER_FOREACH((sav), &(sah)->savtree[(state)],          \
+       PSLIST_READER_FOREACH((sav), &(sah)->savlist[(state)],          \
                              struct secasvar, pslist_entry)
 #define SAVLIST_WRITER_FOREACH(sav, sah, state)                                \
-       PSLIST_WRITER_FOREACH((sav), &(sah)->savtree[(state)],          \
+       PSLIST_WRITER_FOREACH((sav), &(sah)->savlist[(state)],          \
                              struct secasvar, pslist_entry)
 #define SAVLIST_WRITER_INSERT_BEFORE(sav, new)                         \
        PSLIST_WRITER_INSERT_BEFORE((sav), (new), pslist_entry)
 #define SAVLIST_WRITER_INSERT_AFTER(sav, new)                          \
        PSLIST_WRITER_INSERT_AFTER((sav), (new), pslist_entry)
 #define SAVLIST_WRITER_EMPTY(sah, state)                               \
-       (PSLIST_WRITER_FIRST(&(sah)->savtree[(state)], struct secasvar, \
+       (PSLIST_WRITER_FIRST(&(sah)->savlist[(state)], struct secasvar, \
                             pslist_entry) == NULL)
 #define SAVLIST_WRITER_INSERT_HEAD(sah, state, sav)                    \
-       PSLIST_WRITER_INSERT_HEAD(&(sah)->savtree[(state)], (sav),      \
+       PSLIST_WRITER_INSERT_HEAD(&(sah)->savlist[(state)], (sav),      \
                                  pslist_entry)
 #define SAVLIST_WRITER_NEXT(sav)                                       \
        PSLIST_WRITER_NEXT((sav), struct secasvar, pslist_entry)
@@ -303,27 +339,6 @@
 #define SAVLIST_READER_NEXT(sav)                                       \
        PSLIST_READER_NEXT((sav), struct secasvar, pslist_entry)
 
-/*
- * The list has SPs that are set to a socket via setsockopt(IP_IPSEC_POLICY)
- * from userland. See ipsec_set_policy.
- */
-static struct pslist_head key_socksplist;
-
-#define SOCKSPLIST_WRITER_FOREACH(sp)                                  \
-       PSLIST_WRITER_FOREACH((sp), &key_socksplist, struct secpolicy,  \
-                             pslist_entry)
-#define SOCKSPLIST_READER_EMPTY()                                      \
-       (PSLIST_READER_FIRST(&key_socksplist, struct secpolicy,         \
-                            pslist_entry) == NULL)
-
-/*
- * Protect regtree, acqtree and items stored in the lists.
- */
-static kmutex_t key_mtx __cacheline_aligned;
-static pserialize_t key_psz;
-static kmutex_t key_sp_mtx __cacheline_aligned;
-static kcondvar_t key_sp_cv __cacheline_aligned;
-static kmutex_t key_sa_mtx __cacheline_aligned;
 
 /* search order for SAs */
        /*
@@ -757,14 +772,14 @@
 }
 
 /*
- * Remove the sp from the sptree and wait for references to the sp
- * to be released. key_sp_mtx must be held.
+ * Remove the sp from the key_spd.splist and wait for references to the sp
+ * to be released. key_spd.lock must be held.
  */
 static void
 key_unlink_sp(struct secpolicy *sp)
 {
 
-       KASSERT(mutex_owned(&key_sp_mtx));
+       KASSERT(mutex_owned(&key_spd.lock));
 
        sp->state = IPSEC_SPSTATE_DEAD;
        SPLIST_WRITER_REMOVE(sp);
@@ -777,7 +792,7 @@
        pserialize_perform(key_psz);
 #endif
 
-       localcount_drain(&sp->localcount, &key_sp_cv, &key_sp_mtx);
+       localcount_drain(&sp->localcount, &key_spd.cv, &key_spd.lock);
 }
 
 /*
@@ -1297,13 +1312,13 @@
 key_sp_unref(struct secpolicy *sp, const char* where, int tag)
 {
 
-       KDASSERT(mutex_ownable(&key_sp_mtx));
+       KDASSERT(mutex_ownable(&key_spd.lock));
 
        KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP,
            "DP SP:%p (ID=%u) from %s:%u; refcnt-- now %u\n",
            sp, sp->id, where, tag, key_sp_refcnt(sp));
 
-       localcount_release(&sp->localcount, &key_sp_cv, &key_sp_mtx);
+       localcount_release(&sp->localcount, &key_spd.cv, &key_spd.lock);
 }
 
 void
@@ -1455,9 +1470,9 @@
 key_socksplist_add(struct secpolicy *sp)
 {
 
-       mutex_enter(&key_sp_mtx);
-       PSLIST_WRITER_INSERT_HEAD(&key_socksplist, sp, pslist_entry);
-       mutex_exit(&key_sp_mtx);
+       mutex_enter(&key_spd.lock);
+       PSLIST_WRITER_INSERT_HEAD(&key_spd.socksplist, sp, pslist_entry);
+       mutex_exit(&key_spd.lock);
 
        key_update_used();
 }
@@ -1500,7 +1515,7 @@
 {
        struct secpolicy *sp = NULL;
 
-       mutex_enter(&key_sp_mtx);
+       mutex_enter(&key_spd.lock);
        SPLIST_WRITER_FOREACH(sp, spidx->dir) {
                KASSERT(sp->state != IPSEC_SPSTATE_DEAD);
 
@@ -1511,7 +1526,7 @@
        }
        sp = NULL;



Home | Main Index | Thread Index | Old Index