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/f3214e087731
branches: trunk
changeset: 355626:f3214e087731
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 c12ea70a1943 -r f3214e087731 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