The TCP/IP transition from TCP_LISTEN to TCP_SYN_RECV and some other
transitions are not traced with tcp_set_state tracepoint.
In order to trace the whole tcp lifespans, two helpers are introduced,
void sk_set_state(struct sock *sk, int state);
void sk_state_store(struct sock *sk, int newstate);
When do TCP/IP state transition, we should use these two helpers or use
tcp_set_state() other than assigning a value to sk_state directly.
Signed-off-by: Yafang Shao <redacted>
Acked-by: Song Liu <redacted>
Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Yafang Shao <redacted>
---
v4->v5: Trace only TCP sockets, whatever it is stream socket or raw socket.
v3->v4: Do not trace DCCP socket
v2->v3: Per suggestion from Marcelo Ricardo Leitner, inverting __
to sk_state_store.
---
include/net/sock.h | 8 ++++++--
net/core/sock.c | 15 +++++++++++++++
net/ipv4/inet_connection_sock.c | 5 +++--
net/ipv4/inet_hashtables.c | 2 +-
net/ipv4/tcp.c | 2 +-
5 files changed, 26 insertions(+), 6 deletions(-)
@@ -888,7 +888,8 @@ int inet_csk_listen_start(struct sock *sk, int backlog)return0;}-sk->sk_state=TCP_CLOSE;+sk_set_state(sk,TCP_CLOSE);+returnerr;}EXPORT_SYMBOL_GPL(inet_csk_listen_start);
@@ -2065,7 +2065,7 @@ void tcp_set_state(struct sock *sk, int state)/* Change state AFTER socket is unhashed to avoid closed*socketsittinginhashtables.*/-sk_state_store(sk,state);+__sk_state_store(sk,state);#ifdef STATE_TRACESOCK_DEBUG(sk,"TCP sk=%p, State %s -> %s\n",sk,statename[oldstate],statename[state]);
On Thu, Dec 07, 2017 at 02:10:42PM +0000, Yafang Shao wrote:
quoted hunk
The TCP/IP transition from TCP_LISTEN to TCP_SYN_RECV and some other
transitions are not traced with tcp_set_state tracepoint.
In order to trace the whole tcp lifespans, two helpers are introduced,
void sk_set_state(struct sock *sk, int state);
void sk_state_store(struct sock *sk, int newstate);
When do TCP/IP state transition, we should use these two helpers or use
tcp_set_state() other than assigning a value to sk_state directly.
Signed-off-by: Yafang Shao <redacted>
Acked-by: Song Liu <redacted>
Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Yafang Shao <redacted>
---
v4->v5: Trace only TCP sockets, whatever it is stream socket or raw socket.
v3->v4: Do not trace DCCP socket
v2->v3: Per suggestion from Marcelo Ricardo Leitner, inverting __
to sk_state_store.
---
include/net/sock.h | 8 ++++++--
net/core/sock.c | 15 +++++++++++++++
net/ipv4/inet_connection_sock.c | 5 +++--
net/ipv4/inet_hashtables.c | 2 +-
net/ipv4/tcp.c | 2 +-
5 files changed, 26 insertions(+), 6 deletions(-)
I think this is going in the wrong way. When Dave said to not define a
sock generic function in tcp code on v3, you moved it all from tcp.h
to sock.h. But now sock.h gets to deal with more tcp code, which also
isn't nice.
Instead, if you move it back to tcp.h but rename the function to
tcp_state_store (instead of the original sk_state_store), it won't be
a generic sock code and will fit nicely into tcp.h.
You may then even keep sk_state_store() as it is now, and just define
tcp_state_store():
tcp_state_store()
{
trace_tcp_...();
sk_state_store();
}
Making it very clear that this code is only to be used by tcp stack.
quoted hunk
+ __sk_state_store(sk, newstate);+}++void sk_set_state(struct sock *sk, int state)
Same about this one.
Dave?
quoted hunk
+{+ if (sk->sk_protocol == IPPROTO_TCP) + trace_tcp_set_state(sk, sk->sk_state, state);+ sk->sk_state = state;+}+ void sock_enable_timestamp(struct sock *sk, int flag) { if (!sock_flag(sk, flag)) {
@@ -888,7 +888,8 @@ int inet_csk_listen_start(struct sock *sk, int backlog)return0;}-sk->sk_state=TCP_CLOSE;+sk_set_state(sk,TCP_CLOSE);+returnerr;}EXPORT_SYMBOL_GPL(inet_csk_listen_start);
@@ -2065,7 +2065,7 @@ void tcp_set_state(struct sock *sk, int state)/* Change state AFTER socket is unhashed to avoid closed*socketsittinginhashtables.*/-sk_state_store(sk,state);+__sk_state_store(sk,state);#ifdef STATE_TRACESOCK_DEBUG(sk,"TCP sk=%p, State %s -> %s\n",sk,statename[oldstate],statename[state]);
On Thu, Dec 07, 2017 at 02:10:42PM +0000, Yafang Shao wrote:
quoted
The TCP/IP transition from TCP_LISTEN to TCP_SYN_RECV and some other
transitions are not traced with tcp_set_state tracepoint.
In order to trace the whole tcp lifespans, two helpers are introduced,
void sk_set_state(struct sock *sk, int state);
void sk_state_store(struct sock *sk, int newstate);
When do TCP/IP state transition, we should use these two helpers or use
tcp_set_state() other than assigning a value to sk_state directly.
Signed-off-by: Yafang Shao <redacted>
Acked-by: Song Liu <redacted>
Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Yafang Shao <redacted>
---
v4->v5: Trace only TCP sockets, whatever it is stream socket or raw socket.
v3->v4: Do not trace DCCP socket
v2->v3: Per suggestion from Marcelo Ricardo Leitner, inverting __
to sk_state_store.
---
include/net/sock.h | 8 ++++++--
net/core/sock.c | 15 +++++++++++++++
net/ipv4/inet_connection_sock.c | 5 +++--
net/ipv4/inet_hashtables.c | 2 +-
net/ipv4/tcp.c | 2 +-
5 files changed, 26 insertions(+), 6 deletions(-)
I think this is going in the wrong way. When Dave said to not define a
sock generic function in tcp code on v3, you moved it all from tcp.h
to sock.h. But now sock.h gets to deal with more tcp code, which also
isn't nice.
Instead, if you move it back to tcp.h but rename the function to
tcp_state_store (instead of the original sk_state_store), it won't be
a generic sock code and will fit nicely into tcp.h.
You may then even keep sk_state_store() as it is now, and just define
tcp_state_store():
tcp_state_store()
{
trace_tcp_...();
sk_state_store();
}
Making it very clear that this code is only to be used by tcp stack.
Then we have to do bellow 'if' test in inet_connection_sock.c and
/inet_hashtables.
if (sk->sk_protocol == IPPROTO_TCP)
tcp_state_store(sk, TCP_CLOSE)
else
sk->sk_state = TCP_CLOSE;
And same code about other changes.
Is that proper ?
quoted
+ __sk_state_store(sk, newstate);+}++void sk_set_state(struct sock *sk, int state)
Same about this one.
Dave?
quoted
+{+ if (sk->sk_protocol == IPPROTO_TCP)+ trace_tcp_set_state(sk, sk->sk_state, state);+ sk->sk_state = state;+}+ void sock_enable_timestamp(struct sock *sk, int flag) { if (!sock_flag(sk, flag)) {
@@ -888,7 +888,8 @@ int inet_csk_listen_start(struct sock *sk, int backlog)return0;}-sk->sk_state=TCP_CLOSE;+sk_set_state(sk,TCP_CLOSE);+returnerr;}EXPORT_SYMBOL_GPL(inet_csk_listen_start);
@@ -2065,7 +2065,7 @@ void tcp_set_state(struct sock *sk, int state)/* Change state AFTER socket is unhashed to avoid closed*socketsittinginhashtables.*/-sk_state_store(sk,state);+__sk_state_store(sk,state);#ifdef STATE_TRACESOCK_DEBUG(sk,"TCP sk=%p, State %s -> %s\n",sk,statename[oldstate],statename[state]);--
On Thu, Dec 07, 2017 at 02:10:42PM +0000, Yafang Shao wrote:
quoted
The TCP/IP transition from TCP_LISTEN to TCP_SYN_RECV and some other
transitions are not traced with tcp_set_state tracepoint.
In order to trace the whole tcp lifespans, two helpers are introduced,
void sk_set_state(struct sock *sk, int state);
void sk_state_store(struct sock *sk, int newstate);
When do TCP/IP state transition, we should use these two helpers or use
tcp_set_state() other than assigning a value to sk_state directly.
Signed-off-by: Yafang Shao <redacted>
Acked-by: Song Liu <redacted>
Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Yafang Shao <redacted>
---
v4->v5: Trace only TCP sockets, whatever it is stream socket or raw socket.
v3->v4: Do not trace DCCP socket
v2->v3: Per suggestion from Marcelo Ricardo Leitner, inverting __
to sk_state_store.
---
include/net/sock.h | 8 ++++++--
net/core/sock.c | 15 +++++++++++++++
net/ipv4/inet_connection_sock.c | 5 +++--
net/ipv4/inet_hashtables.c | 2 +-
net/ipv4/tcp.c | 2 +-
5 files changed, 26 insertions(+), 6 deletions(-)
I think this is going in the wrong way. When Dave said to not define a
sock generic function in tcp code on v3, you moved it all from tcp.h
to sock.h. But now sock.h gets to deal with more tcp code, which also
isn't nice.
Instead, if you move it back to tcp.h but rename the function to
tcp_state_store (instead of the original sk_state_store), it won't be
a generic sock code and will fit nicely into tcp.h.
You may then even keep sk_state_store() as it is now, and just define
tcp_state_store():
tcp_state_store()
{
trace_tcp_...();
sk_state_store();
}
Making it very clear that this code is only to be used by tcp stack.
Then we have to do bellow 'if' test in inet_connection_sock.c and
/inet_hashtables.
if (sk->sk_protocol == IPPROTO_TCP)
tcp_state_store(sk, TCP_CLOSE)
else
sk->sk_state = TCP_CLOSE;
And same code about other changes.
Is that proper ?
It will looks like these,
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(newsk, TCP_SYN_RECV);
else
newsk->sk_state = TCP_SYN_RECV;
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(sk, TCP_CLOSE);
else
sk->sk_state = TCP_CLOSE;
if (sk->sk_protocol == IPPROTO_TCP)
tcp_state_store(sk, state);
else
sk_state_store(sk, state);
Some redundant code.
IMO, put these similar code into a wrapper is more nice.
Thanks
Yafang
On Fri, Dec 08, 2017 at 11:40:23AM +0800, Yafang Shao wrote:
It will looks like these,
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(newsk, TCP_SYN_RECV);
else
newsk->sk_state = TCP_SYN_RECV;
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(sk, TCP_CLOSE);
else
sk->sk_state = TCP_CLOSE;
if (sk->sk_protocol == IPPROTO_TCP)
tcp_state_store(sk, state);
else
sk_state_store(sk, state);
Some redundant code.
IMO, put these similar code into a wrapper is more nice.
Agreed. Hmpf, looks like one way or another, we have to add the sk_
functions to do such check, and then the tcp_* won't help much.
I'm okay with this v5 then, can't see a better way around it.
Marcelo
It will looks like these,
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(newsk, TCP_SYN_RECV);
else
newsk->sk_state = TCP_SYN_RECV;
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(sk, TCP_CLOSE);
else
sk->sk_state = TCP_CLOSE;
if (sk->sk_protocol == IPPROTO_TCP)
tcp_state_store(sk, state);
else
sk_state_store(sk, state);
Some redundant code.
IMO, put these similar code into a wrapper is more nice.
I think this discussion and how ugly this is getting shows that
tracing the state transitions of a socket is perhaps not best as a TCP
specific feature.
It will looks like these,
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(newsk, TCP_SYN_RECV);
else
newsk->sk_state = TCP_SYN_RECV;
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(sk, TCP_CLOSE);
else
sk->sk_state = TCP_CLOSE;
if (sk->sk_protocol == IPPROTO_TCP)
tcp_state_store(sk, state);
else
sk_state_store(sk, state);
Some redundant code.
IMO, put these similar code into a wrapper is more nice.
I think this discussion and how ugly this is getting shows that
tracing the state transitions of a socket is perhaps not best as a TCP
specific feature.
Do you mean that tcp_set_state tracepoint should be replaced with
sk_set_state tracepoint and move that tracepoint to
trace/events/sock.h ?
Thanks
Yafang
It will looks like these,
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(newsk, TCP_SYN_RECV);
else
newsk->sk_state = TCP_SYN_RECV;
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(sk, TCP_CLOSE);
else
sk->sk_state = TCP_CLOSE;
if (sk->sk_protocol == IPPROTO_TCP)
tcp_state_store(sk, state);
else
sk_state_store(sk, state);
Some redundant code.
IMO, put these similar code into a wrapper is more nice.
I think this discussion and how ugly this is getting shows that
tracing the state transitions of a socket is perhaps not best as a TCP
specific feature.
Do you mean that tcp_set_state tracepoint should be replaced with
sk_set_state tracepoint and move that tracepoint to
trace/events/sock.h ?
Yes, something like that.
It will avoid all of these protocol specific checks and weird
dependencies.
It will looks like these,
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(newsk, TCP_SYN_RECV);
else
newsk->sk_state = TCP_SYN_RECV;
if (sk->sk_protocol == IPPROTO_TCP)
__tcp_set_state(sk, TCP_CLOSE);
else
sk->sk_state = TCP_CLOSE;
if (sk->sk_protocol == IPPROTO_TCP)
tcp_state_store(sk, state);
else
sk_state_store(sk, state);
Some redundant code.
IMO, put these similar code into a wrapper is more nice.
I think this discussion and how ugly this is getting shows that
tracing the state transitions of a socket is perhaps not best as a TCP
specific feature.
Do you mean that tcp_set_state tracepoint should be replaced with
sk_set_state tracepoint and move that tracepoint to
trace/events/sock.h ?
Yes, something like that.
It will avoid all of these protocol specific checks and weird
dependencies.
That looks like a good idea.
I will try to reimplemnet it.
Thanks
Yafang