SUNRPC: Trace struct svc_sock lifetime events
Capture a timestamp and pointer address during the creation and destruction of struct svc_sock to record its lifetime. This helps to diagnose transport reference counting issues. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
d7900daea0
commit
c42bebca96
|
@ -2104,31 +2104,46 @@ DEFINE_SVC_DEFERRED_EVENT(drop);
|
||||||
DEFINE_SVC_DEFERRED_EVENT(queue);
|
DEFINE_SVC_DEFERRED_EVENT(queue);
|
||||||
DEFINE_SVC_DEFERRED_EVENT(recv);
|
DEFINE_SVC_DEFERRED_EVENT(recv);
|
||||||
|
|
||||||
TRACE_EVENT(svcsock_new_socket,
|
DECLARE_EVENT_CLASS(svcsock_lifetime_class,
|
||||||
TP_PROTO(
|
TP_PROTO(
|
||||||
|
const void *svsk,
|
||||||
const struct socket *socket
|
const struct socket *socket
|
||||||
),
|
),
|
||||||
|
TP_ARGS(svsk, socket),
|
||||||
TP_ARGS(socket),
|
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
|
__field(unsigned int, netns_ino)
|
||||||
|
__field(const void *, svsk)
|
||||||
|
__field(const void *, sk)
|
||||||
__field(unsigned long, type)
|
__field(unsigned long, type)
|
||||||
__field(unsigned long, family)
|
__field(unsigned long, family)
|
||||||
__field(bool, listener)
|
__field(unsigned long, state)
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
__entry->type = socket->type;
|
struct sock *sk = socket->sk;
|
||||||
__entry->family = socket->sk->sk_family;
|
|
||||||
__entry->listener = (socket->sk->sk_state == TCP_LISTEN);
|
|
||||||
),
|
|
||||||
|
|
||||||
TP_printk("type=%s family=%s%s",
|
__entry->netns_ino = sock_net(sk)->ns.inum;
|
||||||
show_socket_type(__entry->type),
|
__entry->svsk = svsk;
|
||||||
|
__entry->sk = sk;
|
||||||
|
__entry->type = socket->type;
|
||||||
|
__entry->family = sk->sk_family;
|
||||||
|
__entry->state = sk->sk_state;
|
||||||
|
),
|
||||||
|
TP_printk("svsk=%p type=%s family=%s%s",
|
||||||
|
__entry->svsk, show_socket_type(__entry->type),
|
||||||
rpc_show_address_family(__entry->family),
|
rpc_show_address_family(__entry->family),
|
||||||
__entry->listener ? " (listener)" : ""
|
__entry->state == TCP_LISTEN ? " (listener)" : ""
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
#define DEFINE_SVCSOCK_LIFETIME_EVENT(name) \
|
||||||
|
DEFINE_EVENT(svcsock_lifetime_class, name, \
|
||||||
|
TP_PROTO( \
|
||||||
|
const void *svsk, \
|
||||||
|
const struct socket *socket \
|
||||||
|
), \
|
||||||
|
TP_ARGS(svsk, socket))
|
||||||
|
|
||||||
|
DEFINE_SVCSOCK_LIFETIME_EVENT(svcsock_new);
|
||||||
|
DEFINE_SVCSOCK_LIFETIME_EVENT(svcsock_free);
|
||||||
|
|
||||||
TRACE_EVENT(svcsock_marker,
|
TRACE_EVENT(svcsock_marker,
|
||||||
TP_PROTO(
|
TP_PROTO(
|
||||||
|
|
|
@ -1470,7 +1470,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
|
||||||
else
|
else
|
||||||
svc_tcp_init(svsk, serv);
|
svc_tcp_init(svsk, serv);
|
||||||
|
|
||||||
trace_svcsock_new_socket(sock);
|
trace_svcsock_new(svsk, sock);
|
||||||
return svsk;
|
return svsk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1651,6 +1651,8 @@ static void svc_sock_free(struct svc_xprt *xprt)
|
||||||
struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
|
struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
|
||||||
struct socket *sock = svsk->sk_sock;
|
struct socket *sock = svsk->sk_sock;
|
||||||
|
|
||||||
|
trace_svcsock_free(svsk, sock);
|
||||||
|
|
||||||
tls_handshake_cancel(sock->sk);
|
tls_handshake_cancel(sock->sk);
|
||||||
if (sock->file)
|
if (sock->file)
|
||||||
sockfd_put(sock);
|
sockfd_put(sock);
|
||||||
|
|
Loading…
Reference in New Issue