tcp: add OFO snmp counters
authorEric Dumazet <edumazet@google.com>
Mon, 16 Jul 2012 01:41:36 +0000 (01:41 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 17 Jul 2012 05:12:00 +0000 (22:12 -0700)
Add three SNMP TCP counters, to better track TCP behavior
at global stage (netstat -s), when packets are received
Out Of Order (OFO)

TCPOFOQueue : Number of packets queued in OFO queue

TCPOFODrop  : Number of packets meant to be queued in OFO
              but dropped because socket rcvbuf limit hit.

TCPOFOMerge : Number of packets in OFO that were merged with
              other packets.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/snmp.h
net/ipv4/proc.c
net/ipv4/tcp_input.c

index 2e68f5ba03896947942c9b9886476c4af2a5da03..6e4c5112382895502b53cf2b11b63c53bc690aaa 100644 (file)
@@ -233,7 +233,10 @@ enum
        LINUX_MIB_TCPREQQFULLDOCOOKIES,         /* TCPReqQFullDoCookies */
        LINUX_MIB_TCPREQQFULLDROP,              /* TCPReqQFullDrop */
        LINUX_MIB_TCPRETRANSFAIL,               /* TCPRetransFail */
-       LINUX_MIB_TCPRCVCOALESCE,                       /* TCPRcvCoalesce */
+       LINUX_MIB_TCPRCVCOALESCE,               /* TCPRcvCoalesce */
+       LINUX_MIB_TCPOFOQUEUE,                  /* TCPOFOQueue */
+       LINUX_MIB_TCPOFODROP,                   /* TCPOFODrop */
+       LINUX_MIB_TCPOFOMERGE,                  /* TCPOFOMerge */
        __LINUX_MIB_MAX
 };
 
index 8af0d44e4e2219cee75126adc6f2348e1d1f2d70..dae25e7622cf77f3f82d3d771564238234159a2d 100644 (file)
@@ -258,6 +258,9 @@ static const struct snmp_mib snmp4_net_list[] = {
        SNMP_MIB_ITEM("TCPReqQFullDrop", LINUX_MIB_TCPREQQFULLDROP),
        SNMP_MIB_ITEM("TCPRetransFail", LINUX_MIB_TCPRETRANSFAIL),
        SNMP_MIB_ITEM("TCPRcvCoalesce", LINUX_MIB_TCPRCVCOALESCE),
+       SNMP_MIB_ITEM("TCPOFOQueue", LINUX_MIB_TCPOFOQUEUE),
+       SNMP_MIB_ITEM("TCPOFODrop", LINUX_MIB_TCPOFODROP),
+       SNMP_MIB_ITEM("TCPOFOMerge", LINUX_MIB_TCPOFOMERGE),
        SNMP_MIB_SENTINEL
 };
 
index 055ac49b8b4090f5dd0da1d9e2d587cca1d900b0..cc4e12f1f2f77e5a16dfebe06d5acc8f7875ac9c 100644 (file)
@@ -4397,8 +4397,8 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
 
        TCP_ECN_check_ce(tp, skb);
 
-       if (tcp_try_rmem_schedule(sk, skb->truesize)) {
-               /* TODO: should increment a counter */
+       if (unlikely(tcp_try_rmem_schedule(sk, skb->truesize))) {
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFODROP);
                __kfree_skb(skb);
                return;
        }
@@ -4407,6 +4407,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
        tp->pred_flags = 0;
        inet_csk_schedule_ack(sk);
 
+       NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFOQUEUE);
        SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n",
                   tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
 
@@ -4460,6 +4461,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
        if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) {
                if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
                        /* All the bits are present. Drop. */
+                       NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFOMERGE);
                        __kfree_skb(skb);
                        skb = NULL;
                        tcp_dsack_set(sk, seq, end_seq);
@@ -4498,6 +4500,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
                __skb_unlink(skb1, &tp->out_of_order_queue);
                tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
                                 TCP_SKB_CB(skb1)->end_seq);
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFOMERGE);
                __kfree_skb(skb1);
        }