aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
authorEric Dumazet <[email protected]>2025-03-20 12:16:04 +0000
committerJakub Kicinski <[email protected]>2025-03-25 14:37:16 +0000
commit0de2a5c4b824da2205658ebebb99a55c43cdf60f (patch)
tree35c86479d8dd4f78f78c63164a17f70fc9e72b3a /net/ipv4/tcp.c
parentMerge branch 'nexthop-convert-rtm_-new-del-nexthop-to-per-netns-rtnl' (diff)
downloadkernel-0de2a5c4b824da2205658ebebb99a55c43cdf60f.tar.gz
kernel-0de2a5c4b824da2205658ebebb99a55c43cdf60f.zip
tcp: avoid atomic operations on sk->sk_rmem_alloc
TCP uses generic skb_set_owner_r() and sock_rfree() for received packets, with socket lock being owned. Switch to private versions, avoiding two atomic operations per packet. Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: Neal Cardwell <[email protected]> Reviewed-by: Kuniyuki Iwashima <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 6edc441b3702..ea8de00f669d 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1525,11 +1525,25 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied)
__tcp_cleanup_rbuf(sk, copied);
}
+/* private version of sock_rfree() avoiding one atomic_sub() */
+void tcp_sock_rfree(struct sk_buff *skb)
+{
+ struct sock *sk = skb->sk;
+ unsigned int len = skb->truesize;
+
+ sock_owned_by_me(sk);
+ atomic_set(&sk->sk_rmem_alloc,
+ atomic_read(&sk->sk_rmem_alloc) - len);
+
+ sk_forward_alloc_add(sk, len);
+ sk_mem_reclaim(sk);
+}
+
static void tcp_eat_recv_skb(struct sock *sk, struct sk_buff *skb)
{
__skb_unlink(skb, &sk->sk_receive_queue);
- if (likely(skb->destructor == sock_rfree)) {
- sock_rfree(skb);
+ if (likely(skb->destructor == tcp_sock_rfree)) {
+ tcp_sock_rfree(skb);
skb->destructor = NULL;
skb->sk = NULL;
return skb_attempt_defer_free(skb);