From ff8ce5186386febac2d30dd5bfef3c49a61ab8a0 Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Sun, 20 Oct 2019 18:03:04 -0600 Subject: [PATCH] tcp: Clear sack info on purge This ensures that the sack information is cleared when TCP is in FIN-WAIT1 state. This also tracks whenever tcp queue purge is called which resets all the transmit queue information and ensures there are no outstanding packets. This addresses the following - 16496.596106: <6> Unable to handle kernel paging request at virtual address fffffff2cd81a368 16496.730771: <2> pc : tcp_ack+0x174/0x11e8 16496.734536: <2> lr : tcp_rcv_state_process+0x318/0x1300 16497.183109: <2> Call trace: 16497.183114: <2> tcp_ack+0x174/0x11e8 16497.183115: <2> tcp_rcv_state_process+0x318/0x1300 16497.183117: <2> tcp_v4_do_rcv+0x1a8/0x1f0 16497.183118: <2> tcp_v4_rcv+0xe90/0xec8 16497.183120: <2> ip_protocol_deliver_rcu+0x150/0x298 16497.183121: <2> ip_local_deliver+0x21c/0x2a8 16497.183122: <2> ip_rcv+0x1c4/0x210 16497.183124: <2> __netif_receive_skb_core+0xab0/0xd90 16497.183125: <2> netif_receive_skb_internal+0x12c/0x368 16497.183126: <2> napi_gro_receive+0x1e0/0x290 No outstanding data is expected on a socket after write queue purge is called. CRs-Fixed: 2541019 Change-Id: I586c43931969eae48fe1bf9799ef38267401fdc6 Signed-off-by: Subash Abhinov Kasiviswanathan --- include/linux/tcp.h | 3 ++- net/ipv4/tcp.c | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 4374196b98ea..9af749754d2d 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -232,7 +232,8 @@ struct tcp_sock { fastopen_connect:1, /* FASTOPEN_CONNECT sockopt */ fastopen_no_cookie:1, /* Allow send/recv SYN+data without a cookie */ is_sack_reneg:1, /* in recovery from loss with SACK reneg? */ - unused:2; + unused:1, + wqp_called:1; u8 nonagle : 4,/* Disable Nagle algorithm? */ thin_lto : 1,/* Use linear timeouts for thin streams */ recvmsg_inq : 1,/* Indicate # of bytes in queue upon recvmsg */ diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 1a1fcb32c491..0c29bdd41a8d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2534,6 +2534,9 @@ void tcp_write_queue_purge(struct sock *sk) INIT_LIST_HEAD(&tcp_sk(sk)->tsorted_sent_queue); sk_mem_reclaim(sk); tcp_clear_all_retrans_hints(tcp_sk(sk)); + tcp_sk(sk)->highest_sack = NULL; + tcp_sk(sk)->sacked_out = 0; + tcp_sk(sk)->wqp_called = 1; tcp_sk(sk)->packets_out = 0; inet_csk(sk)->icsk_backoff = 0; }