Source-Changes-HG archive

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

[src/trunk]: src/sys/netipsec MP-ify SAD slightly



details:   https://anonhg.NetBSD.org/src/rev/b44a35dd2e82
branches:  trunk
changeset: 355565:b44a35dd2e82
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Thu Aug 03 06:31:58 2017 +0000

description:
MP-ify SAD slightly

- Introduce key_sa_mtx and use it for some list operations
- Use pserialize for some list iterations

diffstat:

 sys/netipsec/key.c |  93 +++++++++++++++++++++++++++++++++--------------------
 1 files changed, 58 insertions(+), 35 deletions(-)

diffs (truncated from 329 to 300 lines):

diff -r 3edbecec014c -r b44a35dd2e82 sys/netipsec/key.c
--- a/sys/netipsec/key.c        Thu Aug 03 06:31:16 2017 +0000
+++ b/sys/netipsec/key.c        Thu Aug 03 06:31:58 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: key.c,v 1.204 2017/08/03 06:31:16 ozaki-r Exp $        */
+/*     $NetBSD: key.c,v 1.205 2017/08/03 06:31: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.204 2017/08/03 06:31:16 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.205 2017/08/03 06:31:58 ozaki-r Exp $");
 
 /*
  * This code is referd to RFC 2367
@@ -323,6 +323,7 @@
 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 */
        /*
@@ -986,14 +987,16 @@
 key_lookup_sa_bysaidx(const struct secasindex *saidx)
 {
        struct secashead *sah;
-       struct secasvar *sav;
+       struct secasvar *sav = NULL;
        u_int stateidx, state;
        const u_int *saorder_state_valid;
        int arraysize;
-
+       int s;
+
+       s = pserialize_read_enter();
        sah = key_getsah(saidx, CMP_MODE_REQID);
        if (sah == NULL)
-               return NULL;
+               goto out;
 
        /*
         * search a valid state list for outbound packet.
@@ -1029,11 +1032,13 @@
                        KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP,
                            "DP cause refcnt++:%d SA:%p\n",
                            sav->refcnt, sav);
-                       return sav;
-               }
-       }
-
-       return NULL;
+                       break;
+               }
+       }
+out:
+       pserialize_read_exit(s);
+
+       return sav;
 }
 
 #if 0
@@ -1166,7 +1171,6 @@
         * IPsec tunnel packet is received.  But ESP tunnel mode is
         * encrypted so we can't check internal IP header.
         */
-       s = splsoftnet();       /*called from softclock()*/
        if (key_prefered_oldsa) {
                saorder_state_valid = saorder_state_valid_prefer_old;
                arraysize = _ARRAYLEN(saorder_state_valid_prefer_old);
@@ -1174,6 +1178,7 @@
                saorder_state_valid = saorder_state_valid_prefer_new;
                arraysize = _ARRAYLEN(saorder_state_valid_prefer_new);
        }
+       s = pserialize_read_enter();
        SAHLIST_READER_FOREACH(sah) {
                /* search valid state */
                for (stateidx = 0; stateidx < arraysize; stateidx++) {
@@ -1229,7 +1234,7 @@
        }
        sav = NULL;
 done:
-       splx(s);
+       pserialize_read_exit(s);
 
        KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP,
            "DP return SA:%p; refcnt %u\n", sav, sav ? sav->refcnt : 0);
@@ -1241,11 +1246,13 @@
 {
 #ifdef DEBUG
        struct secasvar *sav, *next;
+       int s;
 
        /*
         * The list should be sorted by lft_c->sadb_lifetime_addtime
         * in ascending order.
         */
+       s = pserialize_read_enter();
        SAVLIST_READER_FOREACH(sav, sah, state) {
                next = SAVLIST_READER_NEXT(sav);
                if (next != NULL &&
@@ -1258,6 +1265,7 @@
                            next->lft_c->sadb_lifetime_addtime);
                }
        }
+       pserialize_read_exit(s);
 #endif
 }
 
@@ -2915,7 +2923,9 @@
        /* add to saidxtree */
        newsah->state = SADB_SASTATE_MATURE;
        SAHLIST_ENTRY_INIT(newsah);
+       mutex_enter(&key_sa_mtx);
        SAHLIST_WRITER_INSERT_HEAD(newsah);
+       mutex_exit(&key_sa_mtx);
 
        return newsah;
 }
@@ -3154,10 +3164,12 @@
 static struct secasvar *
 key_getsavbyspi(struct secashead *sah, u_int32_t spi)
 {
-       struct secasvar *sav;
+       struct secasvar *sav = NULL;
        u_int state;
+       int s;
 
        /* search all status */
+       s = pserialize_read_enter();
        SASTATE_ALIVE_FOREACH(state) {
                SAVLIST_READER_FOREACH(sav, sah, state) {
                        /* sanity check */
@@ -3170,12 +3182,14 @@
 
                        if (sav->spi == spi) {
                                SA_ADDREF(sav);
-                               return sav;
+                               goto out;
                        }
                }
        }
-
-       return NULL;
+out:
+       pserialize_read_exit(s);
+
+       return sav;
 }
 
 /*
@@ -4962,7 +4976,9 @@
        newsav->sah = sah;
        newsav->state = SADB_SASTATE_LARVAL;
        SAVLIST_ENTRY_INIT(newsav);
+       mutex_enter(&key_sa_mtx);
        SAVLIST_WRITER_INSERT_TAIL(sah, SADB_SASTATE_LARVAL, newsav);
+       mutex_exit(&key_sa_mtx);
        key_validate_savlist(sah, SADB_SASTATE_LARVAL);
 
 #ifndef IPSEC_NONBLOCK_ACQUIRE
@@ -5440,10 +5456,12 @@
 {
        struct secasvar *sav;
        u_int state;
+       int s;
 
        state = SADB_SASTATE_LARVAL;
 
        /* search SAD with sequence number ? */
