Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2597f78 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'replace-tcp_set_state-tracepoint-with-inet_sock_set_state'

Yafang Shao says:

====================
replace tcp_set_state tracepoint with inet_sock_set_state

According to the discussion in the mail thread
https://patchwork.kernel.org/patch/10099243/

,
tcp_set_state tracepoint is renamed to inet_sock_set_state tracepoint and is
moved to include/trace/events/sock.h.

With this new tracepoint, we can trace AF_INET/AF_INET6 sock state transitions.
As there's only one single tracepoint for inet, so I didn't create a new trace
file named trace/events/inet_sock.h, and just place it in
include/trace/events/sock.h

Currently TCP/DCCP/SCTP state transitions are traced with this tracepoint.

- Why not more protocol ?
If we really think that anonter protocol should be traced, I will modify the
code to trace it.
I just want to make the code easy and not output useless information.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9ee1942c cbabf463
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -291,6 +291,31 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to,

int inet_sk_rebuild_header(struct sock *sk);

/**
 * inet_sk_state_load - read sk->sk_state for lockless contexts
 * @sk: socket pointer
 *
 * Paired with inet_sk_state_store(). Used in places we don't hold socket lock:
 * tcp_diag_get_info(), tcp_get_info(), tcp_poll(), get_tcp4_sock() ...
 */
static inline int inet_sk_state_load(const struct sock *sk)
{
	/* state change might impact lockless readers. */
	return smp_load_acquire(&sk->sk_state);
}

/**
 * inet_sk_state_store - update sk->sk_state
 * @sk: socket pointer
 * @newstate: new state
 *
 * Paired with inet_sk_state_load(). Should be used in contexts where
 * state change might impact lockless readers.
 */
void inet_sk_state_store(struct sock *sk, int newstate);

void inet_sk_set_state(struct sock *sk, int state);

static inline unsigned int __inet_ehashfn(const __be32 laddr,
					  const __u16 lport,
					  const __be32 faddr,
+0 −25
Original line number Diff line number Diff line
@@ -2333,31 +2333,6 @@ static inline bool sk_listener(const struct sock *sk)
	return (1 << sk->sk_state) & (TCPF_LISTEN | TCPF_NEW_SYN_RECV);
}

/**
 * sk_state_load - read sk->sk_state for lockless contexts
 * @sk: socket pointer
 *
 * Paired with sk_state_store(). Used in places we do not hold socket lock :
 * tcp_diag_get_info(), tcp_get_info(), tcp_poll(), get_tcp4_sock() ...
 */
static inline int sk_state_load(const struct sock *sk)
{
	return smp_load_acquire(&sk->sk_state);
}

/**
 * sk_state_store - update sk->sk_state
 * @sk: socket pointer
 * @newstate: new state
 *
 * Paired with sk_state_load(). Should be used in contexts where
 * state change might impact lockless readers.
 */
static inline void sk_state_store(struct sock *sk, int newstate)
{
	smp_store_release(&sk->sk_state, newstate);
}

void sock_enable_timestamp(struct sock *sk, int flag);
int sock_get_timestamp(struct sock *, struct timeval __user *);
int sock_get_timestampns(struct sock *, struct timespec __user *);
+107 −0
Original line number Diff line number Diff line
@@ -6,7 +6,50 @@
#define _TRACE_SOCK_H

#include <net/sock.h>
#include <net/ipv6.h>
#include <linux/tracepoint.h>
#include <linux/ipv6.h>
#include <linux/tcp.h>

/* The protocol traced by sock_set_state */
#define inet_protocol_names		\
		EM(IPPROTO_TCP)			\
		EM(IPPROTO_DCCP)		\
		EMe(IPPROTO_SCTP)

#define tcp_state_names			\
		EM(TCP_ESTABLISHED)		\
		EM(TCP_SYN_SENT)		\
		EM(TCP_SYN_RECV)		\
		EM(TCP_FIN_WAIT1)		\
		EM(TCP_FIN_WAIT2)		\
		EM(TCP_TIME_WAIT)		\
		EM(TCP_CLOSE)			\
		EM(TCP_CLOSE_WAIT)		\
		EM(TCP_LAST_ACK)		\
		EM(TCP_LISTEN)			\
		EM(TCP_CLOSING)			\
		EMe(TCP_NEW_SYN_RECV)

/* enums need to be exported to user space */
#undef EM
#undef EMe
#define EM(a)       TRACE_DEFINE_ENUM(a);
#define EMe(a)      TRACE_DEFINE_ENUM(a);

