Commit 0fd7bac6 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

net: relax rcvbuf limits

skb->truesize might be big even for a small packet.

Its even bigger after commit 87fb4b7b (net: more accurate skb
truesize) and big MTU.

We should allow queueing at least one packet per receiver, even with a
low RCVBUF setting.
Reported-by: default avatarMichal Simek <monstr@monstr.eu>
Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a0a129f8
...@@ -637,12 +637,14 @@ static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb) ...@@ -637,12 +637,14 @@ static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)
/* /*
* Take into account size of receive queue and backlog queue * Take into account size of receive queue and backlog queue
* Do not take into account this skb truesize,
* to allow even a single big packet to come.
*/ */
static inline bool sk_rcvqueues_full(const struct sock *sk, const struct sk_buff *skb) static inline bool sk_rcvqueues_full(const struct sock *sk, const struct sk_buff *skb)
{ {
unsigned int qsize = sk->sk_backlog.len + atomic_read(&sk->sk_rmem_alloc); unsigned int qsize = sk->sk_backlog.len + atomic_read(&sk->sk_rmem_alloc);
return qsize + skb->truesize > sk->sk_rcvbuf; return qsize > sk->sk_rcvbuf;
} }
/* The per-socket spinlock must be held here. */ /* The per-socket spinlock must be held here. */
......
...@@ -288,11 +288,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -288,11 +288,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
unsigned long flags; unsigned long flags;
struct sk_buff_head *list = &sk->sk_receive_queue; struct sk_buff_head *list = &sk->sk_receive_queue;
/* Cast sk->rcvbuf to unsigned... It's pointless, but reduces if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) {
number of warnings when compiling with -W --ANK
*/
if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
(unsigned)sk->sk_rcvbuf) {
atomic_inc(&sk->sk_drops); atomic_inc(&sk->sk_drops);
trace_sock_rcvqueue_full(sk, skb); trace_sock_rcvqueue_full(sk, skb);
return -ENOMEM; return -ENOMEM;
......
...@@ -1630,8 +1630,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -1630,8 +1630,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
if (snaplen > res) if (snaplen > res)
snaplen = res; snaplen = res;
if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
(unsigned)sk->sk_rcvbuf)
goto drop_n_acct; goto drop_n_acct;
if (skb_shared(skb)) { if (skb_shared(skb)) {
...@@ -1762,8 +1761,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -1762,8 +1761,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
if (po->tp_version <= TPACKET_V2) { if (po->tp_version <= TPACKET_V2) {
if (macoff + snaplen > po->rx_ring.frame_size) { if (macoff + snaplen > po->rx_ring.frame_size) {
if (po->copy_thresh && if (po->copy_thresh &&
atomic_read(&sk->sk_rmem_alloc) + skb->truesize atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf) {
< (unsigned)sk->sk_rcvbuf) {
if (skb_shared(skb)) { if (skb_shared(skb)) {
copy_skb = skb_clone(skb, GFP_ATOMIC); copy_skb = skb_clone(skb, GFP_ATOMIC);
} else { } else {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment