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 <edumazet@google.com>
Link: https://patch.msgid.link/20260409145625.2306224-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Eric Dumazet
2026-04-09 14:56:20 +00:00
committed by Jakub Kicinski
parent 4431c239a3
commit 900f27fb79
9 changed files with 34 additions and 26 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}