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

tcp: Export to userspace the TCP state names for the trace events

The TCP trace events (specifically tcp_set_state), maps emums to symbol
names via __print_symbolic(). But this only works for reading trace events
from the tracefs trace files. If perf or trace-cmd were to record these
events, the event format file does not convert the enum names into numbers,
and you get something like:

__print_symbolic(REC->oldstate,
{ TCP_ESTABLISHED, "TCP_ESTABLISHED" },
{ TCP_SYN_SENT, "TCP_SYN_SENT" },
{ TCP_SYN_RECV, "TCP_SYN_RECV" },
{ TCP_FIN_WAIT1, "TCP_FIN_WAIT1" },
{ TCP_FIN_WAIT2, "TCP_FIN_WAIT2" },
{ TCP_TIME_WAIT, "TCP_TIME_WAIT" },
{ TCP_CLOSE, "TCP_CLOSE" },
{ TCP_CLOSE_WAIT, "TCP_CLOSE_WAIT" },
{ TCP_LAST_ACK, "TCP_LAST_ACK" },
{ TCP_LISTEN, "TCP_LISTEN" },
{ TCP_CLOSING, "TCP_CLOSING" },
{ TCP_NEW_SYN_RECV, "TCP_NEW_SYN_RECV" })

Where trace-cmd and perf do not know the values of those enums.

Use the TRACE_DEFINE_ENUM() macros that will have the trace events convert
the enum strings into their values at system boot. This will allow perf and
trace-cmd to see actual numbers and not enums:

__print_symbolic(REC->oldstate,
{ 1, "TCP_ESTABLISHED" },
{ 2, "TCP_SYN_SENT" },
{ 3, "TCP_SYN_RECV" },
{ 4, "TCP_FIN_WAIT1" },
{ 5, "TCP_FIN_WAIT2" },
{ 6, "TCP_TIME_WAIT" },
{ 7, "TCP_CLOSE" },
{ 8, "TCP_CLOSE_WAIT" },
{ 9, "TCP_LAST_ACK" },
{ 10, "TCP_LISTEN" },
{ 11, "TCP_CLOSING" },
{ 12, "TCP_NEW_SYN_RECV" })

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Acked-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Steven Rostedt (VMware) and committed by
David S. Miller
d7b850a7 9ee1942c

+28 -13
+28 -13
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 + 12 39 #define tcp_state_name(state) { state, #state } 13 40 #define show_tcp_state_name(val) \ 14 - __print_symbolic(val, \ 15 - tcp_state_name(TCP_ESTABLISHED), \ 16 - tcp_state_name(TCP_SYN_SENT), \ 17 - tcp_state_name(TCP_SYN_RECV), \ 18 - tcp_state_name(TCP_FIN_WAIT1), \ 19 - tcp_state_name(TCP_FIN_WAIT2), \ 20 - tcp_state_name(TCP_TIME_WAIT), \ 21 - tcp_state_name(TCP_CLOSE), \ 22 - tcp_state_name(TCP_CLOSE_WAIT), \ 23 - tcp_state_name(TCP_LAST_ACK), \ 24 - tcp_state_name(TCP_LISTEN), \ 25 - tcp_state_name(TCP_CLOSING), \ 26 - tcp_state_name(TCP_NEW_SYN_RECV)) 41 + __print_symbolic(val, tcp_state_names) 27 42 28 43 /* 29 44 * tcp event with arguments sk and skb