summaryrefslogtreecommitdiffstats
path: root/sys/netipsec/xform_ah.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_ah.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_ah.c')
-rw-r--r--sys/netipsec/xform_ah.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c
index 6a2d351..726e025 100644
--- a/sys/netipsec/xform_ah.c
+++ b/sys/netipsec/xform_ah.c
@@ -715,6 +715,8 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
tc->tc_protoff = protoff;
tc->tc_skip = skip;
tc->tc_ptr = (caddr_t) mtag; /* Save the mtag we've identified. */
+ KEY_ADDREFSA(sav);
+ tc->tc_sav = sav;
if (mtag == NULL)
return crypto_dispatch(crp);
@@ -764,13 +766,8 @@ ah_input_cb(struct cryptop *crp)
mtag = (struct m_tag *) 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_ahstat.ahs_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 ||
@@ -785,7 +782,6 @@ ah_input_cb(struct cryptop *crp)
sav->tdb_cryptoid = crp->crp_sid;
if (crp->crp_etype == EAGAIN) {
- KEY_FREESAV(&sav);
error = crypto_dispatch(crp);
return error;
}
@@ -1111,6 +1107,8 @@ ah_output(
/* These are passed as-is to the callback. */
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;
@@ -1147,14 +1145,14 @@ ah_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_ahstat.ahs_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) {
@@ -1162,7 +1160,6 @@ ah_output_cb(struct cryptop *crp)
sav->tdb_cryptoid = crp->crp_sid;
if (crp->crp_etype == EAGAIN) {
- KEY_FREESAV(&sav);
IPSECREQUEST_UNLOCK(isr);
error = crypto_dispatch(crp);
return error;
OpenPOWER on IntegriCloud