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

Commit b4b9d2cc authored by Jeff Layton's avatar Jeff Layton Committed by Trond Myklebust
Browse files

sunrpc: add debugfs file for displaying client rpc_task queue



It's possible to get a dump of the RPC task queue by writing a value to
/proc/sys/sunrpc/rpc_debug. If you write any value to that file, you get
a dump of the RPC client task list into the log buffer. This is a rather
inconvenient interface however, and makes it hard to get immediate info
about the task queue.

Add a new directory hierarchy under debugfs:

    sunrpc/
        rpc_clnt/
            <clientid>/

Within each clientid directory we create a new "tasks" file that will
dump info similar to what shows up in the log buffer, but with a few
small differences -- we avoid printing raw kernel addresses in favor of
symbolic names and the XID is also displayed.

Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent ea526413
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -63,6 +63,9 @@ struct rpc_clnt {
	struct rpc_rtt		cl_rtt_default;
	struct rpc_timeout	cl_timeout_default;
	const struct rpc_program *cl_program;
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
	struct dentry		*cl_debugfs;	/* debugfs directory */
#endif
};

/*
@@ -176,5 +179,6 @@ size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
const char	*rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
int		rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t);

const char *rpc_proc_name(const struct rpc_task *task);
#endif /* __KERNEL__ */
#endif /* _LINUX_SUNRPC_CLNT_H */
+31 −0
Original line number Diff line number Diff line
@@ -53,9 +53,40 @@ extern unsigned int nlm_debug;
/*
 * Sysctl interface for RPC debugging
 */

struct rpc_clnt;

#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
void		rpc_register_sysctl(void);
void		rpc_unregister_sysctl(void);
int		sunrpc_debugfs_init(void);
void		sunrpc_debugfs_exit(void);
int		rpc_clnt_debugfs_register(struct rpc_clnt *);
void		rpc_clnt_debugfs_unregister(struct rpc_clnt *);
#else
static inline int
sunrpc_debugfs_init(void)
{
	return 0;
}

static inline void
sunrpc_debugfs_exit(void)
{
	return;
}

static inline int
rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
{
	return 0;
}

static inline void
rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
{
	return;
}
#endif

#endif /* _LINUX_SUNRPC_DEBUG_H_ */
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ config RPCSEC_GSS_KRB5
config SUNRPC_DEBUG
	bool "RPC: Enable dprintk debugging"
	depends on SUNRPC && SYSCTL
	select DEBUG_FS
	help
	  This option enables a sysctl-based debugging interface
	  that is be used by the 'rpcdebug' utility to turn on or off
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
	    addr.o rpcb_clnt.o timer.o xdr.o \
	    sunrpc_syms.o cache.o rpc_pipe.o \
	    svc_xprt.o
sunrpc-$(CONFIG_SUNRPC_DEBUG) += debugfs.o
sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o
sunrpc-$(CONFIG_PROC_FS) += stats.o
sunrpc-$(CONFIG_SYSCTL) += sysctl.o
+9 −1
Original line number Diff line number Diff line
@@ -305,6 +305,10 @@ static int rpc_client_register(struct rpc_clnt *clnt,
	struct super_block *pipefs_sb;
	int err;

	err = rpc_clnt_debugfs_register(clnt);
	if (err)
		return err;

	pipefs_sb = rpc_get_sb_net(net);
	if (pipefs_sb) {
		err = rpc_setup_pipedir(pipefs_sb, clnt);
@@ -331,6 +335,7 @@ err_auth:
out:
	if (pipefs_sb)
		rpc_put_sb_net(net);
	rpc_clnt_debugfs_unregister(clnt);
	return err;
}

@@ -670,6 +675,7 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,

	rpc_unregister_client(clnt);
	__rpc_clnt_remove_pipedir(clnt);
	rpc_clnt_debugfs_unregister(clnt);

	/*
	 * A new transport was created.  "clnt" therefore
@@ -771,6 +777,7 @@ rpc_free_client(struct rpc_clnt *clnt)
			rcu_dereference(clnt->cl_xprt)->servername);
	if (clnt->cl_parent != clnt)
		parent = clnt->cl_parent;
	rpc_clnt_debugfs_unregister(clnt);
	rpc_clnt_remove_pipedir(clnt);
	rpc_unregister_client(clnt);
	rpc_free_iostats(clnt->cl_metrics);
@@ -1397,7 +1404,8 @@ rpc_restart_call(struct rpc_task *task)
EXPORT_SYMBOL_GPL(rpc_restart_call);

#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
static const char *rpc_proc_name(const struct rpc_task *task)
const char
*rpc_proc_name(const struct rpc_task *task)
{
	const struct rpc_procinfo *proc = task->tk_msg.rpc_proc;

Loading