Implementation of RFC 4898 Extended TCP Statistics (Web10G)
Subsystems (3)
PATCH 1/3 Implementation of RFC 4898 Extended TCP Statistics (Web10G)
This patch provides the kernel instrument set. While this patch compiles and runs it does not have control and management capabilities. These are provided in the next patch submission.
--- include/linux/tcp.h | 8 + include/net/tcp.h | 1 + include/net/tcp_estats.h | 376 +++++++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/tcp.h | 6 +- net/ipv4/tcp.c | 21 ++- net/ipv4/tcp_cong.c | 3 + net/ipv4/tcp_htcp.c | 1 + net/ipv4/tcp_input.c | 116 +++++++++++++-- net/ipv4/tcp_ipv4.c | 10 ++ net/ipv4/tcp_output.c | 61 +++++++- net/ipv4/tcp_timer.c | 3 + net/ipv6/tcp_ipv6.c | 7 + 12 files changed, 592 insertions(+), 21 deletions(-) create mode 100644 include/net/tcp_estats.h
include/linux/tcp.h +8 -0
@@ -126,6 +126,10 @@ static inline struct tcp_request_sock *tcp_rsk(const struct request_sock *req)return (struct tcp_request_sock *)req; } +#ifdef CONFIG_TCP_ESTATS +struct tcp_estats ; +#endif +struct tcp_sock {/* inet_connection_sock has to be the first member of tcp_sock */ struct inet_connection_sock inet_conn;
@@ -309,6 +313,10 @@ struct tcp_sock {struct tcp_md5sig_info __rcu *md5sig_info;#endif +#ifdef CONFIG_TCP_ESTATS +struct tcp_estats *tcp_stats; +#endif +/* TCP fastopen related information */ struct tcp_fastopen_request *fastopen_req;/* fastopen_rsk points to request_sock that resulted in this big
include/net/tcp.h +1 -0
@@ -43,6 +43,7 @@#include <net/tcp_states.h> #include <net/inet_ecn.h> #include <net/dst.h> +#include <net/tcp_estats.h> #include <linux/seq_file.h> #include <linux/memcontrol.h>
include/net/tcp_estats.h new file +376 -0
376 lines not on this page · raw message
include/uapi/linux/tcp.h +5 -1
@@ -186,9 +186,13 @@ struct tcp_info {__u32 tcpi_rcv_space;__u32 tcpi_total_retrans; -__u64 tcpi_pacing_rate;__u64 tcpi_max_pacing_rate; + +#ifdef CONFIG_TCP_ESTATS +/* RFC 4898 extended stats Info */ +__u32 tcpi_estats_cid; +#endif };/* for TCP_MD5SIG socket option */
net/ipv4/tcp.c +20 -1
@@ -418,6 +418,10 @@ void tcp_init_sock(struct sock *sk) sk->sk_sndbuf = sysctl_tcp_wmem[1 ]; sk->sk_rcvbuf = sysctl_tcp_rmem[1 ]; +#ifdef CONFIG_TCP_ESTATS + tp->tcp_stats =NULL ; +#endif +local_bh_disable ();sock_update_memcg (sk);sk_sockets_allocated_inc (sk);
@@ -972,6 +976,9 @@ wait_for_memory:tcp_push (sk, flags & ~MSG_MORE , mss_now,TCP_NAGLE_PUSH , size_goal); +if (copied) +TCP_ESTATS_UPDATE (tp,tcp_estats_update_writeq (sk)); +if ((err =sk_stream_wait_memory (sk, &timeo)) !=0 ) goto do_error;
@@ -1264,9 +1271,11 @@ new_segment: wait_for_sndbuf:set_bit (SOCK_NOSPACE , &sk->sk_socket->flags); wait_for_memory: -if (copied) +if (copied) {tcp_push (sk, flags & ~MSG_MORE , mss_now,TCP_NAGLE_PUSH , size_goal); +TCP_ESTATS_UPDATE (tp,tcp_estats_update_writeq (sk)); + }if ((err =sk_stream_wait_memory (sk, &timeo)) !=0 ) goto do_error;
@@ -1658,6 +1667,8 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, *seq, TCP_SKB_CB(skb)->seq, tp->rcv_nxt, flags); } +TCP_ESTATS_UPDATE (tp,tcp_estats_update_recvq (sk)); +/* Well, if we have backlog, try to process it now yet. */ if (copied >= target && !sk->sk_backlog.tail)
@@ -2684,6 +2695,11 @@ void tcp_get_info(const struct sock *sk, struct tcp_info *info) sk->sk_pacing_rate : ~0ULL; info->tcpi_max_pacing_rate = sk->sk_max_pacing_rate != ~0U ? sk->sk_max_pacing_rate : ~0ULL ; + +#ifdef CONFIG_TCP_ESTATS + info->tcpi_estats_cid = (tp->tcp_stats && tp->tcp_stats->tcpe_cid >0 ) + ? tp->tcp_stats->tcpe_cid :0 ; +#endif }EXPORT_SYMBOL_GPL (tcp_get_info);
@@ -3101,6 +3117,9 @@ void __init tcp_init(void) tcp_hashinfo.ehash_mask + 1, tcp_hashinfo.bhash_size);tcp_metrics_init (); +BUG_ON (tcp_register_congestion_control (&tcp_reno) !=0 ); +tcp_estats_init (); +tcp_tasklet_init (); }
net/ipv4/tcp_cong.c +3 -0
@@ -295,6 +295,8 @@ void tcp_slow_start(struct tcp_sock *tp, u32 acked) {u32 cwnd = tp->snd_cwnd + acked; +TCP_ESTATS_VAR_INC (tp, stack_table, SlowStart); +if (cwnd > tp->snd_ssthresh) cwnd = tp->snd_ssthresh +1 ; tp->snd_cwnd =min (cwnd, tp->snd_cwnd_clamp);
@@ -304,6 +306,7 @@ EXPORT_SYMBOL_GPL(tcp_slow_start);/* In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd (or alternative w) */ void tcp_cong_avoid_ai (struct tcp_sock *tp,u32 w) { +TCP_ESTATS_VAR_INC (tp, stack_table, CongAvoid);if (tp->snd_cwnd_cnt >= w) {if (tp->snd_cwnd < tp->snd_cwnd_clamp) tp->snd_cwnd++;
net/ipv4/tcp_htcp.c +1 -0
@@ -251,6 +251,7 @@ static void htcp_cong_avoid(struct sock *sk, u32 ack, u32 acked) tp->snd_cwnd_cnt += ca->pkts_acked; ca->pkts_acked =1 ; +TCP_ESTATS_VAR_INC (tp, stack_table, CongAvoid); } }
net/ipv4/tcp_input.c +105 -11
366 lines not on this page · raw message
net/ipv4/tcp_ipv4.c +10 -0
@@ -1310,6 +1310,8 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,if (!newsk) goto exit_nonewsk; +tcp_estats_create (newsk,TCP_ESTATS_ADDRTYPE_IPV4 ,TCP_ESTATS_INACTIVE ); + newsk->sk_gso_type =SKB_GSO_TCPV4 ;inet_sk_rx_dst_set (newsk, skb);
@@ -1670,6 +1672,8 @@ process: skb->dev =NULL ;bh_lock_sock_nested (sk); +TCP_ESTATS_UPDATE ( +tcp_sk (sk),tcp_estats_update_segrecv (tcp_sk (sk), skb)); ret =0 ;if (!sock_owned_by_user (sk)) {if (!tcp_prequeue (sk, skb))
@@ -1680,6 +1684,8 @@ process:NET_INC_STATS_BH (net,LINUX_MIB_TCPBACKLOGDROP ); goto discard_and_relse; } +TCP_ESTATS_UPDATE ( +tcp_sk (sk),tcp_estats_update_finish_segrecv (tcp_sk (sk)));bh_unlock_sock (sk);sock_put (sk);
@@ -1809,6 +1815,8 @@ static int tcp_v4_init_sock(struct sock *sk)tcp_sk (sk)->af_specific = &tcp_sock_ipv4_specific;#endif +tcp_estats_create (sk,TCP_ESTATS_ADDRTYPE_IPV4 ,TCP_ESTATS_ACTIVE ); +return 0 ; }
@@ -1842,6 +1850,8 @@ void tcp_v4_destroy_sock(struct sock *sk)if (inet_csk (sk)->icsk_bind_hash)inet_put_port (sk); +tcp_estats_destroy (sk); +BUG_ON (tp->fastopen_rsk !=NULL );/* If socket is aborted during connect operation */
net/ipv4/tcp_output.c +53 -8
178 lines not on this page · raw message
net/ipv4/tcp_timer.c +3 -0
@@ -477,6 +477,9 @@ out_reset_timer: icsk->icsk_rto =min (icsk->icsk_rto <<1 ,TCP_RTO_MAX ); }inet_csk_reset_xmit_timer (sk,ICSK_TIME_RETRANS , icsk->icsk_rto,TCP_RTO_MAX ); + +TCP_ESTATS_UPDATE (tp,tcp_estats_update_timeout (sk)); +if (retransmits_timed_out (sk, sysctl_tcp_retries1 +1 ,0 ,0 ))__sk_dst_reset (sk);
net/ipv6/tcp_ipv6.c +7 -0
@@ -1131,6 +1131,8 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,if (newsk ==NULL ) goto out_nonewsk; +tcp_estats_create (newsk,TCP_ESTATS_ADDRTYPE_IPV6 ,TCP_ESTATS_INACTIVE ); +/* * No need to charge this sock to the relevant IPv6 refcnt debug socks * count here, tcp_create_openreq_child now does this for us, see the
@@ -1463,6 +1465,8 @@ process: skb->dev =NULL ;bh_lock_sock_nested (sk); +TCP_ESTATS_UPDATE ( +tcp_sk (sk),tcp_estats_update_segrecv (tcp_sk (sk), skb)); ret =0 ;if (!sock_owned_by_user (sk)) {if (!tcp_prequeue (sk, skb))
@@ -1473,6 +1477,8 @@ process:NET_INC_STATS_BH (net,LINUX_MIB_TCPBACKLOGDROP ); goto discard_and_relse; } +TCP_ESTATS_UPDATE ( +tcp_sk (sk),tcp_estats_update_finish_segrecv (tcp_sk (sk)));bh_unlock_sock (sk);sock_put (sk);
@@ -1661,6 +1667,7 @@ static int tcp_v6_init_sock(struct sock *sk)#ifdef CONFIG_TCP_MD5SIG tcp_sk (sk)->af_specific = &tcp_sock_ipv6_specific;#endif +tcp_estats_create (sk,TCP_ESTATS_ADDRTYPE_IPV6 ,TCP_ESTATS_ACTIVE );return 0 ; }
Signature · 1 line
1.9.3
Quoted 1 line · rapier
+ * The Web10Gig project. See http://www.web10gig.org
URL is already outdated?
Bjørn
Quoted 5 lines · Bjørn Mork
Quoted 1 line · rapier
+ * The Web10Gig project. See http://www.web10gig.org
URL is already outdated?
My apologies. The correct site is http://www.web10g.org. My fingers moved faster than my brain on that one.
Quoted 2 lines · Bjørn Mork
Quoted 1 line
+ * The Web10Gig project. See http://www.web10gig.org
URL is already outdated?
That's a typo. Please see http://www.web10g.org