* [PATCH net] tcp: fix overflow in __tcp_retransmit_skb()
@ 2016-09-15 15:12 Eric Dumazet
2016-09-15 15:52 ` David Laight
2016-09-17 14:00 ` David Miller
0 siblings, 2 replies; 4+ messages in thread
From: Eric Dumazet @ 2016-09-15 15:12 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
If a TCP socket gets a large write queue, an overflow can happen
in a test in __tcp_retransmit_skb() preventing all retransmits.
The flow then stalls and resets after timeouts.
Tested:
sysctl -w net.core.wmem_max=1000000000
netperf -H dest -- -s 1000000000
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/ipv4/tcp_output.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index bdaef7fd6e47..f53d0cca5fa4 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2605,7 +2605,8 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
* copying overhead: fragmentation, tunneling, mangling etc.
*/
if (atomic_read(&sk->sk_wmem_alloc) >
- min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))
+ min_t(u32, sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2),
+ sk->sk_sndbuf))
return -EAGAIN;
if (skb_still_in_host_queue(sk, skb))
^ permalink raw reply related [flat|nested] 4+ messages in thread
* RE: [PATCH net] tcp: fix overflow in __tcp_retransmit_skb()
2016-09-15 15:12 [PATCH net] tcp: fix overflow in __tcp_retransmit_skb() Eric Dumazet
@ 2016-09-15 15:52 ` David Laight
2016-09-15 16:35 ` Eric Dumazet
2016-09-17 14:00 ` David Miller
1 sibling, 1 reply; 4+ messages in thread
From: David Laight @ 2016-09-15 15:52 UTC (permalink / raw)
To: 'Eric Dumazet', David Miller; +Cc: netdev
From: Eric Dumazet
> Sent: 15 September 2016 16:13
> If a TCP socket gets a large write queue, an overflow can happen
> in a test in __tcp_retransmit_skb() preventing all retransmits.
...
> if (atomic_read(&sk->sk_wmem_alloc) >
> - min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))
> + min_t(u32, sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2),
> + sk->sk_sndbuf))
> return -EAGAIN;
Might it also be better to split that test to (say):
u32 wmem_alloc = atomic_read(&sk->sk_wmem_alloc);
if (unlikely((wmem_alloc > sk->sk_sndbuf))
return -EAGAIN;
if (unlikely(wmem_alloc > sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2)))
return -EAGAIN;
It might even be worth splitting the second test as:
if (unlikely(wmem_alloc > sk->sk_wmem_queued)
&& wmem_alloc > sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2))
return -EAGAIN;
David
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH net] tcp: fix overflow in __tcp_retransmit_skb()
2016-09-15 15:52 ` David Laight
@ 2016-09-15 16:35 ` Eric Dumazet
0 siblings, 0 replies; 4+ messages in thread
From: Eric Dumazet @ 2016-09-15 16:35 UTC (permalink / raw)
To: David Laight; +Cc: David Miller, netdev
On Thu, 2016-09-15 at 15:52 +0000, David Laight wrote:
> From: Eric Dumazet
> > Sent: 15 September 2016 16:13
> > If a TCP socket gets a large write queue, an overflow can happen
> > in a test in __tcp_retransmit_skb() preventing all retransmits.
> ...
> > if (atomic_read(&sk->sk_wmem_alloc) >
> > - min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))
> > + min_t(u32, sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2),
> > + sk->sk_sndbuf))
> > return -EAGAIN;
>
> Might it also be better to split that test to (say):
>
> u32 wmem_alloc = atomic_read(&sk->sk_wmem_alloc);
> if (unlikely((wmem_alloc > sk->sk_sndbuf))
> return -EAGAIN;
> if (unlikely(wmem_alloc > sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2)))
> return -EAGAIN;
Well, I find the existing code more readable, but this is just an
opinion.
Thanks.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH net] tcp: fix overflow in __tcp_retransmit_skb()
2016-09-15 15:12 [PATCH net] tcp: fix overflow in __tcp_retransmit_skb() Eric Dumazet
2016-09-15 15:52 ` David Laight
@ 2016-09-17 14:00 ` David Miller
1 sibling, 0 replies; 4+ messages in thread
From: David Miller @ 2016-09-17 14:00 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 15 Sep 2016 08:12:33 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> If a TCP socket gets a large write queue, an overflow can happen
> in a test in __tcp_retransmit_skb() preventing all retransmits.
>
> The flow then stalls and resets after timeouts.
>
> Tested:
>
> sysctl -w net.core.wmem_max=1000000000
> netperf -H dest -- -s 1000000000
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-09-17 14:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-15 15:12 [PATCH net] tcp: fix overflow in __tcp_retransmit_skb() Eric Dumazet
2016-09-15 15:52 ` David Laight
2016-09-15 16:35 ` Eric Dumazet
2016-09-17 14:00 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).