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);

Reply via email to