mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-02 00:24:12 +08:00
2ca310fc41
When tracking sunrpc_task events in nfs client, the clnt pointer may be NULL. [ 139.269266] BUG: unable to handle kernel NULL pointer dereference at 0000000000000004 [ 139.269915] IP: [<ffffffffa026f216>] ftrace_raw_event_rpc_task_running+0x86/0xf0 [sunrpc] [ 139.269915] PGD 1d293067 PUD 1d294067 PMD 0 [ 139.269915] Oops: 0000 [#1] SMP [ 139.269915] Modules linked in: nfsv4 dns_resolver nfs lockd sunrpc fscache sg ppdev e1000 serio_raw pcspkr parport_pc parport i2c_piix4 i2c_core microcode xfs libcrc32c sd_mod sr_mod cdrom ata_generic crc_t10dif crct10dif_common pata_acpi ahci libahci ata_piix libata dm_mirror dm_region_hash dm_log dm_mod [ 139.269915] CPU: 0 PID: 59 Comm: kworker/0:2 Not tainted 3.10.0-84.el7.x86_64 #1 [ 139.269915] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 139.269915] Workqueue: rpciod rpc_async_schedule [sunrpc] [ 139.269915] task: ffff88001b598000 ti: ffff88001b632000 task.ti: ffff88001b632000 [ 139.269915] RIP: 0010:[<ffffffffa026f216>] [<ffffffffa026f216>] ftrace_raw_event_rpc_task_running+0x86/0xf0 [sunrpc] [ 139.269915] RSP: 0018:ffff88001b633d70 EFLAGS: 00010206 [ 139.269915] RAX: ffff88001dfc5338 RBX: ffff88001cc37a00 RCX: ffff88001dfc5334 [ 139.269915] RDX: ffff88001dfc5338 RSI: 0000000000000000 RDI: ffff88001dfc533c [ 139.269915] RBP: ffff88001b633db0 R08: 000000000000002c R09: 000000000000000a [ 139.269915] R10: 0000000000062180 R11: 00000020759fb9dc R12: ffffffffa0292c20 [ 139.269915] R13: ffff88001dfc5334 R14: 0000000000000000 R15: 0000000000000000 [ 139.269915] FS: 0000000000000000(0000) GS:ffff88001fc00000(0000) knlGS:0000000000000000 [ 139.269915] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 139.269915] CR2: 0000000000000004 CR3: 000000001d290000 CR4: 00000000000006f0 [ 139.269915] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 139.269915] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 139.269915] Stack: [ 139.269915] 000000001b633d98 0000000000000246 ffff88001df1dc00 ffff88001cc37a00 [ 139.269915] ffff88001bc35e60 0000000000000000 ffff88001ffa0a48 ffff88001bc35ee0 [ 139.269915] ffff88001b633e08 ffffffffa02704b5 0000000000010000 ffff88001cc37a70 [ 139.269915] Call Trace: [ 139.269915] [<ffffffffa02704b5>] __rpc_execute+0x1d5/0x400 [sunrpc] [ 139.269915] [<ffffffffa0270706>] rpc_async_schedule+0x26/0x30 [sunrpc] [ 139.269915] [<ffffffff8107867b>] process_one_work+0x17b/0x460 [ 139.269915] [<ffffffff8107942b>] worker_thread+0x11b/0x400 [ 139.269915] [<ffffffff81079310>] ? rescuer_thread+0x3e0/0x3e0 [ 139.269915] [<ffffffff8107fc80>] kthread+0xc0/0xd0 [ 139.269915] [<ffffffff8107fbc0>] ? kthread_create_on_node+0x110/0x110 [ 139.269915] [<ffffffff815d122c>] ret_from_fork+0x7c/0xb0 [ 139.269915] [<ffffffff8107fbc0>] ? kthread_create_on_node+0x110/0x110 [ 139.269915] Code: 4c 8b 45 c8 48 8d 7d d0 89 4d c4 41 89 c9 b9 28 00 00 00 e8 9d b4 e9 e0 48 85 c0 49 89 c5 74 a2 48 89 c7 e8 9d 3f e9 e0 48 89 c2 <41> 8b 46 04 48 8b 7d d0 4c 89 e9 4c 89 e6 89 42 0c 0f b7 83 d4 [ 139.269915] RIP [<ffffffffa026f216>] ftrace_raw_event_rpc_task_running+0x86/0xf0 [sunrpc] [ 139.269915] RSP <ffff88001b633d70> [ 139.269915] CR2: 0000000000000004 [ 140.946406] ---[ end trace ba486328b98d7622 ]--- Signed-off-by: Ditang Chen <chendt.fnst@cn.fujitsu.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
312 lines
7.5 KiB
C
312 lines
7.5 KiB
C
#undef TRACE_SYSTEM
|
|
#define TRACE_SYSTEM sunrpc
|
|
|
|
#if !defined(_TRACE_SUNRPC_H) || defined(TRACE_HEADER_MULTI_READ)
|
|
#define _TRACE_SUNRPC_H
|
|
|
|
#include <linux/sunrpc/sched.h>
|
|
#include <linux/sunrpc/clnt.h>
|
|
#include <net/tcp_states.h>
|
|
#include <linux/net.h>
|
|
#include <linux/tracepoint.h>
|
|
|
|
DECLARE_EVENT_CLASS(rpc_task_status,
|
|
|
|
TP_PROTO(struct rpc_task *task),
|
|
|
|
TP_ARGS(task),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, task_id)
|
|
__field(unsigned int, client_id)
|
|
__field(int, status)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->task_id = task->tk_pid;
|
|
__entry->client_id = task->tk_client->cl_clid;
|
|
__entry->status = task->tk_status;
|
|
),
|
|
|
|
TP_printk("task:%u@%u, status %d",
|
|
__entry->task_id, __entry->client_id,
|
|
__entry->status)
|
|
);
|
|
|
|
DEFINE_EVENT(rpc_task_status, rpc_call_status,
|
|
TP_PROTO(struct rpc_task *task),
|
|
|
|
TP_ARGS(task)
|
|
);
|
|
|
|
DEFINE_EVENT(rpc_task_status, rpc_bind_status,
|
|
TP_PROTO(struct rpc_task *task),
|
|
|
|
TP_ARGS(task)
|
|
);
|
|
|
|
TRACE_EVENT(rpc_connect_status,
|
|
TP_PROTO(struct rpc_task *task, int status),
|
|
|
|
TP_ARGS(task, status),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, task_id)
|
|
__field(unsigned int, client_id)
|
|
__field(int, status)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->task_id = task->tk_pid;
|
|
__entry->client_id = task->tk_client->cl_clid;
|
|
__entry->status = status;
|
|
),
|
|
|
|
TP_printk("task:%u@%u, status %d",
|
|
__entry->task_id, __entry->client_id,
|
|
__entry->status)
|
|
);
|
|
|
|
DECLARE_EVENT_CLASS(rpc_task_running,
|
|
|
|
TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const void *action),
|
|
|
|
TP_ARGS(clnt, task, action),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, task_id)
|
|
__field(unsigned int, client_id)
|
|
__field(const void *, action)
|
|
__field(unsigned long, runstate)
|
|
__field(int, status)
|
|
__field(unsigned short, flags)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->client_id = clnt ? clnt->cl_clid : -1;
|
|
__entry->task_id = task->tk_pid;
|
|
__entry->action = action;
|
|
__entry->runstate = task->tk_runstate;
|
|
__entry->status = task->tk_status;
|
|
__entry->flags = task->tk_flags;
|
|
),
|
|
|
|
TP_printk("task:%u@%d flags=%4.4x state=%4.4lx status=%d action=%pf",
|
|
__entry->task_id, __entry->client_id,
|
|
__entry->flags,
|
|
__entry->runstate,
|
|
__entry->status,
|
|
__entry->action
|
|
)
|
|
);
|
|
|
|
DEFINE_EVENT(rpc_task_running, rpc_task_begin,
|
|
|
|
TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const void *action),
|
|
|
|
TP_ARGS(clnt, task, action)
|
|
|
|
);
|
|
|
|
DEFINE_EVENT(rpc_task_running, rpc_task_run_action,
|
|
|
|
TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const void *action),
|
|
|
|
TP_ARGS(clnt, task, action)
|
|
|
|
);
|
|
|
|
DEFINE_EVENT(rpc_task_running, rpc_task_complete,
|
|
|
|
TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const void *action),
|
|
|
|
TP_ARGS(clnt, task, action)
|
|
|
|
);
|
|
|
|
DECLARE_EVENT_CLASS(rpc_task_queued,
|
|
|
|
TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const struct rpc_wait_queue *q),
|
|
|
|
TP_ARGS(clnt, task, q),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, task_id)
|
|
__field(unsigned int, client_id)
|
|
__field(unsigned long, timeout)
|
|
__field(unsigned long, runstate)
|
|
__field(int, status)
|
|
__field(unsigned short, flags)
|
|
__string(q_name, rpc_qname(q))
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->client_id = clnt->cl_clid;
|
|
__entry->task_id = task->tk_pid;
|
|
__entry->timeout = task->tk_timeout;
|
|
__entry->runstate = task->tk_runstate;
|
|
__entry->status = task->tk_status;
|
|
__entry->flags = task->tk_flags;
|
|
__assign_str(q_name, rpc_qname(q));
|
|
),
|
|
|
|
TP_printk("task:%u@%u flags=%4.4x state=%4.4lx status=%d timeout=%lu queue=%s",
|
|
__entry->task_id, __entry->client_id,
|
|
__entry->flags,
|
|
__entry->runstate,
|
|
__entry->status,
|
|
__entry->timeout,
|
|
__get_str(q_name)
|
|
)
|
|
);
|
|
|
|
DEFINE_EVENT(rpc_task_queued, rpc_task_sleep,
|
|
|
|
TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const struct rpc_wait_queue *q),
|
|
|
|
TP_ARGS(clnt, task, q)
|
|
|
|
);
|
|
|
|
DEFINE_EVENT(rpc_task_queued, rpc_task_wakeup,
|
|
|
|
TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const struct rpc_wait_queue *q),
|
|
|
|
TP_ARGS(clnt, task, q)
|
|
|
|
);
|
|
|
|
#define rpc_show_socket_state(state) \
|
|
__print_symbolic(state, \
|
|
{ SS_FREE, "FREE" }, \
|
|
{ SS_UNCONNECTED, "UNCONNECTED" }, \
|
|
{ SS_CONNECTING, "CONNECTING," }, \
|
|
{ SS_CONNECTED, "CONNECTED," }, \
|
|
{ SS_DISCONNECTING, "DISCONNECTING" })
|
|
|
|
#define rpc_show_sock_state(state) \
|
|
__print_symbolic(state, \
|
|
{ TCP_ESTABLISHED, "ESTABLISHED" }, \
|
|
{ TCP_SYN_SENT, "SYN_SENT" }, \
|
|
{ TCP_SYN_RECV, "SYN_RECV" }, \
|
|
{ TCP_FIN_WAIT1, "FIN_WAIT1" }, \
|
|
{ TCP_FIN_WAIT2, "FIN_WAIT2" }, \
|
|
{ TCP_TIME_WAIT, "TIME_WAIT" }, \
|
|
{ TCP_CLOSE, "CLOSE" }, \
|
|
{ TCP_CLOSE_WAIT, "CLOSE_WAIT" }, \
|
|
{ TCP_LAST_ACK, "LAST_ACK" }, \
|
|
{ TCP_LISTEN, "LISTEN" }, \
|
|
{ TCP_CLOSING, "CLOSING" })
|
|
|
|
DECLARE_EVENT_CLASS(xs_socket_event,
|
|
|
|
TP_PROTO(
|
|
struct rpc_xprt *xprt,
|
|
struct socket *socket
|
|
),
|
|
|
|
TP_ARGS(xprt, socket),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, socket_state)
|
|
__field(unsigned int, sock_state)
|
|
__field(unsigned long long, ino)
|
|
__string(dstaddr,
|
|
xprt->address_strings[RPC_DISPLAY_ADDR])
|
|
__string(dstport,
|
|
xprt->address_strings[RPC_DISPLAY_PORT])
|
|
),
|
|
|
|
TP_fast_assign(
|
|
struct inode *inode = SOCK_INODE(socket);
|
|
__entry->socket_state = socket->state;
|
|
__entry->sock_state = socket->sk->sk_state;
|
|
__entry->ino = (unsigned long long)inode->i_ino;
|
|
__assign_str(dstaddr,
|
|
xprt->address_strings[RPC_DISPLAY_ADDR]);
|
|
__assign_str(dstport,
|
|
xprt->address_strings[RPC_DISPLAY_PORT]);
|
|
),
|
|
|
|
TP_printk(
|
|
"socket:[%llu] dstaddr=%s/%s "
|
|
"state=%u (%s) sk_state=%u (%s)",
|
|
__entry->ino, __get_str(dstaddr), __get_str(dstport),
|
|
__entry->socket_state,
|
|
rpc_show_socket_state(__entry->socket_state),
|
|
__entry->sock_state,
|
|
rpc_show_sock_state(__entry->sock_state)
|
|
)
|
|
);
|
|
#define DEFINE_RPC_SOCKET_EVENT(name) \
|
|
DEFINE_EVENT(xs_socket_event, name, \
|
|
TP_PROTO( \
|
|
struct rpc_xprt *xprt, \
|
|
struct socket *socket \
|
|
), \
|
|
TP_ARGS(xprt, socket))
|
|
|
|
DECLARE_EVENT_CLASS(xs_socket_event_done,
|
|
|
|
TP_PROTO(
|
|
struct rpc_xprt *xprt,
|
|
struct socket *socket,
|
|
int error
|
|
),
|
|
|
|
TP_ARGS(xprt, socket, error),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(int, error)
|
|
__field(unsigned int, socket_state)
|
|
__field(unsigned int, sock_state)
|
|
__field(unsigned long long, ino)
|
|
__string(dstaddr,
|
|
xprt->address_strings[RPC_DISPLAY_ADDR])
|
|
__string(dstport,
|
|
xprt->address_strings[RPC_DISPLAY_PORT])
|
|
),
|
|
|
|
TP_fast_assign(
|
|
struct inode *inode = SOCK_INODE(socket);
|
|
__entry->socket_state = socket->state;
|
|
__entry->sock_state = socket->sk->sk_state;
|
|
__entry->ino = (unsigned long long)inode->i_ino;
|
|
__entry->error = error;
|
|
__assign_str(dstaddr,
|
|
xprt->address_strings[RPC_DISPLAY_ADDR]);
|
|
__assign_str(dstport,
|
|
xprt->address_strings[RPC_DISPLAY_PORT]);
|
|
),
|
|
|
|
TP_printk(
|
|
"error=%d socket:[%llu] dstaddr=%s/%s "
|
|
"state=%u (%s) sk_state=%u (%s)",
|
|
__entry->error,
|
|
__entry->ino, __get_str(dstaddr), __get_str(dstport),
|
|
__entry->socket_state,
|
|
rpc_show_socket_state(__entry->socket_state),
|
|
__entry->sock_state,
|
|
rpc_show_sock_state(__entry->sock_state)
|
|
)
|
|
);
|
|
#define DEFINE_RPC_SOCKET_EVENT_DONE(name) \
|
|
DEFINE_EVENT(xs_socket_event_done, name, \
|
|
TP_PROTO( \
|
|
struct rpc_xprt *xprt, \
|
|
struct socket *socket, \
|
|
int error \
|
|
), \
|
|
TP_ARGS(xprt, socket, error))
|
|
|
|
DEFINE_RPC_SOCKET_EVENT(rpc_socket_state_change);
|
|
DEFINE_RPC_SOCKET_EVENT_DONE(rpc_socket_connect);
|
|
DEFINE_RPC_SOCKET_EVENT_DONE(rpc_socket_error);
|
|
DEFINE_RPC_SOCKET_EVENT_DONE(rpc_socket_reset_connection);
|
|
DEFINE_RPC_SOCKET_EVENT(rpc_socket_close);
|
|
DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown);
|
|
|
|
#endif /* _TRACE_SUNRPC_H */
|
|
|
|
#include <trace/define_trace.h>
|