| From foo@baz Tue Mar 24 11:01:55 CET 2015 |
| From: Josh Hunt <johunt@akamai.com> |
| Date: Thu, 19 Mar 2015 19:19:30 -0400 |
| Subject: tcp: fix tcp fin memory accounting |
| |
| From: Josh Hunt <johunt@akamai.com> |
| |
| [ Upstream commit d22e1537181188e5dc8cbc51451832625035bdc2 ] |
| |
| tcp_send_fin() does not account for the memory it allocates properly, so |
| sk_forward_alloc can be negative in cases where we've sent a FIN: |
| |
| ss example output (ss -amn | grep -B1 f4294): |
| tcp FIN-WAIT-1 0 1 192.168.0.1:45520 192.0.2.1:8080 |
| skmem:(r0,rb87380,t0,tb87380,f4294966016,w1280,o0,bl0) |
| Acked-by: Eric Dumazet <edumazet@google.com> |
| |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/ipv4/tcp_output.c | 6 +----- |
| 1 file changed, 1 insertion(+), 5 deletions(-) |
| |
| --- a/net/ipv4/tcp_output.c |
| +++ b/net/ipv4/tcp_output.c |
| @@ -2593,15 +2593,11 @@ void tcp_send_fin(struct sock *sk) |
| } else { |
| /* Socket is locked, keep trying until memory is available. */ |
| for (;;) { |
| - skb = alloc_skb_fclone(MAX_TCP_HEADER, |
| - sk->sk_allocation); |
| + skb = sk_stream_alloc_skb(sk, 0, sk->sk_allocation); |
| if (skb) |
| break; |
| yield(); |
| } |
| - |
| - /* Reserve space for headers and prepare control bits. */ |
| - skb_reserve(skb, MAX_TCP_HEADER); |
| /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */ |
| tcp_init_nondata_skb(skb, tp->write_seq, |
| TCPHDR_ACK | TCPHDR_FIN); |