Module Name: src Committed By: ozaki-r Date: Tue May 30 01:31:07 UTC 2017
Modified Files: src/sys/netipsec: ipsec.c key.c key.h Log Message: Make refcnt operations of SA and SP atomic Using atomic opeartions isn't optimal and should be optimized somehow in the future though, the change allows a kernel with NET_MPSAFE to run out a benchmark, which is useful to know performance improvement and degradation by code changes. To generate a diff of this commit: cvs rdiff -u -r1.94 -r1.95 src/sys/netipsec/ipsec.c cvs rdiff -u -r1.147 -r1.148 src/sys/netipsec/key.c cvs rdiff -u -r1.18 -r1.19 src/sys/netipsec/key.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netipsec/ipsec.c diff -u src/sys/netipsec/ipsec.c:1.94 src/sys/netipsec/ipsec.c:1.95 --- src/sys/netipsec/ipsec.c:1.94 Tue May 23 09:08:45 2017 +++ src/sys/netipsec/ipsec.c Tue May 30 01:31:07 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ipsec.c,v 1.94 2017/05/23 09:08:45 ozaki-r Exp $ */ +/* $NetBSD: ipsec.c,v 1.95 2017/05/30 01:31:07 ozaki-r Exp $ */ /* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $ */ /* $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $ */ @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.94 2017/05/23 09:08:45 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.95 2017/05/30 01:31:07 ozaki-r Exp $"); /* * IPsec controller part. @@ -257,7 +257,7 @@ ipsec_checkpcbcache(struct mbuf *m, stru } pcbsp->sp_cache[dir].cachesp->lastused = time_second; - pcbsp->sp_cache[dir].cachesp->refcnt++; + KEY_SP_REF(pcbsp->sp_cache[dir].cachesp); KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, "DP cause refcnt++:%d SP:%p\n", pcbsp->sp_cache[dir].cachesp->refcnt, @@ -283,7 +283,7 @@ ipsec_fillpcbcache(struct inpcbpolicy *p } pcbsp->sp_cache[dir].cachesp = sp; if (pcbsp->sp_cache[dir].cachesp) { - pcbsp->sp_cache[dir].cachesp->refcnt++; + KEY_SP_REF(pcbsp->sp_cache[dir].cachesp); KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, "DP cause refcnt++:%d SP:%p\n", pcbsp->sp_cache[dir].cachesp->refcnt, @@ -393,7 +393,7 @@ key_allocsp_default(int af, const char * sp->policy, IPSEC_POLICY_NONE); sp->policy = IPSEC_POLICY_NONE; } - sp->refcnt++; + KEY_SP_REF(sp); KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, "DP returns SP:%p (%u)\n", sp, sp->refcnt); @@ -513,7 +513,7 @@ ipsec_getpolicybysock(struct mbuf *m, u_ switch (currsp->policy) { case IPSEC_POLICY_BYPASS: case IPSEC_POLICY_IPSEC: - currsp->refcnt++; + KEY_SP_REF(currsp); sp = currsp; break; @@ -546,7 +546,7 @@ ipsec_getpolicybysock(struct mbuf *m, u_ break; case IPSEC_POLICY_IPSEC: - currsp->refcnt++; + KEY_SP_REF(currsp); sp = currsp; break; Index: src/sys/netipsec/key.c diff -u src/sys/netipsec/key.c:1.147 src/sys/netipsec/key.c:1.148 --- src/sys/netipsec/key.c:1.147 Mon May 29 10:11:10 2017 +++ src/sys/netipsec/key.c Tue May 30 01:31:07 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: key.c,v 1.147 2017/05/29 10:11:10 ozaki-r Exp $ */ +/* $NetBSD: key.c,v 1.148 2017/05/30 01:31:07 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.147 2017/05/29 10:11:10 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.148 2017/05/30 01:31:07 ozaki-r Exp $"); /* * This code is referd to RFC 2367 @@ -550,44 +550,44 @@ static struct work key_timehandler_wk; #endif #define SA_ADDREF(p) do { \ - (p)->refcnt++; \ + atomic_inc_uint(&(p)->refcnt); \ REFLOG("SA_ADDREF", (p), __func__, __LINE__); \ KASSERTMSG((p)->refcnt != 0, "SA refcnt overflow"); \ } while (0) #define SA_ADDREF2(p, where, tag) do { \ - (p)->refcnt++; \ + atomic_inc_uint(&(p)->refcnt); \ REFLOG("SA_ADDREF", (p), (where), (tag)); \ KASSERTMSG((p)->refcnt != 0, "SA refcnt overflow"); \ } while (0) #define SA_DELREF(p) do { \ KASSERTMSG((p)->refcnt > 0, "SA refcnt underflow"); \ - (p)->refcnt--; \ + atomic_dec_uint(&(p)->refcnt); \ REFLOG("SA_DELREF", (p), __func__, __LINE__); \ } while (0) -#define SA_DELREF2(p, where, tag) do { \ +#define SA_DELREF2(p, nv, where, tag) do { \ KASSERTMSG((p)->refcnt > 0, "SA refcnt underflow"); \ - (p)->refcnt--; \ + nv = atomic_dec_uint_nv(&(p)->refcnt); \ REFLOG("SA_DELREF", (p), (where), (tag)); \ } while (0) #define SP_ADDREF(p) do { \ - (p)->refcnt++; \ + atomic_inc_uint(&(p)->refcnt); \ REFLOG("SP_ADDREF", (p), __func__, __LINE__); \ KASSERTMSG((p)->refcnt != 0, "SP refcnt overflow"); \ } while (0) #define SP_ADDREF2(p, where, tag) do { \ - (p)->refcnt++; \ + atomic_inc_uint(&(p)->refcnt); \ REFLOG("SP_ADDREF", (p), (where), (tag)); \ KASSERTMSG((p)->refcnt != 0, "SP refcnt overflow"); \ } while (0) #define SP_DELREF(p) do { \ KASSERTMSG((p)->refcnt > 0, "SP refcnt underflow"); \ - (p)->refcnt--; \ + atomic_dec_uint(&(p)->refcnt); \ REFLOG("SP_DELREF", (p), __func__, __LINE__); \ } while (0) -#define SP_DELREF2(p, where, tag) do { \ +#define SP_DELREF2(p, nv, where, tag) do { \ KASSERTMSG((p)->refcnt > 0, "SP refcnt underflow"); \ - (p)->refcnt--; \ + nv = atomic_dec_uint_nv(&(p)->refcnt); \ REFLOG("SP_DELREF", (p), (where), (tag)); \ } while (0) @@ -1238,6 +1238,17 @@ done: return sav; } +void +key_sp_ref(struct secpolicy *sp, const char* where, int tag) +{ + + SP_ADDREF2(sp, where, tag); + + KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, + "DP SP:%p (ID=%u) from %s:%u; refcnt now %u\n", + sp, sp->id, where, tag, sp->refcnt); +} + /* * Must be called after calling key_allocsp(). * For both the packet without socket and key_freeso(). @@ -1246,16 +1257,17 @@ void _key_freesp(struct secpolicy **spp, const char* where, int tag) { struct secpolicy *sp = *spp; + unsigned int nv; KASSERT(sp != NULL); - SP_DELREF2(sp, where, tag); + SP_DELREF2(sp, nv, where, tag); KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, "DP SP:%p (ID=%u) from %s:%u; refcnt now %u\n", - sp, sp->id, where, tag, sp->refcnt); + sp, sp->id, where, tag, nv); - if (sp->refcnt == 0) { + if (nv == 0) { *spp = NULL; key_delsp(sp); } @@ -1345,16 +1357,17 @@ void key_freesav(struct secasvar **psav, const char* where, int tag) { struct secasvar *sav = *psav; + unsigned int nv; KASSERT(sav != NULL); - SA_DELREF2(sav, where, tag); + SA_DELREF2(sav, nv, where, tag); KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, "DP SA:%p (SPI %lu) from %s:%u; refcnt now %u\n", - sav, (u_long)ntohl(sav->spi), where, tag, sav->refcnt); + sav, (u_long)ntohl(sav->spi), where, tag, nv); - if (sav->refcnt == 0) { + if (nv == 0) { *psav = NULL; key_delsav(sav); } Index: src/sys/netipsec/key.h diff -u src/sys/netipsec/key.h:1.18 src/sys/netipsec/key.h:1.19 --- src/sys/netipsec/key.h:1.18 Fri May 26 08:10:46 2017 +++ src/sys/netipsec/key.h Tue May 30 01:31:07 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: key.h,v 1.18 2017/05/26 08:10:46 ozaki-r Exp $ */ +/* $NetBSD: key.h,v 1.19 2017/05/30 01:31:07 ozaki-r Exp $ */ /* $FreeBSD: src/sys/netipsec/key.h,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */ /* $KAME: key.h,v 1.21 2001/07/27 03:51:30 itojun Exp $ */ @@ -58,6 +58,7 @@ struct secpolicy *key_gettunnel(const st const struct sockaddr *, const char*, int); /* NB: prepend with _ for KAME IPv6 compatbility */ void _key_freesp(struct secpolicy **, const char*, int); +void key_sp_ref(struct secpolicy *, const char*, int); /* * Access to the SADB are interlocked with splsoftnet. In particular, @@ -76,6 +77,8 @@ void _key_freesp(struct secpolicy **, co key_gettunnel(osrc, odst, isrc, idst, __func__, __LINE__) #define KEY_FREESP(spp) \ _key_freesp(spp, __func__, __LINE__) +#define KEY_SP_REF(sp) \ + key_sp_ref(sp, __func__, __LINE__) struct secasvar *key_allocsa(const union sockaddr_union *, u_int, u_int32_t, u_int16_t, u_int16_t, const char*, int);