From: Eric Dumazet Date: Thu, 9 Apr 2026 14:56:20 +0000 (+0000) Subject: net: change sock_queue_rcv_skb_reason() to return a drop_reason X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=900f27fb797c7eaf0b84b7a6516613e19746bc4e;p=thirdparty%2Fkernel%2Flinux.git net: change sock_queue_rcv_skb_reason() to return a drop_reason Change sock_queue_rcv_skb_reason() to return the drop_reason directly instead of using a reference. This is part of an effort to remove stack canaries and reduce bloat. $ scripts/bloat-o-meter -t vmlinux.old vmlinux.new add/remove: 0/0 grow/shrink: 3/7 up/down: 79/-301 (-222) Function old new delta vsock_queue_rcv_skb 50 79 +29 ipmr_cache_report 1290 1315 +25 ip6mr_cache_report 1322 1347 +25 packet_rcv_spkt 329 327 -2 sock_queue_rcv_skb_reason 166 128 -38 raw_rcv_skb 122 80 -42 ping_queue_rcv_skb 109 61 -48 ping_rcv 215 162 -53 rawv6_rcv_skb 278 224 -54 raw_rcv 591 527 -64 Total: Before=29722890, After=29722668, chg -0.00% Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20260409145625.2306224-2-edumazet@google.com Signed-off-by: Jakub Kicinski --- diff --git a/include/net/sock.h b/include/net/sock.h index 7d51ac9e7d9a8..5831a4d1ebe77 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2502,12 +2502,23 @@ int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue, struct sk_buff *skb)); int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); -int sock_queue_rcv_skb_reason(struct sock *sk, struct sk_buff *skb, - enum skb_drop_reason *reason); +enum skb_drop_reason +sock_queue_rcv_skb_reason(struct sock *sk, struct sk_buff *skb); static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) { - return sock_queue_rcv_skb_reason(sk, skb, NULL); + enum skb_drop_reason drop_reason = sock_queue_rcv_skb_reason(sk, skb); + + switch (drop_reason) { + case SKB_DROP_REASON_SOCKET_RCVBUFF: + return -ENOMEM; + case SKB_DROP_REASON_PROTO_MEM: + return -ENOBUFS; + case 0: + return 0; + default: + return -EPERM; + } } int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb); diff --git a/net/can/bcm.c b/net/can/bcm.c index fd9fa072881e2..d6291381afb09 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -363,7 +363,6 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head, struct sockaddr_can *addr; struct sock *sk = op->sk; unsigned int datalen = head->nframes * op->cfsiz; - int err; unsigned int *pflags; enum skb_drop_reason reason; @@ -420,8 +419,8 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head, addr->can_family = AF_CAN; addr->can_ifindex = op->rx_ifindex; - err = sock_queue_rcv_skb_reason(sk, skb, &reason); - if (err < 0) { + reason = sock_queue_rcv_skb_reason(sk, skb); + if (reason) { struct bcm_sock *bo = bcm_sk(sk); sk_skb_reason_drop(sk, skb, reason); diff --git a/net/can/isotp.c b/net/can/isotp.c index 2770f43f49518..c48b4a818297e 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -291,7 +291,8 @@ static void isotp_rcv_skb(struct sk_buff *skb, struct sock *sk) addr->can_family = AF_CAN; addr->can_ifindex = skb->dev->ifindex; - if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) + reason = sock_queue_rcv_skb_reason(sk, skb); + if (reason) sk_skb_reason_drop(sk, skb, reason); } diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c index 0502b030d2385..50a598ef5fd4a 100644 --- a/net/can/j1939/socket.c +++ b/net/can/j1939/socket.c @@ -333,7 +333,8 @@ static void j1939_sk_recv_one(struct j1939_sock *jsk, struct sk_buff *oskb) if (skb->sk) skcb->msg_flags |= MSG_DONTROUTE; - if (sock_queue_rcv_skb_reason(&jsk->sk, skb, &reason) < 0) + reason = sock_queue_rcv_skb_reason(&jsk->sk, skb); + if (reason) sk_skb_reason_drop(&jsk->sk, skb, reason); } diff --git a/net/can/raw.c b/net/can/raw.c index eee244ffc31ec..56c95c768778a 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -207,7 +207,8 @@ static void raw_rcv(struct sk_buff *oskb, void *data) if (oskb->sk == sk) *pflags |= MSG_CONFIRM; - if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) + reason = sock_queue_rcv_skb_reason(sk, skb); + if (reason) sk_skb_reason_drop(sk, skb, reason); } diff --git a/net/core/sock.c b/net/core/sock.c index e821b95e00151..d39a4d6ccafd9 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -520,32 +520,24 @@ int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) } EXPORT_SYMBOL(__sock_queue_rcv_skb); -int sock_queue_rcv_skb_reason(struct sock *sk, struct sk_buff *skb, - enum skb_drop_reason *reason) +enum skb_drop_reason +sock_queue_rcv_skb_reason(struct sock *sk, struct sk_buff *skb) { enum skb_drop_reason drop_reason; int err; err = sk_filter_reason(sk, skb, &drop_reason); if (err) - goto out; + return drop_reason; err = __sock_queue_rcv_skb(sk, skb); switch (err) { case -ENOMEM: - drop_reason = SKB_DROP_REASON_SOCKET_RCVBUFF; - break; + return SKB_DROP_REASON_SOCKET_RCVBUFF; case -ENOBUFS: - drop_reason = SKB_DROP_REASON_PROTO_MEM; - break; - default: - drop_reason = SKB_NOT_DROPPED_YET; - break; + return SKB_DROP_REASON_PROTO_MEM; } -out: - if (reason) - *reason = drop_reason; - return err; + return SKB_NOT_DROPPED_YET; } EXPORT_SYMBOL(sock_queue_rcv_skb_reason); diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index bda245c808938..1273d1028ed9c 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -935,7 +935,8 @@ static enum skb_drop_reason __ping_queue_rcv_skb(struct sock *sk, pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n", inet_sk(sk), inet_sk(sk)->inet_num, skb); - if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) { + reason = sock_queue_rcv_skb_reason(sk, skb); + if (reason) { sk_skb_reason_drop(sk, skb, reason); pr_debug("ping_queue_rcv_skb -> failed\n"); return reason; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 34859e537b492..319428bf06bb8 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -300,7 +300,8 @@ static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb) /* Charge it to the socket. */ ipv4_pktinfo_prepare(sk, skb, true); - if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) { + reason = sock_queue_rcv_skb_reason(sk, skb); + if (reason) { sk_skb_reason_drop(sk, skb, reason); return NET_RX_DROP; } diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 0ac7046911000..3cc58698cbbd3 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -369,7 +369,8 @@ static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb) /* Charge it to the socket. */ skb_dst_drop(skb); - if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) { + reason = sock_queue_rcv_skb_reason(sk, skb); + if (reason) { sk_skb_reason_drop(sk, skb, reason); return NET_RX_DROP; }