summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/snmp.h1
-rw-r--r--net/ipv4/proc.c1
-rw-r--r--net/ipv4/tcp_input.c19
3 files changed, 20 insertions, 1 deletions
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index 8ee8af4e6da9..2e68f5ba0389 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -233,6 +233,7 @@ enum
233 LINUX_MIB_TCPREQQFULLDOCOOKIES, /* TCPReqQFullDoCookies */ 233 LINUX_MIB_TCPREQQFULLDOCOOKIES, /* TCPReqQFullDoCookies */
234 LINUX_MIB_TCPREQQFULLDROP, /* TCPReqQFullDrop */ 234 LINUX_MIB_TCPREQQFULLDROP, /* TCPReqQFullDrop */
235 LINUX_MIB_TCPRETRANSFAIL, /* TCPRetransFail */ 235 LINUX_MIB_TCPRETRANSFAIL, /* TCPRetransFail */
236 LINUX_MIB_TCPRCVCOALESCE, /* TCPRcvCoalesce */
236 __LINUX_MIB_MAX 237 __LINUX_MIB_MAX
237}; 238};
238 239
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 02d61079f08b..8af0d44e4e22 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -257,6 +257,7 @@ static const struct snmp_mib snmp4_net_list[] = {
257 SNMP_MIB_ITEM("TCPReqQFullDoCookies", LINUX_MIB_TCPREQQFULLDOCOOKIES), 257 SNMP_MIB_ITEM("TCPReqQFullDoCookies", LINUX_MIB_TCPREQQFULLDOCOOKIES),
258 SNMP_MIB_ITEM("TCPReqQFullDrop", LINUX_MIB_TCPREQQFULLDROP), 258 SNMP_MIB_ITEM("TCPReqQFullDrop", LINUX_MIB_TCPREQQFULLDROP),
259 SNMP_MIB_ITEM("TCPRetransFail", LINUX_MIB_TCPRETRANSFAIL), 259 SNMP_MIB_ITEM("TCPRetransFail", LINUX_MIB_TCPRETRANSFAIL),
260 SNMP_MIB_ITEM("TCPRcvCoalesce", LINUX_MIB_TCPRCVCOALESCE),
260 SNMP_MIB_SENTINEL 261 SNMP_MIB_SENTINEL
261}; 262};
262 263
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index fa7de12c4a52..e886e2f7fa8d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4484,7 +4484,24 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
4484 end_seq = TCP_SKB_CB(skb)->end_seq; 4484 end_seq = TCP_SKB_CB(skb)->end_seq;
4485 4485
4486 if (seq == TCP_SKB_CB(skb1)->end_seq) { 4486 if (seq == TCP_SKB_CB(skb1)->end_seq) {
4487 __skb_queue_after(&tp->out_of_order_queue, skb1, skb); 4487 /* Packets in ofo can stay in queue a long time.
4488 * Better try to coalesce them right now
4489 * to avoid future tcp_collapse_ofo_queue(),
4490 * probably the most expensive function in tcp stack.
4491 */
4492 if (skb->len <= skb_tailroom(skb1) && !tcp_hdr(skb)->fin) {
4493 NET_INC_STATS_BH(sock_net(sk),
4494 LINUX_MIB_TCPRCVCOALESCE);
4495 BUG_ON(skb_copy_bits(skb, 0,
4496 skb_put(skb1, skb->len),
4497 skb->len));
4498 TCP_SKB_CB(skb1)->end_seq = end_seq;
4499 TCP_SKB_CB(skb1)->ack_seq = TCP_SKB_CB(skb)->ack_seq;
4500 __kfree_skb(skb);
4501 skb = NULL;
4502 } else {
4503 __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
4504 }
4488 4505
4489 if (!tp->rx_opt.num_sacks || 4506 if (!tp->rx_opt.num_sacks ||
4490 tp->selective_acks[0].end_seq != seq) 4507 tp->selective_acks[0].end_seq != seq)