summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2025-10-28 07:46:28 +0100
committerSteffen Klassert <steffen.klassert@secunet.com>2025-10-28 07:46:28 +0100
commit7197e080de3a1da3c9ec1455b7c8051245cf0214 (patch)
tree60a0a7d43dfe1774f13d2ddb8642b4d4c8eabc3d
parentbfe62db5422b1a5f25752bd0877a097d436d876d (diff)
parentb427c0c3bc40cca268a5d54a1cdf6166cb1360e2 (diff)
downloadlinux-7197e080de3a1da3c9ec1455b7c8051245cf0214.tar.gz
linux-7197e080de3a1da3c9ec1455b7c8051245cf0214.zip
Merge branch 'xfrm: IPsec hardware offload performance improvements'
Jianbo Liu says: ==================== This patch series optimizes IPsec crypto offload performance by addressing a lock contention bottleneck using RSS. The first patch refactors the xfrm_input to avoid a costly unlock/relock cycle. The second patch builds on this by removing a redundant replay check, which is unnecessary for the synchronous hardware path. ==================== Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r--net/xfrm/xfrm_input.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index c9ddef869aa5..4ed346e682c7 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -505,6 +505,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
async = 1;
dev_put(skb->dev);
seq = XFRM_SKB_CB(skb)->seq.input.low;
+ spin_lock(&x->lock);
goto resume;
}
/* GRO call */
@@ -541,9 +542,11 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
goto drop;
}
+
+ nexthdr = x->type_offload->input_tail(x, skb);
}
- goto lock;
+ goto process;
}
family = XFRM_SPI_SKB_CB(skb)->family;
@@ -611,7 +614,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
goto drop;
}
-lock:
+process:
+ seq_hi = htonl(xfrm_replay_seqhi(x, seq));
+
+ XFRM_SKB_CB(skb)->seq.input.low = seq;
+ XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
+
spin_lock(&x->lock);
if (unlikely(x->km.state != XFRM_STATE_VALID)) {
@@ -638,21 +646,13 @@ lock:
goto drop_unlock;
}
- spin_unlock(&x->lock);
-
if (xfrm_tunnel_check(skb, x, family)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR);
- goto drop;
+ goto drop_unlock;
}
- seq_hi = htonl(xfrm_replay_seqhi(x, seq));
-
- XFRM_SKB_CB(skb)->seq.input.low = seq;
- XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
-
- if (crypto_done) {
- nexthdr = x->type_offload->input_tail(x, skb);
- } else {
+ if (!crypto_done) {
+ spin_unlock(&x->lock);
dev_hold(skb->dev);
nexthdr = x->type->input(x, skb);
@@ -660,9 +660,9 @@ lock:
return 0;
dev_put(skb->dev);
+ spin_lock(&x->lock);
}
resume:
- spin_lock(&x->lock);
if (nexthdr < 0) {
if (nexthdr == -EBADMSG) {
xfrm_audit_state_icvfail(x, skb,
@@ -676,7 +676,7 @@ resume:
/* only the first xfrm gets the encap type */
encap_type = 0;
- if (xfrm_replay_recheck(x, skb, seq)) {
+ if (!crypto_done && xfrm_replay_recheck(x, skb, seq)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
goto drop_unlock;
}