+       s = pserialize_read_enter();
        SAVLIST_READER_FOREACH(sav, sah, state) {
                KEY_CHKSASTATE(state, sav->state);
 
@@ -5452,11 +5470,12 @@
                        KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP,
                            "DP cause refcnt++:%d SA:%p\n",
                            sav->refcnt, sav);
-                       return sav;
-               }
-       }
-
-       return NULL;
+                       break;
+               }
+       }
+       pserialize_read_exit(s);
+
+       return sav;
 }
 #endif
 
@@ -7047,6 +7066,8 @@
        int cnt;
        struct mbuf *m, *n, *prev;
 
+       KASSERT(mutex_owned(&key_sa_mtx));
+
        *lenp = 0;
 
        /* map satype to proto */
@@ -7058,13 +7079,13 @@
 
        /* count sav entries to be sent to userland. */
        cnt = 0;
-       SAHLIST_READER_FOREACH(sah) {
+       SAHLIST_WRITER_FOREACH(sah) {
                if (req_satype != SADB_SATYPE_UNSPEC &&
                    proto != sah->saidx.proto)
                        continue;
 
                SASTATE_ANY_FOREACH(state) {
-                       SAVLIST_READER_FOREACH(sav, sah, state) {
+                       SAVLIST_WRITER_FOREACH(sav, sah, state) {
                                cnt++;
                        }
                }
@@ -7078,7 +7099,7 @@
        /* send this to the userland, one at a time. */
        m = NULL;
        prev = m;
-       SAHLIST_READER_FOREACH(sah) {
+       SAHLIST_WRITER_FOREACH(sah) {
                if (req_satype != SADB_SATYPE_UNSPEC &&
                    proto != sah->saidx.proto)
                        continue;
@@ -7092,7 +7113,7 @@
                }
 
                SASTATE_ANY_FOREACH(state) {
-                       SAVLIST_READER_FOREACH(sav, sah, state) {
+                       SAVLIST_WRITER_FOREACH(sav, sah, state) {
                                n = key_setdumpsa(sav, SADB_DUMP, satype,
                                    --cnt, pid);
                                if (!n) {
@@ -7144,7 +7165,6 @@
        u_int16_t proto;
        u_int8_t satype;
        struct mbuf *n;
-       int s;
        int error, len, ok;
 
        /* map satype to proto */
@@ -7166,9 +7186,9 @@
                return key_senderror(so, m0, ENOBUFS);
        }
 
-       s = splsoftnet();
+       mutex_enter(&key_sa_mtx);
        n = key_setdump_chain(satype, &error, &len, mhp->msg->sadb_msg_pid);
-       splx(s);
+       mutex_exit(&key_sa_mtx);
 
        if (n == NULL) {
                return key_senderror(so, m0, ENOENT);
@@ -7727,6 +7747,7 @@
        key_psz = pserialize_create();
        mutex_init(&key_sp_mtx, MUTEX_DEFAULT, IPL_NONE);
        cv_init(&key_sp_cv, "key_sp");
+       mutex_init(&key_sa_mtx, MUTEX_DEFAULT, IPL_NONE);
 
        pfkeystat_percpu = percpu_alloc(sizeof(uint64_t) * PFKEY_NSTATS);
 
@@ -8021,6 +8042,8 @@
        int cnt;
        struct mbuf *m, *n;
 
+       KASSERT(mutex_owned(&key_sa_mtx));
+
        /* map satype to proto */
        proto = key_satype2proto(req_satype);
        if (proto == 0) {
@@ -8030,13 +8053,13 @@
 
        /* count sav entries to be sent to the userland. */
        cnt = 0;
-       SAHLIST_READER_FOREACH(sah) {
+       SAHLIST_WRITER_FOREACH(sah) {
                if (req_satype != SADB_SATYPE_UNSPEC &&
                    proto != sah->saidx.proto)
                        continue;
 
                SASTATE_ANY_FOREACH(state) {
-                       SAVLIST_READER_FOREACH(sav, sah, state) {
+                       SAVLIST_WRITER_FOREACH(sav, sah, state) {
                                cnt++;
                        }
                }
@@ -8049,7 +8072,7 @@
 
        /* send this to the userland, one at a time. */
        m = NULL;
-       SAHLIST_READER_FOREACH(sah) {
+       SAHLIST_WRITER_FOREACH(sah) {
                if (req_satype != SADB_SATYPE_UNSPEC &&
                    proto != sah->saidx.proto)
                        continue;



Home | Main Index | Thread Index | Old Index