summaryrefslogtreecommitdiffstats
path: root/sys/netipsec/xform_ipcomp.c
diff options
context:
space:
mode:
authorfabient <fabient@FreeBSD.org>2011-03-31 15:23:32 +0000
committerfabient <fabient@FreeBSD.org>2011-03-31 15:23:32 +0000
commitd56170701edd485dd31c6c68254daab567f5d249 (patch)
tree67cb0da741da7bd58b8f2eaa65607147ebf7f0af /sys/netipsec/xform_ipcomp.c
parent3666785171ab6fafe3466579d69d661e79599f96 (diff)
downloadFreeBSD-src-d56170701edd485dd31c6c68254daab567f5d249.zip
FreeBSD-src-d56170701edd485dd31c6c68254daab567f5d249.tar.gz
Optimisation in IPSEC(4):
- Remove contention on ISR during the crypto operation by using rwlock(9). - Remove a second lookup of the SA in the callback. Gain on 6 cores CPU with SHA1/AES128 can be up to 30%. Reviewed by: vanhu MFC after: 1 month
Diffstat (limited to 'sys/netipsec/xform_ipcomp.c')
-rw-r--r--sys/netipsec/xform_ipcomp.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c
index d528d2a..5b2032a 100644
--- a/sys/netipsec/xform_ipcomp.c
+++ b/sys/netipsec/xform_ipcomp.c
@@ -37,6 +37,7 @@
#include <sys/mbuf.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/rwlock.h>
#include <sys/socket.h>
#include <sys/kernel.h>
#include <sys/protosw.h>
@@ -185,6 +186,8 @@ ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
tc->tc_proto = sav->sah->saidx.proto;
tc->tc_protoff = protoff;
tc->tc_skip = skip;
+ KEY_ADDREFSA(sav);
+ tc->tc_sav = sav;
return crypto_dispatch(crp);
}
@@ -228,13 +231,8 @@ ipcomp_input_cb(struct cryptop *crp)
mtag = (struct mtag *) tc->tc_ptr;
m = (struct mbuf *) crp->crp_buf;
- sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
- if (sav == NULL) {
- V_ipcompstat.ipcomps_notdb++;
- DPRINTF(("%s: SA expired while in crypto\n", __func__));
- error = ENOBUFS; /*XXX*/
- goto bad;
- }
+ sav = tc->tc_sav;
+ IPSEC_ASSERT(sav != NULL, ("null SA!"));
saidx = &sav->sah->saidx;
IPSEC_ASSERT(saidx->dst.sa.sa_family == AF_INET ||
@@ -248,7 +246,6 @@ ipcomp_input_cb(struct cryptop *crp)
sav->tdb_cryptoid = crp->crp_sid;
if (crp->crp_etype == EAGAIN) {
- KEY_FREESAV(&sav);
return crypto_dispatch(crp);
}
V_ipcompstat.ipcomps_noxform++;
@@ -431,6 +428,8 @@ ipcomp_output(
}
tc->tc_isr = isr;
+ KEY_ADDREFSA(sav);
+ tc->tc_sav = sav;
tc->tc_spi = sav->spi;
tc->tc_dst = sav->sah->saidx.dst;
tc->tc_proto = sav->sah->saidx.proto;
@@ -471,14 +470,14 @@ ipcomp_output_cb(struct cryptop *crp)
isr = tc->tc_isr;
IPSECREQUEST_LOCK(isr);
- sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
- if (sav == NULL) {
+ sav = tc->tc_sav;
+ /* With the isr lock released SA pointer can be updated. */
+ if (sav != isr->sav) {
V_ipcompstat.ipcomps_notdb++;
DPRINTF(("%s: SA expired while in crypto\n", __func__));
error = ENOBUFS; /*XXX*/
goto bad;
}
- IPSEC_ASSERT(isr->sav == sav, ("SA changed\n"));
/* Check for crypto errors */
if (crp->crp_etype) {
@@ -487,7 +486,6 @@ ipcomp_output_cb(struct cryptop *crp)
sav->tdb_cryptoid = crp->crp_sid;
if (crp->crp_etype == EAGAIN) {
- KEY_FREESAV(&sav);
IPSECREQUEST_UNLOCK(isr);
return crypto_dispatch(crp);
}
OpenPOWER on IntegriCloud