inet_protocol_names
tcp_state_names

#undef EM
#undef EMe
#define EM(a)       { a, #a },
#define EMe(a)      { a, #a }

#define show_inet_protocol_name(val)    \
	__print_symbolic(val, inet_protocol_names)

#define show_tcp_state_name(val)        \
	__print_symbolic(val, tcp_state_names)

TRACE_EVENT(sock_rcvqueue_full,

@@ -63,6 +106,70 @@ TRACE_EVENT(sock_exceed_buf_limit,
		__entry->rmem_alloc)
);

TRACE_EVENT(inet_sock_set_state,

	TP_PROTO(const struct sock *sk, const int oldstate, const int newstate),

	TP_ARGS(sk, oldstate, newstate),

	TP_STRUCT__entry(
		__field(const void *, skaddr)
		__field(int, oldstate)
		__field(int, newstate)
		__field(__u16, sport)
		__field(__u16, dport)
		__field(__u8, protocol)
		__array(__u8, saddr, 4)
		__array(__u8, daddr, 4)
		__array(__u8, saddr_v6, 16)
		__array(__u8, daddr_v6, 16)
	),

	TP_fast_assign(
		struct inet_sock *inet = inet_sk(sk);
		struct in6_addr *pin6;
		__be32 *p32;

		__entry->skaddr = sk;
		__entry->oldstate = oldstate;
		__entry->newstate = newstate;

		__entry->protocol = sk->sk_protocol;
		__entry->sport = ntohs(inet->inet_sport);
		__entry->dport = ntohs(inet->inet_dport);

		p32 = (__be32 *) __entry->saddr;
		*p32 = inet->inet_saddr;

		p32 = (__be32 *) __entry->daddr;
		*p32 =  inet->inet_daddr;

#if IS_ENABLED(CONFIG_IPV6)
		if (sk->sk_family == AF_INET6) {
			pin6 = (struct in6_addr *)__entry->saddr_v6;
			*pin6 = sk->sk_v6_rcv_saddr;
			pin6 = (struct in6_addr *)__entry->daddr_v6;
			*pin6 = sk->sk_v6_daddr;
		} else
#endif
		{
			pin6 = (struct in6_addr *)__entry->saddr_v6;
			ipv6_addr_set_v4mapped(inet->inet_saddr, pin6);
			pin6 = (struct in6_addr *)__entry->daddr_v6;
			ipv6_addr_set_v4mapped(inet->inet_daddr, pin6);
		}
	),

	TP_printk("protocol=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4"
			"saddrv6=%pI6c daddrv6=%pI6c oldstate=%s newstate=%s",
			show_inet_protocol_name(__entry->protocol),
			__entry->sport, __entry->dport,
			__entry->saddr, __entry->daddr,
			__entry->saddr_v6, __entry->daddr_v6,
			show_tcp_state_name(__entry->oldstate),
			show_tcp_state_name(__entry->newstate))
);

#endif /* _TRACE_SOCK_H */

/* This part must be outside protection */
+0 −16
Original line number Diff line number Diff line
@@ -9,22 +9,6 @@
#include <linux/tracepoint.h>
#include <net/ipv6.h>

#define tcp_state_name(state)	{ state, #state }
#define show_tcp_state_name(val)			\
	__print_symbolic(val,				\
		tcp_state_name(TCP_ESTABLISHED),	\
		tcp_state_name(TCP_SYN_SENT),		\
		tcp_state_name(TCP_SYN_RECV),		\
		tcp_state_name(TCP_FIN_WAIT1),		\
		tcp_state_name(TCP_FIN_WAIT2),		\
		tcp_state_name(TCP_TIME_WAIT),		\
		tcp_state_name(TCP_CLOSE),		\
		tcp_state_name(TCP_CLOSE_WAIT),		\
		tcp_state_name(TCP_LAST_ACK),		\
		tcp_state_name(TCP_LISTEN),		\
		tcp_state_name(TCP_CLOSING),		\
		tcp_state_name(TCP_NEW_SYN_RECV))

/*
 * tcp event with arguments sk and skb
 *
+1 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ void dccp_set_state(struct sock *sk, const int state)
	/* Change state AFTER socket is unhashed to avoid closed
	 * socket sitting in hash tables.
	 */
	sk->sk_state = state;
	inet_sk_set_state(sk, state);
}

EXPORT_SYMBOL_GPL(dccp_set_state);
Loading