linux/net/ipv4
Eric Dumazet 2331ccc5b3 tcp: enhance tcp collapsing
As Ilya Lesokhin suggested, we can collapse two skbs at retransmit
time even if the skb at the right has fragments.

We simply have to use more generic skb_copy_bits() instead of
skb_copy_from_linear_data() in tcp_collapse_retrans()

Also need to guard this skb_copy_bits() in case there is nothing to
copy, otherwise skb_put() could panic if left skb has frags.

Tested:

Used following packetdrill test

// Establish a connection.
0.000 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
   +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
   +0 bind(3, ..., ...) = 0
   +0 listen(3, 1) = 0

   +0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 8>
   +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
+.100 < . 1:1(0) ack 1 win 257
   +0 accept(3, ..., ...) = 4

   +0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
   +0 write(4, ..., 200) = 200
   +0 > P. 1:201(200) ack 1
+.001 write(4, ..., 200) = 200
   +0 > P. 201:401(200) ack 1
+.001 write(4, ..., 200) = 200
   +0 > P. 401:601(200) ack 1
+.001 write(4, ..., 200) = 200
   +0 > P. 601:801(200) ack 1
+.001 write(4, ..., 200) = 200
   +0 > P. 801:1001(200) ack 1
+.001 write(4, ..., 100) = 100
   +0 > P. 1001:1101(100) ack 1
+.001 write(4, ..., 100) = 100
   +0 > P. 1101:1201(100) ack 1
+.001 write(4, ..., 100) = 100
   +0 > P. 1201:1301(100) ack 1
+.001 write(4, ..., 100) = 100
   +0 > P. 1301:1401(100) ack 1

+.100 < . 1:1(0) ack 1 win 257 <nop,nop,sack 1001:1401>
// Check that TCP collapse works :
   +0 > P. 1:1001(1000) ack 1

Reported-by: Ilya Lesokhin <ilyal@mellanox.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Yuchung Cheng <ycheng@google.com>
Cc: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Acked-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2016-11-02 15:21:36 -04:00
..
netfilter netfilter: move socket lookup infrastructure to nf_socket_ipv{4,6}.c 2016-11-01 20:50:31 +01:00
af_inet.c net: add recursion limit to GRO 2016-10-20 14:32:22 -04:00
ah4.c
arp.c
cipso_ipv4.c
datagram.c
devinet.c
esp4.c
fib_frontend.c switchdev: remove FIB offload infrastructure 2016-09-28 04:48:00 -04:00
fib_lookup.h
fib_rules.c switchdev: remove FIB offload infrastructure 2016-09-28 04:48:00 -04:00
fib_semantics.c
fib_trie.c switchdev: remove FIB offload infrastructure 2016-09-28 04:48:00 -04:00
fou.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2016-10-30 12:42:58 -04:00
gre_demux.c
gre_offload.c net: add recursion limit to GRO 2016-10-20 14:32:22 -04:00
icmp.c
igmp.c
inet_connection_sock.c
inet_diag.c net: ip, diag -- Add diag interface for raw sockets 2016-10-23 19:35:24 -04:00
inet_fragment.c
inet_hashtables.c net: Require exact match for TCP socket lookups if dif is l3mdev 2016-10-17 10:17:05 -04:00
inet_timewait_sock.c
inetpeer.c
ip_forward.c
ip_fragment.c
ip_gre.c
ip_input.c net: VRF: Pass original iif to ip_route_input() 2016-09-16 04:24:07 -04:00
ip_options.c
ip_output.c ipv4: Remove unused but set variable 2016-10-18 10:30:28 -04:00
ip_sockglue.c udp: fix IP_CHECKSUM handling 2016-10-26 17:33:22 -04:00
ip_tunnel.c ipv4/6: use core net MTU range checking 2016-10-20 14:51:10 -04:00
ip_tunnel_core.c
ip_vti.c
ipcomp.c
ipconfig.c
ipip.c ip_tunnel: add collect_md mode to IPIP tunnel 2016-09-17 10:13:07 -04:00
ipmr.c net: Enable support for VRF with ipv4 multicast 2016-11-01 11:54:26 -04:00
Kconfig net: ip, diag -- Add diag interface for raw sockets 2016-10-23 19:35:24 -04:00
Makefile net: ip, diag -- Add diag interface for raw sockets 2016-10-23 19:35:24 -04:00
netfilter.c
ping.c udp: must lock the socket in udp_disconnect() 2016-10-20 14:45:52 -04:00
proc.c net: Suppress the "Comparison to NULL could be written" warnings 2016-09-30 01:50:45 -04:00
protocol.c
raw.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2016-10-30 12:42:58 -04:00
raw_diag.c net: ip, diag: include net/inet_sock.h 2016-10-29 14:52:18 -04:00
route.c net: Enable support for VRF with ipv4 multicast 2016-11-01 11:54:26 -04:00
syncookies.c
sysctl_net_ipv4.c ipv4: use the right lock for ping_group_range 2016-10-22 16:23:12 -04:00
tcp.c Merge branch 'akpm' (patches from Andrew) 2016-10-07 21:38:00 -07:00
tcp_bbr.c tcp_bbr: add a state transition diagram and accompanying comment 2016-10-29 17:12:43 -04:00
tcp_bic.c
tcp_cdg.c tcp: cdg: rename struct minmax in tcp_cdg.c to avoid a naming conflict 2016-09-21 00:22:59 -04:00
tcp_cong.c tcp: new CC hook to set sending rate with rate_sample in any CA state 2016-09-21 00:23:01 -04:00
tcp_cubic.c
tcp_dctcp.c
tcp_diag.c
tcp_fastopen.c
tcp_highspeed.c
tcp_htcp.c
tcp_hybla.c
tcp_illinois.c
tcp_input.c tcp/dccp: drop SYN packets if accept queue is full 2016-10-29 15:09:21 -04:00
tcp_ipv4.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2016-10-30 12:42:58 -04:00
tcp_lp.c
tcp_metrics.c genetlink: mark families as __ro_after_init 2016-10-27 16:16:09 -04:00
tcp_minisocks.c tcp: track application-limited rate samples 2016-09-21 00:23:00 -04:00
tcp_nv.c
tcp_offload.c gso: Support partial splitting at the frag_list pointer 2016-09-19 20:59:34 -04:00
tcp_output.c tcp: enhance tcp collapsing 2016-11-02 15:21:36 -04:00
tcp_probe.c
tcp_rate.c tcp: export data delivery rate 2016-09-21 00:23:00 -04:00
tcp_recovery.c
tcp_scalable.c
tcp_timer.c tcp: Change txhash on every SYN and RTO retransmit 2016-09-28 07:52:34 -04:00
tcp_vegas.c
tcp_vegas.h
tcp_veno.c
tcp_westwood.c
tcp_yeah.c
tunnel4.c
udp.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2016-10-30 12:42:58 -04:00
udp_diag.c
udp_impl.h
udp_offload.c net: add recursion limit to GRO 2016-10-20 14:32:22 -04:00
udp_tunnel.c
udplite.c
xfrm4_input.c
xfrm4_mode_beet.c
xfrm4_mode_transport.c
xfrm4_mode_tunnel.c
xfrm4_output.c
xfrm4_policy.c
xfrm4_protocol.c
xfrm4_state.c
xfrm4_tunnel.c