]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
xfrm: hold device only for the asynchronous decryption
authorJianbo Liu <jianbol@nvidia.com>
Thu, 19 Jun 2025 09:48:51 +0000 (12:48 +0300)
committerSteffen Klassert <steffen.klassert@secunet.com>
Fri, 20 Jun 2025 08:39:19 +0000 (10:39 +0200)
The dev_hold() on skb->dev during packet reception was originally
added to prevent the device from being released prematurely during
asynchronous decryption operations.

As current hardware can offload decryption, this asynchronous path is
not always utilized. This often results in a pattern of dev_hold()
immediately followed by dev_put() for each packet, creating
unnecessary reference counting overhead detrimental to performance.

This patch optimizes this by skipping the dev_hold() and subsequent
dev_put() when asynchronous decryption is not being performed.

Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
net/xfrm/xfrm_input.c

index 7e6a71b9d6a3ae2ff1a2742ca620729128823a06..c9ddef869aa557ba678eaa189d72a22b2d4db7e0 100644 (file)
@@ -503,6 +503,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
                /* An encap_type of -1 indicates async resumption. */
                if (encap_type == -1) {
                        async = 1;
+                       dev_put(skb->dev);
                        seq = XFRM_SKB_CB(skb)->seq.input.low;
                        goto resume;
                }
@@ -649,18 +650,18 @@ lock:
                XFRM_SKB_CB(skb)->seq.input.low = seq;
                XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
 
-               dev_hold(skb->dev);
-
-               if (crypto_done)
+               if (crypto_done) {
                        nexthdr = x->type_offload->input_tail(x, skb);
-               else
+               } else {
+                       dev_hold(skb->dev);
+
                        nexthdr = x->type->input(x, skb);
+                       if (nexthdr == -EINPROGRESS)
+                               return 0;
 
-               if (nexthdr == -EINPROGRESS)
-                       return 0;
+                       dev_put(skb->dev);
+               }
 resume:
-               dev_put(skb->dev);
-
                spin_lock(&x->lock);
                if (nexthdr < 0) {
                        if (nexthdr == -EBADMSG) {