Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: tracepoint: replace tcp_set_state tracepoint with inet_sock_set_state tracepoint

As sk_state is a common field for struct sock, so the state
transition tracepoint should not be a TCP specific feature.
Currently it traces all AF_INET state transition, so I rename this
tracepoint to inet_sock_set_state tracepoint with some minor changes and move it
into trace/events/sock.h.
We dont need to create a file named trace/events/inet_sock.h for this one single
tracepoint.

Two helpers are introduced to trace sk_state transition
- void inet_sk_state_store(struct sock *sk, int newstate);
- void inet_sk_set_state(struct sock *sk, int state);
As trace header should not be included in other header files,
so they are defined in sock.c.

The protocol such as SCTP maybe compiled as a ko, hence export
inet_sk_set_state().

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Yafang Shao and committed by
David S. Miller
563e0bb0 d7b850a7

+128 -40
+2
include/net/inet_sock.h
··· 290 290 #endif 291 291 292 292 int inet_sk_rebuild_header(struct sock *sk); 293 + void inet_sk_set_state(struct sock *sk, int state); 294 + void inet_sk_state_store(struct sock *sk, int newstate); 293 295 294 296 static inline unsigned int __inet_ehashfn(const __be32 laddr, 295 297 const __u16 lport,
+107
include/trace/events/sock.h
··· 6 6 #define _TRACE_SOCK_H 7 7 8 8 #include <net/sock.h> 9 + #include <net/ipv6.h> 9 10 #include <linux/tracepoint.h> 11 + #include <linux/ipv6.h> 12 + #include <linux/tcp.h> 13 + 14 + /* The protocol traced by sock_set_state */ 15 + #define inet_protocol_names \ 16 + EM(IPPROTO_TCP) \ 17 + EM(IPPROTO_DCCP) \ 18 + EMe(IPPROTO_SCTP) 19 + 20 + #define tcp_state_names \ 21 + EM(TCP_ESTABLISHED) \ 22 + EM(TCP_SYN_SENT) \ 23 + EM(TCP_SYN_RECV) \ 24 + EM(TCP_FIN_WAIT1) \ 25 + EM(TCP_FIN_WAIT2) \ 26 + EM(TCP_TIME_WAIT) \ 27 + EM(TCP_CLOSE) \ 28 + EM(TCP_CLOSE_WAIT) \ 29 + EM(TCP_LAST_ACK) \ 30 + EM(TCP_LISTEN) \ 31 + EM(TCP_CLOSING) \ 32 + EMe(TCP_NEW_SYN_RECV) 33 + 34 + /* enums need to be exported to user space */ 35 + #undef EM 36 + #undef EMe 37 + #define EM(a) TRACE_DEFINE_ENUM(a); 38 + #define EMe(a) TRACE_DEFINE_ENUM(a); 39 + 40 + inet_protocol_names 41 + tcp_state_names 42 + 43 + #undef EM 44 + #undef EMe 45 + #define EM(a) { a, #a }, 46 + #define EMe(a) { a, #a } 47 + 48 + #define show_inet_protocol_name(val) \ 49 + __print_symbolic(val, inet_protocol_names) 50 + 51 + #define show_tcp_state_name(val) \ 52 + __print_symbolic(val, tcp_state_names) 10 53 11 54 TRACE_EVENT(sock_rcvqueue_full, 12 55 ··· 104 61 __entry->allocated, 105 62 __entry->sysctl_rmem, 106 63 __entry->rmem_alloc) 64 + ); 65 + 66 + TRACE_EVENT(inet_sock_set_state, 67 + 68 + TP_PROTO(const struct sock *sk, const int oldstate, const int newstate), 69 + 70 + TP_ARGS(sk, oldstate, newstate), 71 + 72 + TP_STRUCT__entry( 73 + __field(const void *, skaddr) 74 + __field(int, oldstate) 75 + __field(int, newstate) 76 + __field(__u16, sport) 77 + __field(__u16, dport) 78 + __field(__u8, protocol) 79 + __array(__u8, saddr, 4) 80 + __array(__u8, daddr, 4) 81 + __array(__u8, saddr_v6, 16) 82 + __array(__u8, daddr_v6, 16) 83 + ), 84 + 85 + TP_fast_assign( 86 + struct inet_sock *inet = inet_sk(sk); 87 + struct in6_addr *pin6; 88 + __be32 *p32; 89 + 90 + __entry->skaddr = sk; 91 + __entry->oldstate = oldstate; 92 + __entry->newstate = newstate; 93 + 94 + __entry->protocol = sk->sk_protocol; 95 + __entry->sport = ntohs(inet->inet_sport); 96 + __entry->dport = ntohs(inet->inet_dport); 97 + 98 + p32 = (__be32 *) __entry->saddr; 99 + *p32 = inet->inet_saddr; 100 + 101 + p32 = (__be32 *) __entry->daddr; 102 + *p32 = inet->inet_daddr; 103 + 104 + #if IS_ENABLED(CONFIG_IPV6) 105 + if (sk->sk_family == AF_INET6) { 106 + pin6 = (struct in6_addr *)__entry->saddr_v6; 107 + *pin6 = sk->sk_v6_rcv_saddr; 108 + pin6 = (struct in6_addr *)__entry->daddr_v6; 109 + *pin6 = sk->sk_v6_daddr; 110 + } else 111 + #endif 112 + { 113 + pin6 = (struct in6_addr *)__entry->saddr_v6; 114 + ipv6_addr_set_v4mapped(inet->inet_saddr, pin6); 115 + pin6 = (struct in6_addr *)__entry->daddr_v6; 116 + ipv6_addr_set_v4mapped(inet->inet_daddr, pin6); 117 + } 118 + ), 119 + 120 + TP_printk("protocol=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4" 121 + "saddrv6=%pI6c daddrv6=%pI6c oldstate=%s newstate=%s", 122 + show_inet_protocol_name(__entry->protocol), 123 + __entry->sport, __entry->dport, 124 + __entry->saddr, __entry->daddr, 125 + __entry->saddr_v6, __entry->daddr_v6, 126 + show_tcp_state_name(__entry->oldstate), 127 + show_tcp_state_name(__entry->newstate)) 107 128 ); 108 129 109 130 #endif /* _TRACE_SOCK_H */
-31
include/trace/events/tcp.h
··· 9 9 #include <linux/tracepoint.h> 10 10 #include <net/ipv6.h> 11 11 12 - #define tcp_state_names \ 13 - EM(TCP_ESTABLISHED) \ 14 - EM(TCP_SYN_SENT) \ 15 - EM(TCP_SYN_RECV) \ 16 - EM(TCP_FIN_WAIT1) \ 17 - EM(TCP_FIN_WAIT2) \ 18 - EM(TCP_TIME_WAIT) \ 19 - EM(TCP_CLOSE) \ 20 - EM(TCP_CLOSE_WAIT) \ 21 - EM(TCP_LAST_ACK) \ 22 - EM(TCP_LISTEN) \ 23 - EM(TCP_CLOSING) \ 24 - EMe(TCP_NEW_SYN_RECV) \ 25 - 26 - /* enums need to be exported to user space */ 27 - #undef EM 28 - #undef EMe 29 - #define EM(a) TRACE_DEFINE_ENUM(a); 30 - #define EMe(a) TRACE_DEFINE_ENUM(a); 31 - 32 - tcp_state_names 33 - 34 - #undef EM 35 - #undef EMe 36 - #define EM(a) tcp_state_name(a), 37 - #define EMe(a) tcp_state_name(a) 38 - 39 - #define tcp_state_name(state) { state, #state } 40 - #define show_tcp_state_name(val) \ 41 - __print_symbolic(val, tcp_state_names) 42 - 43 12 /* 44 13 * tcp event with arguments sk and skb 45 14 *
+14
net/ipv4/af_inet.c
··· 121 121 #endif 122 122 #include <net/l3mdev.h> 123 123 124 + #include <trace/events/sock.h> 124 125 125 126 /* The inetsw table contains everything that inet_create needs to 126 127 * build a new socket. ··· 1220 1219 return err; 1221 1220 } 1222 1221 EXPORT_SYMBOL(inet_sk_rebuild_header); 1222 + 1223 + void inet_sk_set_state(struct sock *sk, int state) 1224 + { 1225 + trace_inet_sock_set_state(sk, sk->sk_state, state); 1226 + sk->sk_state = state; 1227 + } 1228 + EXPORT_SYMBOL(inet_sk_set_state); 1229 + 1230 + void inet_sk_state_store(struct sock *sk, int newstate) 1231 + { 1232 + trace_inet_sock_set_state(sk, sk->sk_state, newstate); 1233 + smp_store_release(&sk->sk_state, newstate); 1234 + } 1223 1235 1224 1236 struct sk_buff *inet_gso_segment(struct sk_buff *skb, 1225 1237 netdev_features_t features)
+3 -3
net/ipv4/inet_connection_sock.c
··· 783 783 if (newsk) { 784 784 struct inet_connection_sock *newicsk = inet_csk(newsk); 785 785 786 - newsk->sk_state = TCP_SYN_RECV; 786 + inet_sk_set_state(newsk, TCP_SYN_RECV); 787 787 newicsk->icsk_bind_hash = NULL; 788 788 789 789 inet_sk(newsk)->inet_dport = inet_rsk(req)->ir_rmt_port; ··· 877 877 * It is OK, because this socket enters to hash table only 878 878 * after validation is complete. 879 879 */ 880 - sk_state_store(sk, TCP_LISTEN); 880 + inet_sk_state_store(sk, TCP_LISTEN); 881 881 if (!sk->sk_prot->get_port(sk, inet->inet_num)) { 882 882 inet->inet_sport = htons(inet->inet_num); 883 883 ··· 888 888 return 0; 889 889 } 890 890 891 - sk->sk_state = TCP_CLOSE; 891 + inet_sk_set_state(sk, TCP_CLOSE); 892 892 return err; 893 893 } 894 894 EXPORT_SYMBOL_GPL(inet_csk_listen_start);
+1 -1
net/ipv4/inet_hashtables.c
··· 544 544 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 545 545 } else { 546 546 percpu_counter_inc(sk->sk_prot->orphan_count); 547 - sk->sk_state = TCP_CLOSE; 547 + inet_sk_set_state(sk, TCP_CLOSE); 548 548 sock_set_flag(sk, SOCK_DEAD); 549 549 inet_csk_destroy_sock(sk); 550 550 }
+1 -5
net/ipv4/tcp.c
··· 283 283 #include <asm/ioctls.h> 284 284 #include <net/busy_poll.h> 285 285 286 - #include <trace/events/tcp.h> 287 - 288 286 struct percpu_counter tcp_orphan_count; 289 287 EXPORT_SYMBOL_GPL(tcp_orphan_count); 290 288 ··· 2038 2040 { 2039 2041 int oldstate = sk->sk_state; 2040 2042 2041 - trace_tcp_set_state(sk, oldstate, state); 2042 - 2043 2043 switch (state) { 2044 2044 case TCP_ESTABLISHED: 2045 2045 if (oldstate != TCP_ESTABLISHED) ··· 2061 2065 /* Change state AFTER socket is unhashed to avoid closed 2062 2066 * socket sitting in hash tables. 2063 2067 */ 2064 - sk_state_store(sk, state); 2068 + inet_sk_state_store(sk, state); 2065 2069 2066 2070 #ifdef STATE_TRACE 2067 2071 SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n", sk, statename[oldstate], statename[state]);