Linux NFS development
 help / color / mirror / Atom feed
* [PATCH] sunrpc: add debugfs file for displaying client rpc_task queue
@ 2014-10-28 18:24 Jeff Layton
  2014-10-28 18:30 ` Jeff Layton
  2014-11-25 19:00 ` [PATCH v2 0/4] " Jeff Layton
  0 siblings, 2 replies; 19+ messages in thread
From: Jeff Layton @ 2014-10-28 18:24 UTC (permalink / raw)
  To: trond.myklebust; +Cc: linux-nfs

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 file under debugfs that shows similar info. There are some
small differences -- we avoid printing raw kernel addresses in favor of
symbolic names and the XID is also displayed.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
---
 include/linux/sunrpc/clnt.h  |   1 +
 include/linux/sunrpc/debug.h |  13 ++++
 net/sunrpc/Kconfig           |   1 +
 net/sunrpc/Makefile          |   1 +
 net/sunrpc/clnt.c            |   3 +-
 net/sunrpc/debugfs.c         | 153 +++++++++++++++++++++++++++++++++++++++++++
 net/sunrpc/sunrpc_syms.c     |   8 +++
 7 files changed, 179 insertions(+), 1 deletion(-)
 create mode 100644 net/sunrpc/debugfs.c

diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 70736b98c721..265d40bd3109 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -176,5 +176,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 */
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 9385bd74c860..7c1ef9530087 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -68,6 +68,19 @@ extern unsigned int		nlm_debug;
 #ifdef RPC_DEBUG
 void		rpc_register_sysctl(void);
 void		rpc_unregister_sysctl(void);
+int		sunrpc_debugfs_init(void);
+void		sunrpc_debugfs_exit(void);
+#else
+static inline int
+sunrpc_debugfs_init(void)
+{
+	return 0;
+}
+static inline void
+sunrpc_debugfs_exit(void)
+{
+	return;
+}
 #endif
 
 #endif /* _LINUX_SUNRPC_DEBUG_H_ */
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index 0754d0f466d2..fb78117b896c 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -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
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index e5a7a1cac8f3..15e6f6c23c5d 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -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
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 9acd6ce88db7..5b2e2d3d37c1 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1397,7 +1397,8 @@ rpc_restart_call(struct rpc_task *task)
 EXPORT_SYMBOL_GPL(rpc_restart_call);
 
 #ifdef RPC_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;
 
diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
new file mode 100644
index 000000000000..48769338172e
--- /dev/null
+++ b/net/sunrpc/debugfs.c
@@ -0,0 +1,153 @@
+/**
+ * debugfs interface for sunrpc
+ *
+ * (c) 2014 Jeff Layton <jlayton@primarydata.com>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/clnt.h>
+#include "netns.h"
+
+static struct dentry *topdir;
+
+static int
+tasks_show(struct seq_file *f, void *v)
+{
+	u32 xid = 0;
+	struct rpc_task *task = v;
+	struct rpc_clnt *clnt = task->tk_client;
+	const char *rpc_waitq = "none";
+
+	if (RPC_IS_QUEUED(task))
+		rpc_waitq = rpc_qname(task->tk_waitqueue);
+
+	if (task->tk_rqstp)
+		xid = be32_to_cpu(task->tk_rqstp->rq_xid);
+
+	seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
+		task->tk_pid, task->tk_flags, task->tk_status,
+		clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
+		clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
+		task->tk_action, rpc_waitq);
+	return 0;
+}
+
+static void *
+tasks_start(struct seq_file *f, loff_t *ppos)
+	__acquires(&sn->rpc_client_lock)
+	__acquires(&clnt->cl_lock)
+{
+	loff_t *p = f->private, pos = *ppos;
+	struct rpc_clnt *clnt;
+	struct rpc_task *task;
+	struct sunrpc_net *sn = net_generic(current->nsproxy->net_ns,
+						sunrpc_net_id);
+
+	*p = pos + 1;
+	spin_lock(&sn->rpc_client_lock);
+	list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
+		spin_lock(&clnt->cl_lock);
+		list_for_each_entry(task, &clnt->cl_tasks, tk_task)
+			if (pos-- == 0)
+				return task;
+		spin_unlock(&clnt->cl_lock);
+	}
+	return NULL;
+}
+
+static void *
+tasks_next(struct seq_file *f, void *v, loff_t *pos)
+	__releases(&clnt->cl_lock)
+	__acquires(&clnt->cl_lock)
+{
+	loff_t *p = f->private;
+	struct rpc_task *task = v;
+	struct rpc_clnt *clnt = task->tk_client;
+	struct list_head *next = task->tk_task.next;
+	struct sunrpc_net *sn = net_generic(current->nsproxy->net_ns,
+						sunrpc_net_id);
+
+	++*p;
+	++*pos;
+
+	/* If there's another task on list, return it */
+	if (next != &clnt->cl_tasks)
+		return list_entry(next, struct rpc_task, tk_task);
+
+	/* We're finished with this client, move on */
+	spin_unlock(&clnt->cl_lock);
+next_client:
+	next = clnt->cl_clients.next;
+	if (next == &sn->all_clients)
+		return NULL;
+
+	clnt = list_entry(next, struct rpc_clnt, cl_clients);
+	if (list_empty(&clnt->cl_tasks))
+		goto next_client;
+	spin_lock(&clnt->cl_lock);
+	if (list_empty(&clnt->cl_tasks)) {
+		spin_unlock(&clnt->cl_lock);
+		goto next_client;
+	}
+	return list_first_entry(&clnt->cl_tasks, struct rpc_task, tk_task);
+}
+
+static void
+tasks_stop(struct seq_file *f, void *v)
+	__releases(&sn->rpc_client_lock)
+	__releases(&clnt->cl_lock)
+{
+	struct rpc_task *task = v;
+	struct rpc_clnt *clnt;
+	struct sunrpc_net *sn = net_generic(current->nsproxy->net_ns,
+						sunrpc_net_id);
+
+	if (v) {
+		clnt = task->tk_client;
+		spin_unlock(&clnt->cl_lock);
+	}
+	spin_unlock(&sn->rpc_client_lock);
+}
+
+static const struct seq_operations tasks_seq_operations = {
+	.start	= tasks_start,
+	.next	= tasks_next,
+	.stop	= tasks_stop,
+	.show	= tasks_show,
+};
+
+static int tasks_open(struct inode *inode, struct file *filp)
+{
+	return seq_open_private(filp, &tasks_seq_operations,
+				sizeof(loff_t));
+}
+
+static const struct file_operations tasks_fops = {
+	.owner		= THIS_MODULE,
+	.open		= tasks_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release_private,
+};
+
+void __exit
+sunrpc_debugfs_exit(void)
+{
+	debugfs_remove_recursive(topdir);
+}
+
+int __init
+sunrpc_debugfs_init(void)
+{
+	topdir = debugfs_create_dir("sunrpc", NULL);
+	if (!topdir)
+		return -ENOMEM;
+
+	if (!debugfs_create_file("client_tasks", S_IFREG | S_IRUSR, topdir,
+					NULL, &tasks_fops)) {
+		debugfs_remove_recursive(topdir);
+		return -ENOMEM;
+	}
+	return 0;
+}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index cd30120de9e4..32583adf3477 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -97,6 +97,11 @@ init_sunrpc(void)
 	err = register_rpc_pipefs();
 	if (err)
 		goto out4;
+
+	err = sunrpc_debugfs_init();
+	if (err)
+		goto out5;
+
 #ifdef RPC_DEBUG
 	rpc_register_sysctl();
 #endif
@@ -104,6 +109,8 @@ init_sunrpc(void)
 	init_socket_xprt();	/* clnt sock transport */
 	return 0;
 
+out5:
+	unregister_rpc_pipefs();
 out4:
 	unregister_pernet_subsys(&sunrpc_net_ops);
 out3:
@@ -120,6 +127,7 @@ cleanup_sunrpc(void)
 	rpcauth_remove_module();
 	cleanup_socket_xprt();
 	svc_cleanup_xprt_sock();
+	sunrpc_debugfs_exit();
 	unregister_rpc_pipefs();
 	rpc_destroy_mempool();
 	unregister_pernet_subsys(&sunrpc_net_ops);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH] sunrpc: add debugfs file for displaying client rpc_task queue
  2014-10-28 18:24 [PATCH] sunrpc: add debugfs file for displaying client rpc_task queue Jeff Layton
@ 2014-10-28 18:30 ` Jeff Layton
  2014-11-24 19:20   ` Trond Myklebust
  2014-11-25 19:00 ` [PATCH v2 0/4] " Jeff Layton
  1 sibling, 1 reply; 19+ messages in thread
From: Jeff Layton @ 2014-10-28 18:30 UTC (permalink / raw)
  To: trond.myklebust; +Cc: linux-nfs

On Tue, 28 Oct 2014 14:24:55 -0400
Jeff Layton <jlayton@primarydata.com> wrote:

> 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 file under debugfs that shows similar info. There are some
> small differences -- we avoid printing raw kernel addresses in favor of
> symbolic names and the XID is also displayed.
> 
> Signed-off-by: Jeff Layton <jlayton@primarydata.com>
> ---
>  include/linux/sunrpc/clnt.h  |   1 +
>  include/linux/sunrpc/debug.h |  13 ++++
>  net/sunrpc/Kconfig           |   1 +
>  net/sunrpc/Makefile          |   1 +
>  net/sunrpc/clnt.c            |   3 +-
>  net/sunrpc/debugfs.c         | 153 +++++++++++++++++++++++++++++++++++++++++++
>  net/sunrpc/sunrpc_syms.c     |   8 +++
>  7 files changed, 179 insertions(+), 1 deletion(-)
>  create mode 100644 net/sunrpc/debugfs.c
> 
> diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
> index 70736b98c721..265d40bd3109 100644
> --- a/include/linux/sunrpc/clnt.h
> +++ b/include/linux/sunrpc/clnt.h
> @@ -176,5 +176,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 */
> diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
> index 9385bd74c860..7c1ef9530087 100644
> --- a/include/linux/sunrpc/debug.h
> +++ b/include/linux/sunrpc/debug.h
> @@ -68,6 +68,19 @@ extern unsigned int		nlm_debug;
>  #ifdef RPC_DEBUG
>  void		rpc_register_sysctl(void);
>  void		rpc_unregister_sysctl(void);
> +int		sunrpc_debugfs_init(void);
> +void		sunrpc_debugfs_exit(void);
> +#else
> +static inline int
> +sunrpc_debugfs_init(void)
> +{
> +	return 0;
> +}
> +static inline void
> +sunrpc_debugfs_exit(void)
> +{
> +	return;
> +}
>  #endif
>  
>  #endif /* _LINUX_SUNRPC_DEBUG_H_ */
> diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
> index 0754d0f466d2..fb78117b896c 100644
> --- a/net/sunrpc/Kconfig
> +++ b/net/sunrpc/Kconfig
> @@ -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
> diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
> index e5a7a1cac8f3..15e6f6c23c5d 100644
> --- a/net/sunrpc/Makefile
> +++ b/net/sunrpc/Makefile
> @@ -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
> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
> index 9acd6ce88db7..5b2e2d3d37c1 100644
> --- a/net/sunrpc/clnt.c
> +++ b/net/sunrpc/clnt.c
> @@ -1397,7 +1397,8 @@ rpc_restart_call(struct rpc_task *task)
>  EXPORT_SYMBOL_GPL(rpc_restart_call);
>  
>  #ifdef RPC_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;
>  
> diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
> new file mode 100644
> index 000000000000..48769338172e
> --- /dev/null
> +++ b/net/sunrpc/debugfs.c
> @@ -0,0 +1,153 @@
> +/**
> + * debugfs interface for sunrpc
> + *
> + * (c) 2014 Jeff Layton <jlayton@primarydata.com>
> + */
> +
> +#include <linux/debugfs.h>
> +#include <linux/sunrpc/sched.h>
> +#include <linux/sunrpc/clnt.h>
> +#include "netns.h"
> +
> +static struct dentry *topdir;
> +
> +static int
> +tasks_show(struct seq_file *f, void *v)
> +{
> +	u32 xid = 0;
> +	struct rpc_task *task = v;
> +	struct rpc_clnt *clnt = task->tk_client;
> +	const char *rpc_waitq = "none";
> +
> +	if (RPC_IS_QUEUED(task))
> +		rpc_waitq = rpc_qname(task->tk_waitqueue);
> +
> +	if (task->tk_rqstp)
> +		xid = be32_to_cpu(task->tk_rqstp->rq_xid);
> +
> +	seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
> +		task->tk_pid, task->tk_flags, task->tk_status,
> +		clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
> +		clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
> +		task->tk_action, rpc_waitq);
> +	return 0;
> +}
> +
> +static void *
> +tasks_start(struct seq_file *f, loff_t *ppos)
> +	__acquires(&sn->rpc_client_lock)
> +	__acquires(&clnt->cl_lock)
> +{
> +	loff_t *p = f->private, pos = *ppos;
> +	struct rpc_clnt *clnt;
> +	struct rpc_task *task;
> +	struct sunrpc_net *sn = net_generic(current->nsproxy->net_ns,
> +						sunrpc_net_id);
> +
> +	*p = pos + 1;
> +	spin_lock(&sn->rpc_client_lock);
> +	list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
> +		spin_lock(&clnt->cl_lock);
> +		list_for_each_entry(task, &clnt->cl_tasks, tk_task)
> +			if (pos-- == 0)
> +				return task;
> +		spin_unlock(&clnt->cl_lock);
> +	}
> +	return NULL;
> +}
> +
> +static void *
> +tasks_next(struct seq_file *f, void *v, loff_t *pos)
> +	__releases(&clnt->cl_lock)
> +	__acquires(&clnt->cl_lock)
> +{
> +	loff_t *p = f->private;
> +	struct rpc_task *task = v;
> +	struct rpc_clnt *clnt = task->tk_client;
> +	struct list_head *next = task->tk_task.next;
> +	struct sunrpc_net *sn = net_generic(current->nsproxy->net_ns,
> +						sunrpc_net_id);
> +
> +	++*p;
> +	++*pos;
> +
> +	/* If there's another task on list, return it */
> +	if (next != &clnt->cl_tasks)
> +		return list_entry(next, struct rpc_task, tk_task);
> +
> +	/* We're finished with this client, move on */
> +	spin_unlock(&clnt->cl_lock);
> +next_client:
> +	next = clnt->cl_clients.next;
> +	if (next == &sn->all_clients)
> +		return NULL;
> +
> +	clnt = list_entry(next, struct rpc_clnt, cl_clients);
> +	if (list_empty(&clnt->cl_tasks))
> +		goto next_client;
> +	spin_lock(&clnt->cl_lock);
> +	if (list_empty(&clnt->cl_tasks)) {
> +		spin_unlock(&clnt->cl_lock);
> +		goto next_client;
> +	}
> +	return list_first_entry(&clnt->cl_tasks, struct rpc_task, tk_task);
> +}
> +
> +static void
> +tasks_stop(struct seq_file *f, void *v)
> +	__releases(&sn->rpc_client_lock)
> +	__releases(&clnt->cl_lock)
> +{
> +	struct rpc_task *task = v;
> +	struct rpc_clnt *clnt;
> +	struct sunrpc_net *sn = net_generic(current->nsproxy->net_ns,
> +						sunrpc_net_id);
> +
> +	if (v) {
> +		clnt = task->tk_client;
> +		spin_unlock(&clnt->cl_lock);
> +	}

Full disclosure here...

sparse complains about this patch:

net/sunrpc/debugfs.c:36:13: warning: context imbalance in 'tasks_start' - different lock contexts for basic block
net/sunrpc/debugfs.c:59:13: warning: context imbalance in 'tasks_next' - different lock contexts for basic block
net/sunrpc/debugfs.c:110:20: warning: context imbalance in 'tasks_stop' - different lock contexts for basic block


The __acquires/__releases annotations don't help in this case since
tasks_start and tasks_next can conditionally return with the cl_lock
held or not.

If tasks_start/_next return a valid object, then the lock will be held.
If it returns NULL then it won't be. There should be no actual lock
imbalances however.

> +	spin_unlock(&sn->rpc_client_lock);
> +}
> +
> +static const struct seq_operations tasks_seq_operations = {
> +	.start	= tasks_start,
> +	.next	= tasks_next,
> +	.stop	= tasks_stop,
> +	.show	= tasks_show,
> +};
> +
> +static int tasks_open(struct inode *inode, struct file *filp)
> +{
> +	return seq_open_private(filp, &tasks_seq_operations,
> +				sizeof(loff_t));
> +}
> +
> +static const struct file_operations tasks_fops = {
> +	.owner		= THIS_MODULE,
> +	.open		= tasks_open,
> +	.read		= seq_read,
> +	.llseek		= seq_lseek,
> +	.release	= seq_release_private,
> +};
> +
> +void __exit
> +sunrpc_debugfs_exit(void)
> +{
> +	debugfs_remove_recursive(topdir);
> +}
> +
> +int __init
> +sunrpc_debugfs_init(void)
> +{
> +	topdir = debugfs_create_dir("sunrpc", NULL);
> +	if (!topdir)
> +		return -ENOMEM;
> +
> +	if (!debugfs_create_file("client_tasks", S_IFREG | S_IRUSR, topdir,
> +					NULL, &tasks_fops)) {
> +		debugfs_remove_recursive(topdir);
> +		return -ENOMEM;
> +	}
> +	return 0;
> +}
> diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
> index cd30120de9e4..32583adf3477 100644
> --- a/net/sunrpc/sunrpc_syms.c
> +++ b/net/sunrpc/sunrpc_syms.c
> @@ -97,6 +97,11 @@ init_sunrpc(void)
>  	err = register_rpc_pipefs();
>  	if (err)
>  		goto out4;
> +
> +	err = sunrpc_debugfs_init();
> +	if (err)
> +		goto out5;
> +
>  #ifdef RPC_DEBUG
>  	rpc_register_sysctl();
>  #endif
> @@ -104,6 +109,8 @@ init_sunrpc(void)
>  	init_socket_xprt();	/* clnt sock transport */
>  	return 0;
>  
> +out5:
> +	unregister_rpc_pipefs();
>  out4:
>  	unregister_pernet_subsys(&sunrpc_net_ops);
>  out3:
> @@ -120,6 +127,7 @@ cleanup_sunrpc(void)
>  	rpcauth_remove_module();
>  	cleanup_socket_xprt();
>  	svc_cleanup_xprt_sock();
> +	sunrpc_debugfs_exit();
>  	unregister_rpc_pipefs();
>  	rpc_destroy_mempool();
>  	unregister_pernet_subsys(&sunrpc_net_ops);


-- 
Jeff Layton <jlayton@primarydata.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] sunrpc: add debugfs file for displaying client rpc_task queue
  2014-10-28 18:30 ` Jeff Layton
@ 2014-11-24 19:20   ` Trond Myklebust
  2014-11-24 21:35     ` Jeff Layton
  0 siblings, 1 reply; 19+ messages in thread
From: Trond Myklebust @ 2014-11-24 19:20 UTC (permalink / raw)
  To: Jeff Layton; +Cc: Linux NFS Mailing List

On Tue, Oct 28, 2014 at 2:30 PM, Jeff Layton
<jeff.layton@primarydata.com> wrote:
> On Tue, 28 Oct 2014 14:24:55 -0400
> Jeff Layton <jlayton@primarydata.com> wrote:
>
>> 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 file under debugfs that shows similar info. There are some
>> small differences -- we avoid printing raw kernel addresses in favor of
>> symbolic names and the XID is also displayed.
>>
>> Signed-off-by: Jeff Layton <jlayton@primarydata.com>
>> ---
>>  include/linux/sunrpc/clnt.h  |   1 +
>>  include/linux/sunrpc/debug.h |  13 ++++
>>  net/sunrpc/Kconfig           |   1 +
>>  net/sunrpc/Makefile          |   1 +
>>  net/sunrpc/clnt.c            |   3 +-
>>  net/sunrpc/debugfs.c         | 153 +++++++++++++++++++++++++++++++++++++++++++
>>  net/sunrpc/sunrpc_syms.c     |   8 +++
>>  7 files changed, 179 insertions(+), 1 deletion(-)
>>  create mode 100644 net/sunrpc/debugfs.c
>>
>> diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
>> index 70736b98c721..265d40bd3109 100644
>> --- a/include/linux/sunrpc/clnt.h
>> +++ b/include/linux/sunrpc/clnt.h
>> @@ -176,5 +176,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 */
>> diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
>> index 9385bd74c860..7c1ef9530087 100644
>> --- a/include/linux/sunrpc/debug.h
>> +++ b/include/linux/sunrpc/debug.h
>> @@ -68,6 +68,19 @@ extern unsigned int                nlm_debug;
>>  #ifdef RPC_DEBUG
>>  void         rpc_register_sysctl(void);
>>  void         rpc_unregister_sysctl(void);
>> +int          sunrpc_debugfs_init(void);
>> +void         sunrpc_debugfs_exit(void);
>> +#else
>> +static inline int
>> +sunrpc_debugfs_init(void)
>> +{
>> +     return 0;
>> +}
>> +static inline void
>> +sunrpc_debugfs_exit(void)
>> +{
>> +     return;
>> +}
>>  #endif
>>
>>  #endif /* _LINUX_SUNRPC_DEBUG_H_ */
>> diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
>> index 0754d0f466d2..fb78117b896c 100644
>> --- a/net/sunrpc/Kconfig
>> +++ b/net/sunrpc/Kconfig
>> @@ -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
>> diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
>> index e5a7a1cac8f3..15e6f6c23c5d 100644
>> --- a/net/sunrpc/Makefile
>> +++ b/net/sunrpc/Makefile
>> @@ -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
>> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
>> index 9acd6ce88db7..5b2e2d3d37c1 100644
>> --- a/net/sunrpc/clnt.c
>> +++ b/net/sunrpc/clnt.c
>> @@ -1397,7 +1397,8 @@ rpc_restart_call(struct rpc_task *task)
>>  EXPORT_SYMBOL_GPL(rpc_restart_call);
>>
>>  #ifdef RPC_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;
>>
>> diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
>> new file mode 100644
>> index 000000000000..48769338172e
>> --- /dev/null
>> +++ b/net/sunrpc/debugfs.c
>> @@ -0,0 +1,153 @@
>> +/**
>> + * debugfs interface for sunrpc
>> + *
>> + * (c) 2014 Jeff Layton <jlayton@primarydata.com>
>> + */
>> +
>> +#include <linux/debugfs.h>
>> +#include <linux/sunrpc/sched.h>
>> +#include <linux/sunrpc/clnt.h>
>> +#include "netns.h"
>> +
>> +static struct dentry *topdir;
>> +
>> +static int
>> +tasks_show(struct seq_file *f, void *v)
>> +{
>> +     u32 xid = 0;
>> +     struct rpc_task *task = v;
>> +     struct rpc_clnt *clnt = task->tk_client;
>> +     const char *rpc_waitq = "none";
>> +
>> +     if (RPC_IS_QUEUED(task))
>> +             rpc_waitq = rpc_qname(task->tk_waitqueue);
>> +
>> +     if (task->tk_rqstp)
>> +             xid = be32_to_cpu(task->tk_rqstp->rq_xid);
>> +
>> +     seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
>> +             task->tk_pid, task->tk_flags, task->tk_status,
>> +             clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
>> +             clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
>> +             task->tk_action, rpc_waitq);
>> +     return 0;
>> +}
>> +
>> +static void *
>> +tasks_start(struct seq_file *f, loff_t *ppos)
>> +     __acquires(&sn->rpc_client_lock)
>> +     __acquires(&clnt->cl_lock)
>> +{
>> +     loff_t *p = f->private, pos = *ppos;
>> +     struct rpc_clnt *clnt;
>> +     struct rpc_task *task;
>> +     struct sunrpc_net *sn = net_generic(current->nsproxy->net_ns,
>> +                                             sunrpc_net_id);
>> +
>> +     *p = pos + 1;
>> +     spin_lock(&sn->rpc_client_lock);
>> +     list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
>> +             spin_lock(&clnt->cl_lock);
>> +             list_for_each_entry(task, &clnt->cl_tasks, tk_task)
>> +                     if (pos-- == 0)
>> +                             return task;
>> +             spin_unlock(&clnt->cl_lock);
>> +     }
>> +     return NULL;
>> +}

Instead of having a single pseudofile that iterates through all
rpc_clients and all rpc_tasks, should we perhaps have a hierarchy of
subdirectories?
I'm thinking we might want a directory per rpc_client, each containing
a pseudo-file that iterates through all rpc_tasks for that rpc_client
only. The reason for doing so would be so that we can add pseudofiles
to display more per-rpc_client debugging info, such as cl_nodename,
cl_program->name, cl_prog, cl_vers. Maybe also with a symlink to
another subdirectory that displays per-xprt debugging information?

i.e. a hierarchy of the form

debugfs/
    rpc_clients/
         1/
            cl_tasks
            cl_xprt->../../rpc_xprt/1
.....
         2/
            cl_tasks
            cl_xprt->../../rpc_xprt/1
.....
    rpc_xprt/
         1/
            servername
.....

-- 
Trond Myklebust

Linux NFS client maintainer, PrimaryData

trond.myklebust@primarydata.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] sunrpc: add debugfs file for displaying client rpc_task queue
  2014-11-24 19:20   ` Trond Myklebust
@ 2014-11-24 21:35     ` Jeff Layton
  0 siblings, 0 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-24 21:35 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: Jeff Layton, Linux NFS Mailing List

On Mon, 24 Nov 2014 14:20:25 -0500
Trond Myklebust <trond.myklebust@primarydata.com> wrote:

> On Tue, Oct 28, 2014 at 2:30 PM, Jeff Layton
> <jeff.layton@primarydata.com> wrote:
> > On Tue, 28 Oct 2014 14:24:55 -0400
> > Jeff Layton <jlayton@primarydata.com> wrote:
> >
> >> 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 file under debugfs that shows similar info. There are some
> >> small differences -- we avoid printing raw kernel addresses in favor of
> >> symbolic names and the XID is also displayed.
> >>
> >> Signed-off-by: Jeff Layton <jlayton@primarydata.com>
> >> ---
> >>  include/linux/sunrpc/clnt.h  |   1 +
> >>  include/linux/sunrpc/debug.h |  13 ++++
> >>  net/sunrpc/Kconfig           |   1 +
> >>  net/sunrpc/Makefile          |   1 +
> >>  net/sunrpc/clnt.c            |   3 +-
> >>  net/sunrpc/debugfs.c         | 153 +++++++++++++++++++++++++++++++++++++++++++
> >>  net/sunrpc/sunrpc_syms.c     |   8 +++
> >>  7 files changed, 179 insertions(+), 1 deletion(-)
> >>  create mode 100644 net/sunrpc/debugfs.c
> >>
> >> diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
> >> index 70736b98c721..265d40bd3109 100644
> >> --- a/include/linux/sunrpc/clnt.h
> >> +++ b/include/linux/sunrpc/clnt.h
> >> @@ -176,5 +176,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 */
> >> diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
> >> index 9385bd74c860..7c1ef9530087 100644
> >> --- a/include/linux/sunrpc/debug.h
> >> +++ b/include/linux/sunrpc/debug.h
> >> @@ -68,6 +68,19 @@ extern unsigned int                nlm_debug;
> >>  #ifdef RPC_DEBUG
> >>  void         rpc_register_sysctl(void);
> >>  void         rpc_unregister_sysctl(void);
> >> +int          sunrpc_debugfs_init(void);
> >> +void         sunrpc_debugfs_exit(void);
> >> +#else
> >> +static inline int
> >> +sunrpc_debugfs_init(void)
> >> +{
> >> +     return 0;
> >> +}
> >> +static inline void
> >> +sunrpc_debugfs_exit(void)
> >> +{
> >> +     return;
> >> +}
> >>  #endif
> >>
> >>  #endif /* _LINUX_SUNRPC_DEBUG_H_ */
> >> diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
> >> index 0754d0f466d2..fb78117b896c 100644
> >> --- a/net/sunrpc/Kconfig
> >> +++ b/net/sunrpc/Kconfig
> >> @@ -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
> >> diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
> >> index e5a7a1cac8f3..15e6f6c23c5d 100644
> >> --- a/net/sunrpc/Makefile
> >> +++ b/net/sunrpc/Makefile
> >> @@ -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
> >> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
> >> index 9acd6ce88db7..5b2e2d3d37c1 100644
> >> --- a/net/sunrpc/clnt.c
> >> +++ b/net/sunrpc/clnt.c
> >> @@ -1397,7 +1397,8 @@ rpc_restart_call(struct rpc_task *task)
> >>  EXPORT_SYMBOL_GPL(rpc_restart_call);
> >>
> >>  #ifdef RPC_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;
> >>
> >> diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
> >> new file mode 100644
> >> index 000000000000..48769338172e
> >> --- /dev/null
> >> +++ b/net/sunrpc/debugfs.c
> >> @@ -0,0 +1,153 @@
> >> +/**
> >> + * debugfs interface for sunrpc
> >> + *
> >> + * (c) 2014 Jeff Layton <jlayton@primarydata.com>
> >> + */
> >> +
> >> +#include <linux/debugfs.h>
> >> +#include <linux/sunrpc/sched.h>
> >> +#include <linux/sunrpc/clnt.h>
> >> +#include "netns.h"
> >> +
> >> +static struct dentry *topdir;
> >> +
> >> +static int
> >> +tasks_show(struct seq_file *f, void *v)
> >> +{
> >> +     u32 xid = 0;
> >> +     struct rpc_task *task = v;
> >> +     struct rpc_clnt *clnt = task->tk_client;
> >> +     const char *rpc_waitq = "none";
> >> +
> >> +     if (RPC_IS_QUEUED(task))
> >> +             rpc_waitq = rpc_qname(task->tk_waitqueue);
> >> +
> >> +     if (task->tk_rqstp)
> >> +             xid = be32_to_cpu(task->tk_rqstp->rq_xid);
> >> +
> >> +     seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
> >> +             task->tk_pid, task->tk_flags, task->tk_status,
> >> +             clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
> >> +             clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
> >> +             task->tk_action, rpc_waitq);
> >> +     return 0;
> >> +}
> >> +
> >> +static void *
> >> +tasks_start(struct seq_file *f, loff_t *ppos)
> >> +     __acquires(&sn->rpc_client_lock)
> >> +     __acquires(&clnt->cl_lock)
> >> +{
> >> +     loff_t *p = f->private, pos = *ppos;
> >> +     struct rpc_clnt *clnt;
> >> +     struct rpc_task *task;
> >> +     struct sunrpc_net *sn = net_generic(current->nsproxy->net_ns,
> >> +                                             sunrpc_net_id);
> >> +
> >> +     *p = pos + 1;
> >> +     spin_lock(&sn->rpc_client_lock);
> >> +     list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
> >> +             spin_lock(&clnt->cl_lock);
> >> +             list_for_each_entry(task, &clnt->cl_tasks, tk_task)
> >> +                     if (pos-- == 0)
> >> +                             return task;
> >> +             spin_unlock(&clnt->cl_lock);
> >> +     }
> >> +     return NULL;
> >> +}
> 
> Instead of having a single pseudofile that iterates through all
> rpc_clients and all rpc_tasks, should we perhaps have a hierarchy of
> subdirectories?
> I'm thinking we might want a directory per rpc_client, each containing
> a pseudo-file that iterates through all rpc_tasks for that rpc_client
> only. The reason for doing so would be so that we can add pseudofiles
> to display more per-rpc_client debugging info, such as cl_nodename,
> cl_program->name, cl_prog, cl_vers. Maybe also with a symlink to
> another subdirectory that displays per-xprt debugging information?
> 
> i.e. a hierarchy of the form
> 
> debugfs/

I'd suggest that we have a top level "sunrpc/" directory here to keep
things neat and tidy.

>     rpc_clients/
>          1/
>             cl_tasks
>             cl_xprt->../../rpc_xprt/1
> .....
>          2/
>             cl_tasks
>             cl_xprt->../../rpc_xprt/1
> .....
>     rpc_xprt/
>          1/
>             servername
> .....
> 

Hmm...that looks doable, but is a much larger piece of work than this
patch. Let me see what I can come up with and I'll get back to you...

-- 
Jeff Layton <jlayton@primarydata.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 0/4] sunrpc:  add debugfs file for displaying client rpc_task queue
  2014-10-28 18:24 [PATCH] sunrpc: add debugfs file for displaying client rpc_task queue Jeff Layton
  2014-10-28 18:30 ` Jeff Layton
@ 2014-11-25 19:00 ` Jeff Layton
  2014-11-25 19:00   ` [PATCH v2 1/4] lockd: eliminate LOCKD_DEBUG Jeff Layton
                     ` (4 more replies)
  1 sibling, 5 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-25 19:00 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

This is a respin of this patch that I sent a few weeks ago:

    sunrpc: add debugfs file for displaying client rpc_task queue

...to address Trond's concerns about how to lay out this directory.

I've also included a respin of the patches to eliminate the unneeded
#define redirection in the sunrpc debugging code. I had originally based
those patches on top of the debugfs patch, so if we drop that patch
there are merge conflicts with these.

In this set, I've reversed the order so if there are any more respins
needed on the debugfs work, I shouldn't need to resend the whole set.

Jeff Layton (4):
  lockd: eliminate LOCKD_DEBUG
  sunrpc: eliminate RPC_DEBUG
  sunrpc: eliminate RPC_TRACEPOINTS
  sunrpc: add debugfs file for displaying client rpc_task queue

 fs/lockd/svclock.c                      |   2 +-
 include/linux/lockd/debug.h             |   6 +-
 include/linux/sunrpc/auth.h             |   2 +-
 include/linux/sunrpc/clnt.h             |   4 +
 include/linux/sunrpc/debug.h            |  49 ++++++---
 include/linux/sunrpc/sched.h            |   8 +-
 include/uapi/linux/nfsd/debug.h         |   2 +-
 net/sunrpc/Kconfig                      |   1 +
 net/sunrpc/Makefile                     |   1 +
 net/sunrpc/auth.c                       |   4 +-
 net/sunrpc/auth_generic.c               |   2 +-
 net/sunrpc/auth_gss/auth_gss.c          |   2 +-
 net/sunrpc/auth_gss/gss_generic_token.c |   2 +-
 net/sunrpc/auth_gss/gss_krb5_crypto.c   |   2 +-
 net/sunrpc/auth_gss/gss_krb5_keys.c     |   2 +-
 net/sunrpc/auth_gss/gss_krb5_mech.c     |   2 +-
 net/sunrpc/auth_gss/gss_krb5_seal.c     |   2 +-
 net/sunrpc/auth_gss/gss_krb5_seqnum.c   |   2 +-
 net/sunrpc/auth_gss/gss_krb5_unseal.c   |   2 +-
 net/sunrpc/auth_gss/gss_krb5_wrap.c     |   2 +-
 net/sunrpc/auth_gss/gss_mech_switch.c   |   2 +-
 net/sunrpc/auth_gss/gss_rpc_xdr.h       |   2 +-
 net/sunrpc/auth_gss/svcauth_gss.c       |   2 +-
 net/sunrpc/auth_null.c                  |   4 +-
 net/sunrpc/auth_unix.c                  |   2 +-
 net/sunrpc/backchannel_rqst.c           |   2 +-
 net/sunrpc/clnt.c                       |  15 ++-
 net/sunrpc/debugfs.c                    | 173 ++++++++++++++++++++++++++++++++
 net/sunrpc/rpcb_clnt.c                  |   2 +-
 net/sunrpc/sched.c                      |   4 +-
 net/sunrpc/sunrpc_syms.c                |  12 ++-
 net/sunrpc/svc.c                        |   2 +-
 net/sunrpc/sysctl.c                     |   2 +-
 net/sunrpc/xprt.c                       |   2 +-
 net/sunrpc/xprtrdma/rpc_rdma.c          |   4 +-
 net/sunrpc/xprtrdma/transport.c         |   8 +-
 net/sunrpc/xprtrdma/verbs.c             |   8 +-
 net/sunrpc/xprtsock.c                   |   8 +-
 38 files changed, 281 insertions(+), 72 deletions(-)
 create mode 100644 net/sunrpc/debugfs.c

-- 
2.1.0


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 1/4] lockd: eliminate LOCKD_DEBUG
  2014-11-25 19:00 ` [PATCH v2 0/4] " Jeff Layton
@ 2014-11-25 19:00   ` Jeff Layton
  2014-11-25 19:00   ` [PATCH v2 2/4] sunrpc: eliminate RPC_DEBUG Jeff Layton
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-25 19:00 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

LOCKD_DEBUG is always the same value as CONFIG_SUNRPC_DEBUG, so we can
just use it instead.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
---
 fs/lockd/svclock.c          | 2 +-
 include/linux/lockd/debug.h | 6 +-----
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 13db95f54176..56598742dde4 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -53,7 +53,7 @@ static const struct rpc_call_ops nlmsvc_grant_ops;
 static LIST_HEAD(nlm_blocked);
 static DEFINE_SPINLOCK(nlm_blocked_lock);
 
-#ifdef LOCKD_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie)
 {
 	/*
diff --git a/include/linux/lockd/debug.h b/include/linux/lockd/debug.h
index 257d3779f2ab..0ca8109934e4 100644
--- a/include/linux/lockd/debug.h
+++ b/include/linux/lockd/debug.h
@@ -17,12 +17,8 @@
  * Enable lockd debugging.
  * Requires RPC_DEBUG.
  */
-#ifdef RPC_DEBUG
-# define LOCKD_DEBUG		1
-#endif
-
 #undef ifdebug
-#if defined(RPC_DEBUG) && defined(LOCKD_DEBUG)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define ifdebug(flag)		if (unlikely(nlm_debug & NLMDBG_##flag))
 #else
 # define ifdebug(flag)		if (0)
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 2/4] sunrpc: eliminate RPC_DEBUG
  2014-11-25 19:00 ` [PATCH v2 0/4] " Jeff Layton
  2014-11-25 19:00   ` [PATCH v2 1/4] lockd: eliminate LOCKD_DEBUG Jeff Layton
@ 2014-11-25 19:00   ` Jeff Layton
  2014-11-25 19:00   ` [PATCH v2 3/4] sunrpc: eliminate RPC_TRACEPOINTS Jeff Layton
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-25 19:00 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

It's always set to whatever CONFIG_SUNRPC_DEBUG is, so just use that.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
---
 include/linux/sunrpc/auth.h             | 2 +-
 include/linux/sunrpc/debug.h            | 9 +++------
 include/linux/sunrpc/sched.h            | 8 ++++----
 include/uapi/linux/nfsd/debug.h         | 2 +-
 net/sunrpc/auth.c                       | 4 ++--
 net/sunrpc/auth_generic.c               | 2 +-
 net/sunrpc/auth_gss/auth_gss.c          | 2 +-
 net/sunrpc/auth_gss/gss_generic_token.c | 2 +-
 net/sunrpc/auth_gss/gss_krb5_crypto.c   | 2 +-
 net/sunrpc/auth_gss/gss_krb5_keys.c     | 2 +-
 net/sunrpc/auth_gss/gss_krb5_mech.c     | 2 +-
 net/sunrpc/auth_gss/gss_krb5_seal.c     | 2 +-
 net/sunrpc/auth_gss/gss_krb5_seqnum.c   | 2 +-
 net/sunrpc/auth_gss/gss_krb5_unseal.c   | 2 +-
 net/sunrpc/auth_gss/gss_krb5_wrap.c     | 2 +-
 net/sunrpc/auth_gss/gss_mech_switch.c   | 2 +-
 net/sunrpc/auth_gss/gss_rpc_xdr.h       | 2 +-
 net/sunrpc/auth_gss/svcauth_gss.c       | 2 +-
 net/sunrpc/auth_null.c                  | 4 ++--
 net/sunrpc/auth_unix.c                  | 2 +-
 net/sunrpc/backchannel_rqst.c           | 2 +-
 net/sunrpc/clnt.c                       | 6 +++---
 net/sunrpc/rpcb_clnt.c                  | 2 +-
 net/sunrpc/sched.c                      | 4 ++--
 net/sunrpc/sunrpc_syms.c                | 4 ++--
 net/sunrpc/svc.c                        | 2 +-
 net/sunrpc/sysctl.c                     | 2 +-
 net/sunrpc/xprt.c                       | 2 +-
 net/sunrpc/xprtrdma/rpc_rdma.c          | 4 ++--
 net/sunrpc/xprtrdma/transport.c         | 8 ++++----
 net/sunrpc/xprtrdma/verbs.c             | 8 ++++----
 net/sunrpc/xprtsock.c                   | 8 ++++----
 32 files changed, 53 insertions(+), 56 deletions(-)

diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 8e030075fe79..a7cbb570cc5c 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -53,7 +53,7 @@ struct rpc_cred {
 	struct rcu_head		cr_rcu;
 	struct rpc_auth *	cr_auth;
 	const struct rpc_credops *cr_ops;
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	unsigned long		cr_magic;	/* 0x0f4aa4f0 */
 #endif
 	unsigned long		cr_expire;	/* when to gc */
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 9385bd74c860..51143757b8f7 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -14,9 +14,6 @@
 /*
  * Enable RPC debugging/profiling.
  */
-#ifdef CONFIG_SUNRPC_DEBUG
-#define  RPC_DEBUG
-#endif
 #ifdef CONFIG_TRACEPOINTS
 #define RPC_TRACEPOINTS
 #endif
@@ -25,7 +22,7 @@
 /*
  * Debugging macros etc
  */
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 extern unsigned int		rpc_debug;
 extern unsigned int		nfs_debug;
 extern unsigned int		nfsd_debug;
@@ -36,7 +33,7 @@ extern unsigned int		nlm_debug;
 #define dprintk_rcu(args...)	dfprintk_rcu(FACILITY, ## args)
 
 #undef ifdebug
-#ifdef RPC_DEBUG			
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define ifdebug(fac)		if (unlikely(rpc_debug & RPCDBG_##fac))
 
 # define dfprintk(fac, args...)	\
@@ -65,7 +62,7 @@ extern unsigned int		nlm_debug;
 /*
  * Sysctl interface for RPC debugging
  */
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 void		rpc_register_sysctl(void);
 void		rpc_unregister_sysctl(void);
 #endif
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 1a8959944c5f..fecdbf1b4797 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -79,7 +79,7 @@ struct rpc_task {
 	unsigned short		tk_flags;	/* misc flags */
 	unsigned short		tk_timeouts;	/* maj timeouts */
 
-#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
 	unsigned short		tk_pid;		/* debugging aid */
 #endif
 	unsigned char		tk_priority : 2,/* Task priority */
@@ -187,7 +187,7 @@ struct rpc_wait_queue {
 	unsigned char		nr;			/* # tasks remaining for cookie */
 	unsigned short		qlen;			/* total # tasks waiting in queue */
 	struct rpc_timer	timer_list;
-#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
 	const char *		name;
 #endif
 };
@@ -237,7 +237,7 @@ void		rpc_free(void *);
 int		rpciod_up(void);
 void		rpciod_down(void);
 int		__rpc_wait_for_completion_task(struct rpc_task *task, wait_bit_action_f *);
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 struct net;
 void		rpc_show_tasks(struct net *);
 #endif
@@ -251,7 +251,7 @@ static inline int rpc_wait_for_completion_task(struct rpc_task *task)
 	return __rpc_wait_for_completion_task(task, NULL);
 }
 
-#if defined(RPC_DEBUG) || defined (RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined (RPC_TRACEPOINTS)
 static inline const char * rpc_qname(const struct rpc_wait_queue *q)
 {
 	return ((q && q->name) ? q->name : "unknown");
diff --git a/include/uapi/linux/nfsd/debug.h b/include/uapi/linux/nfsd/debug.h
index a6f453c740b8..1fdc95bb2375 100644
--- a/include/uapi/linux/nfsd/debug.h
+++ b/include/uapi/linux/nfsd/debug.h
@@ -15,7 +15,7 @@
  * Enable debugging for nfsd.
  * Requires RPC_DEBUG.
  */
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define NFSD_DEBUG		1
 #endif
 
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 383eb919ac0b..47f38be4155f 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -16,7 +16,7 @@
 #include <linux/sunrpc/gss_api.h>
 #include <linux/spinlock.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
@@ -646,7 +646,7 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
 	cred->cr_auth = auth;
 	cred->cr_ops = ops;
 	cred->cr_expire = jiffies;
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	cred->cr_magic = RPCAUTH_CRED_MAGIC;
 #endif
 	cred->cr_uid = acred->uid;
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index 6f6b829c9e8e..41248b1820c7 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -14,7 +14,7 @@
 #include <linux/sunrpc/debug.h>
 #include <linux/sunrpc/sched.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 53ed8d3f8897..dace13d7638e 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -66,7 +66,7 @@ static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
 #define GSS_KEY_EXPIRE_TIMEO 240
 static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO;
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c
index c586e92bcf76..254defe446a7 100644
--- a/net/sunrpc/auth_gss/gss_generic_token.c
+++ b/net/sunrpc/auth_gss/gss_generic_token.c
@@ -38,7 +38,7 @@
 #include <linux/sunrpc/gss_asn1.h>
 
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index f5ed9f6ece06..b5408e8a37f2 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -45,7 +45,7 @@
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/sunrpc/xdr.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c
index 24589bd2a4b6..234fa8d0fd9b 100644
--- a/net/sunrpc/auth_gss/gss_krb5_keys.c
+++ b/net/sunrpc/auth_gss/gss_krb5_keys.c
@@ -61,7 +61,7 @@
 #include <linux/sunrpc/xdr.h>
 #include <linux/lcm.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 0d3c158ef8fa..28db442a0034 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -45,7 +45,7 @@
 #include <linux/crypto.h>
 #include <linux/sunrpc/gss_krb5_enctypes.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
index 42768e5c3994..1d74d653e6c0 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
@@ -64,7 +64,7 @@
 #include <linux/random.h>
 #include <linux/crypto.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
index 62ac90c62cb1..20d55c793eb6 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seqnum.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
@@ -35,7 +35,7 @@
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/crypto.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
index 6c981ddc19f8..dcf9515d9aef 100644
--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
@@ -62,7 +62,7 @@
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/crypto.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index 4b614c604fe0..ca7e92a32f84 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -35,7 +35,7 @@
 #include <linux/pagemap.h>
 #include <linux/crypto.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index 92d5ab99fbf3..7063d856a598 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -46,7 +46,7 @@
 #include <linux/sunrpc/gss_api.h>
 #include <linux/sunrpc/clnt.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.h b/net/sunrpc/auth_gss/gss_rpc_xdr.h
index 685a688f3d8a..9d88c6239f01 100644
--- a/net/sunrpc/auth_gss/gss_rpc_xdr.h
+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.h
@@ -25,7 +25,7 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/xprtsock.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index c548ab213f76..de856ddf5fed 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -51,7 +51,7 @@
 #include "gss_rpc_upcall.h"
 
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index 712c123e04e9..c2a2b584a056 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -10,7 +10,7 @@
 #include <linux/module.h>
 #include <linux/sunrpc/clnt.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
@@ -138,7 +138,7 @@ struct rpc_cred null_cred = {
 	.cr_ops		= &null_credops,
 	.cr_count	= ATOMIC_INIT(1),
 	.cr_flags	= 1UL << RPCAUTH_CRED_UPTODATE,
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	.cr_magic	= RPCAUTH_CRED_MAGIC,
 #endif
 };
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index d5d692366294..4feda2d0a833 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -25,7 +25,7 @@ struct unx_cred {
 
 #define UNX_WRITESLACK		(21 + (UNX_MAXNODENAME >> 2))
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
index 9761a0da964d..651f49ab601f 100644
--- a/net/sunrpc/backchannel_rqst.c
+++ b/net/sunrpc/backchannel_rqst.c
@@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <linux/export.h>
 #include <linux/sunrpc/bc_xprt.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 #define RPCDBG_FACILITY	RPCDBG_TRANS
 #endif
 
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 9acd6ce88db7..36c64ef460cf 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -42,7 +42,7 @@
 #include "sunrpc.h"
 #include "netns.h"
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_CALL
 #endif
 
@@ -1396,7 +1396,7 @@ rpc_restart_call(struct rpc_task *task)
 }
 EXPORT_SYMBOL_GPL(rpc_restart_call);
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static const char *rpc_proc_name(const struct rpc_task *task)
 {
 	const struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
@@ -2421,7 +2421,7 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int
 }
 EXPORT_SYMBOL_GPL(rpc_call_null);
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static void rpc_show_header(void)
 {
 	printk(KERN_INFO "-pid- flgs status -client- --rqstp- "
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 1891a1022c17..05202012bcfc 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -32,7 +32,7 @@
 
 #include "netns.h"
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_BIND
 #endif
 
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index fe3441abdbe5..574b2977fc4b 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -24,7 +24,7 @@
 
 #include "sunrpc.h"
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 #define RPCDBG_FACILITY		RPCDBG_SCHED
 #endif
 
@@ -258,7 +258,7 @@ static int rpc_wait_bit_killable(struct wait_bit_key *key)
 	return 0;
 }
 
-#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
 static void rpc_task_set_debuginfo(struct rpc_task *task)
 {
 	static atomic_t rpc_pid;
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index cd30120de9e4..f632e476ab6c 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -97,7 +97,7 @@ init_sunrpc(void)
 	err = register_rpc_pipefs();
 	if (err)
 		goto out4;
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	rpc_register_sysctl();
 #endif
 	svc_init_xprt_sock();	/* svc sock transport */
@@ -123,7 +123,7 @@ cleanup_sunrpc(void)
 	unregister_rpc_pipefs();
 	rpc_destroy_mempool();
 	unregister_pernet_subsys(&sunrpc_net_ops);
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	rpc_unregister_sysctl();
 #endif
 	rcu_barrier(); /* Wait for completion of call_rcu()'s */
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 371a8bbb43d6..2783fd80c229 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1042,7 +1042,7 @@ static void svc_unregister(const struct svc_serv *serv, struct net *net)
 /*
  * dprintk the given error with the address of the client that caused it.
  */
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static __printf(2, 3)
 void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
 {
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index c99c58e2ee66..887f0183b4c6 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -37,7 +37,7 @@ EXPORT_SYMBOL_GPL(nfsd_debug);
 unsigned int	nlm_debug;
 EXPORT_SYMBOL_GPL(nlm_debug);
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 
 static struct ctl_table_header *sunrpc_table_header;
 static struct ctl_table sunrpc_table[];
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 1b2e5e616cae..894d071426b2 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -57,7 +57,7 @@
  * Local variables
  */
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_XPRT
 #endif
 
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index 6166c985fe24..df01d124936c 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -49,11 +49,11 @@
 
 #include <linux/highmem.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_TRANS
 #endif
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static const char transfertypes[][12] = {
 	"pure inline",	/* no chunks */
 	" read chunk",	/* some argument via rdma read */
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 6a4615dd0261..ef58ebadb3ae 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -55,7 +55,7 @@
 
 #include "xprt_rdma.h"
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_TRANS
 #endif
 
@@ -75,7 +75,7 @@ static unsigned int xprt_rdma_inline_write_padding;
 static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR;
                 int xprt_rdma_pad_optimize = 0;
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 
 static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE;
 static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE;
@@ -705,7 +705,7 @@ static void __exit xprt_rdma_cleanup(void)
 	int rc;
 
 	dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n");
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	if (sunrpc_table_header) {
 		unregister_sysctl_table(sunrpc_table_header);
 		sunrpc_table_header = NULL;
@@ -736,7 +736,7 @@ static int __init xprt_rdma_init(void)
 	dprintk("\tPadding %d\n\tMemreg %d\n",
 		xprt_rdma_inline_write_padding, xprt_rdma_memreg_strategy);
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	if (!sunrpc_table_header)
 		sunrpc_table_header = register_sysctl_table(sunrpc_table);
 #endif
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 61c41298b4ea..b92b04083e40 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -57,7 +57,7 @@
  * Globals/Macros
  */
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_TRANS
 #endif
 
@@ -313,7 +313,7 @@ rpcrdma_flush_cqs(struct rpcrdma_ep *ep)
 	rpcrdma_sendcq_upcall(ep->rep_attr.send_cq, ep);
 }
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static const char * const conn[] = {
 	"address resolved",
 	"address error",
@@ -344,7 +344,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
 	struct rpcrdma_xprt *xprt = id->context;
 	struct rpcrdma_ia *ia = &xprt->rx_ia;
 	struct rpcrdma_ep *ep = &xprt->rx_ep;
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	struct sockaddr_in *addr = (struct sockaddr_in *) &ep->rep_remote_addr;
 #endif
 	struct ib_qp_attr attr;
@@ -408,7 +408,7 @@ connected:
 		break;
 	}
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	if (connstate == 1) {
 		int ird = attr.max_dest_rd_atomic;
 		int tird = ep->rep_remote_cma.responder_resources;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 31c015196a29..87ce7e8bb8dc 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -75,7 +75,7 @@ static unsigned int xs_tcp_fin_timeout __read_mostly = XS_TCP_LINGER_TO;
  * someone else's file names!
  */
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 
 static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
 static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
@@ -186,7 +186,7 @@ static struct ctl_table sunrpc_table[] = {
  */
 #define XS_IDLE_DISC_TO		(5U * 60 * HZ)
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # undef  RPC_DEBUG_DATA
 # define RPCDBG_FACILITY	RPCDBG_TRANS
 #endif
@@ -2991,7 +2991,7 @@ static struct xprt_class	xs_bc_tcp_transport = {
  */
 int init_socket_xprt(void)
 {
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	if (!sunrpc_table_header)
 		sunrpc_table_header = register_sysctl_table(sunrpc_table);
 #endif
@@ -3010,7 +3010,7 @@ int init_socket_xprt(void)
  */
 void cleanup_socket_xprt(void)
 {
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	if (sunrpc_table_header) {
 		unregister_sysctl_table(sunrpc_table_header);
 		sunrpc_table_header = NULL;
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 3/4] sunrpc: eliminate RPC_TRACEPOINTS
  2014-11-25 19:00 ` [PATCH v2 0/4] " Jeff Layton
  2014-11-25 19:00   ` [PATCH v2 1/4] lockd: eliminate LOCKD_DEBUG Jeff Layton
  2014-11-25 19:00   ` [PATCH v2 2/4] sunrpc: eliminate RPC_DEBUG Jeff Layton
@ 2014-11-25 19:00   ` Jeff Layton
  2014-11-25 19:01   ` [PATCH v2 4/4] sunrpc: add debugfs file for displaying client rpc_task queue Jeff Layton
  2014-11-26 19:44   ` [PATCH v3 0/5] sunrpc: add some debugfs files for dumping task and xprt info Jeff Layton
  4 siblings, 0 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-25 19:00 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

It's always set to the same value as CONFIG_TRACEPOINTS, so we can just
use that instead.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
---
 include/linux/sunrpc/debug.h | 9 ---------
 include/linux/sunrpc/sched.h | 6 +++---
 net/sunrpc/sched.c           | 2 +-
 3 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 51143757b8f7..43f38ee9668c 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -10,15 +10,6 @@
 
 #include <uapi/linux/sunrpc/debug.h>
 
-
-/*
- * Enable RPC debugging/profiling.
- */
-#ifdef CONFIG_TRACEPOINTS
-#define RPC_TRACEPOINTS
-#endif
-/* #define  RPC_PROFILE */
-
 /*
  * Debugging macros etc
  */
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index fecdbf1b4797..5f1e6bd4c316 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -79,7 +79,7 @@ struct rpc_task {
 	unsigned short		tk_flags;	/* misc flags */
 	unsigned short		tk_timeouts;	/* maj timeouts */
 
-#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
 	unsigned short		tk_pid;		/* debugging aid */
 #endif
 	unsigned char		tk_priority : 2,/* Task priority */
@@ -187,7 +187,7 @@ struct rpc_wait_queue {
 	unsigned char		nr;			/* # tasks remaining for cookie */
 	unsigned short		qlen;			/* total # tasks waiting in queue */
 	struct rpc_timer	timer_list;
-#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
 	const char *		name;
 #endif
 };
@@ -251,7 +251,7 @@ static inline int rpc_wait_for_completion_task(struct rpc_task *task)
 	return __rpc_wait_for_completion_task(task, NULL);
 }
 
-#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined (RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
 static inline const char * rpc_qname(const struct rpc_wait_queue *q)
 {
 	return ((q && q->name) ? q->name : "unknown");
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 574b2977fc4b..d20f2329eea3 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -258,7 +258,7 @@ static int rpc_wait_bit_killable(struct wait_bit_key *key)
 	return 0;
 }
 
-#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
 static void rpc_task_set_debuginfo(struct rpc_task *task)
 {
 	static atomic_t rpc_pid;
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 4/4] sunrpc: add debugfs file for displaying client rpc_task queue
  2014-11-25 19:00 ` [PATCH v2 0/4] " Jeff Layton
                     ` (2 preceding siblings ...)
  2014-11-25 19:00   ` [PATCH v2 3/4] sunrpc: eliminate RPC_TRACEPOINTS Jeff Layton
@ 2014-11-25 19:01   ` Jeff Layton
  2014-11-25 21:00     ` Jeff Layton
  2014-11-26 19:44   ` [PATCH v3 0/5] sunrpc: add some debugfs files for dumping task and xprt info Jeff Layton
  4 siblings, 1 reply; 19+ messages in thread
From: Jeff Layton @ 2014-11-25 19:01 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

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: Jeff Layton <jlayton@primarydata.com>
---
 include/linux/sunrpc/clnt.h  |   4 +
 include/linux/sunrpc/debug.h |  31 ++++++++
 net/sunrpc/Kconfig           |   1 +
 net/sunrpc/Makefile          |   1 +
 net/sunrpc/clnt.c            |   9 ++-
 net/sunrpc/debugfs.c         | 173 +++++++++++++++++++++++++++++++++++++++++++
 net/sunrpc/sunrpc_syms.c     |   8 ++
 7 files changed, 226 insertions(+), 1 deletion(-)
 create mode 100644 net/sunrpc/debugfs.c

diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 70736b98c721..d86acc63b25f 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -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 */
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 43f38ee9668c..835339707094 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -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_ */
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index 0754d0f466d2..fb78117b896c 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -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
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index e5a7a1cac8f3..15e6f6c23c5d 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -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
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 36c64ef460cf..602259baebcc 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -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;
 }
 
@@ -771,6 +776,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 +1403,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;
 
diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
new file mode 100644
index 000000000000..4062e8ca7363
--- /dev/null
+++ b/net/sunrpc/debugfs.c
@@ -0,0 +1,173 @@
+/**
+ * debugfs interface for sunrpc
+ *
+ * (c) 2014 Jeff Layton <jlayton@primarydata.com>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/clnt.h>
+#include "netns.h"
+
+static struct dentry *topdir;
+static struct dentry *rpc_clnt_dir;
+
+struct rpc_clnt_iter {
+	struct rpc_clnt	*clnt;
+	loff_t		pos;
+};
+
+static int
+tasks_show(struct seq_file *f, void *v)
+{
+	u32 xid = 0;
+	struct rpc_task *task = v;
+	struct rpc_clnt *clnt = task->tk_client;
+	const char *rpc_waitq = "none";
+
+	if (RPC_IS_QUEUED(task))
+		rpc_waitq = rpc_qname(task->tk_waitqueue);
+
+	if (task->tk_rqstp)
+		xid = be32_to_cpu(task->tk_rqstp->rq_xid);
+
+	seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
+		task->tk_pid, task->tk_flags, task->tk_status,
+		clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
+		clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
+		task->tk_action, rpc_waitq);
+	return 0;
+}
+
+static void *
+tasks_start(struct seq_file *f, loff_t *ppos)
+	__acquires(&clnt->cl_lock)
+{
+	struct rpc_clnt_iter *iter = f->private;
+	loff_t pos = *ppos;
+	struct rpc_clnt *clnt = iter->clnt;
+	struct rpc_task *task;
+
+	iter->pos = pos + 1;
+	spin_lock(&clnt->cl_lock);
+	list_for_each_entry(task, &clnt->cl_tasks, tk_task)
+		if (pos-- == 0)
+			return task;
+	return NULL;
+}
+
+static void *
+tasks_next(struct seq_file *f, void *v, loff_t *pos)
+{
+	struct rpc_clnt_iter *iter = f->private;
+	struct rpc_clnt *clnt = iter->clnt;
+	struct rpc_task *task = v;
+	struct list_head *next = task->tk_task.next;
+
+	++iter->pos;
+	++*pos;
+
+	/* If there's another task on list, return it */
+	if (next == &clnt->cl_tasks)
+		return NULL;
+	return list_entry(next, struct rpc_task, tk_task);
+}
+
+static void
+tasks_stop(struct seq_file *f, void *v)
+	__releases(&clnt->cl_lock)
+{
+	struct rpc_clnt_iter *iter = f->private;
+	struct rpc_clnt *clnt = iter->clnt;
+
+	spin_unlock(&clnt->cl_lock);
+}
+
+static const struct seq_operations tasks_seq_operations = {
+	.start	= tasks_start,
+	.next	= tasks_next,
+	.stop	= tasks_stop,
+	.show	= tasks_show,
+};
+
+static int tasks_open(struct inode *inode, struct file *filp)
+{
+	int ret = seq_open_private(filp, &tasks_seq_operations,
+					sizeof(struct rpc_clnt_iter));
+
+	if (ret == 0) {
+		struct seq_file *seq = filp->private_data;
+		struct rpc_clnt_iter *iter = seq->private;
+
+		iter->clnt = inode->i_private;
+	}
+
+	return ret;
+}
+
+static const struct file_operations tasks_fops = {
+	.owner		= THIS_MODULE,
+	.open		= tasks_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release_private,
+};
+
+int
+rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
+{
+	char name[9]; /* 8 for hex digits + NULL terminator */
+
+	/* Already registered? */
+	if (clnt->cl_debugfs)
+		return 0;
+
+	snprintf(name, sizeof(name), "%8.8x", clnt->cl_clid);
+
+	/* make the per-client dir */
+	clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir);
+	if (!clnt->cl_debugfs)
+		return -ENOMEM;
+
+	/* make tasks file */
+	if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs,
+				 clnt, &tasks_fops)) {
+		debugfs_remove_recursive(clnt->cl_debugfs);
+		clnt->cl_debugfs = NULL;
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void
+rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
+{
+	debugfs_remove_recursive(clnt->cl_debugfs);
+	clnt->cl_debugfs = NULL;
+}
+
+void __exit
+sunrpc_debugfs_exit(void)
+{
+	debugfs_remove_recursive(topdir);
+}
+
+int __init
+sunrpc_debugfs_init(void)
+{
+	topdir = debugfs_create_dir("sunrpc", NULL);
+	if (!topdir)
+		goto out;
+
+	rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir);
+	if (!rpc_clnt_dir)
+		goto out_remove;
+
+	return 0;
+out_remove:
+	debugfs_remove_recursive(topdir);
+	topdir = NULL;
+out:
+	return -ENOMEM;
+}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index f632e476ab6c..e37fbed87956 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -97,6 +97,11 @@ init_sunrpc(void)
 	err = register_rpc_pipefs();
 	if (err)
 		goto out4;
+
+	err = sunrpc_debugfs_init();
+	if (err)
+		goto out5;
+
 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	rpc_register_sysctl();
 #endif
@@ -104,6 +109,8 @@ init_sunrpc(void)
 	init_socket_xprt();	/* clnt sock transport */
 	return 0;
 
+out5:
+	unregister_rpc_pipefs();
 out4:
 	unregister_pernet_subsys(&sunrpc_net_ops);
 out3:
@@ -120,6 +127,7 @@ cleanup_sunrpc(void)
 	rpcauth_remove_module();
 	cleanup_socket_xprt();
 	svc_cleanup_xprt_sock();
+	sunrpc_debugfs_exit();
 	unregister_rpc_pipefs();
 	rpc_destroy_mempool();
 	unregister_pernet_subsys(&sunrpc_net_ops);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 4/4] sunrpc: add debugfs file for displaying client rpc_task queue
  2014-11-25 19:01   ` [PATCH v2 4/4] sunrpc: add debugfs file for displaying client rpc_task queue Jeff Layton
@ 2014-11-25 21:00     ` Jeff Layton
  0 siblings, 0 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-25 21:00 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

On Tue, 25 Nov 2014 14:01:00 -0500
Jeff Layton <jlayton@primarydata.com> wrote:

> 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: Jeff Layton <jlayton@primarydata.com>
> ---
>  include/linux/sunrpc/clnt.h  |   4 +
>  include/linux/sunrpc/debug.h |  31 ++++++++
>  net/sunrpc/Kconfig           |   1 +
>  net/sunrpc/Makefile          |   1 +
>  net/sunrpc/clnt.c            |   9 ++-
>  net/sunrpc/debugfs.c         | 173 +++++++++++++++++++++++++++++++++++++++++++
>  net/sunrpc/sunrpc_syms.c     |   8 ++
>  7 files changed, 226 insertions(+), 1 deletion(-)
>  create mode 100644 net/sunrpc/debugfs.c
> 
> diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
> index 70736b98c721..d86acc63b25f 100644
> --- a/include/linux/sunrpc/clnt.h
> +++ b/include/linux/sunrpc/clnt.h
> @@ -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 */
> diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
> index 43f38ee9668c..835339707094 100644
> --- a/include/linux/sunrpc/debug.h
> +++ b/include/linux/sunrpc/debug.h
> @@ -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_ */
> diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
> index 0754d0f466d2..fb78117b896c 100644
> --- a/net/sunrpc/Kconfig
> +++ b/net/sunrpc/Kconfig
> @@ -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
> diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
> index e5a7a1cac8f3..15e6f6c23c5d 100644
> --- a/net/sunrpc/Makefile
> +++ b/net/sunrpc/Makefile
> @@ -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
> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
> index 36c64ef460cf..602259baebcc 100644
> --- a/net/sunrpc/clnt.c
> +++ b/net/sunrpc/clnt.c
> @@ -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;
>  }
>  
> @@ -771,6 +776,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 +1403,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;
>  
> diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
> new file mode 100644
> index 000000000000..4062e8ca7363
> --- /dev/null
> +++ b/net/sunrpc/debugfs.c
> @@ -0,0 +1,173 @@
> +/**
> + * debugfs interface for sunrpc
> + *
> + * (c) 2014 Jeff Layton <jlayton@primarydata.com>
> + */
> +
> +#include <linux/debugfs.h>
> +#include <linux/sunrpc/sched.h>
> +#include <linux/sunrpc/clnt.h>
> +#include "netns.h"
> +
> +static struct dentry *topdir;
> +static struct dentry *rpc_clnt_dir;
> +
> +struct rpc_clnt_iter {
> +	struct rpc_clnt	*clnt;
> +	loff_t		pos;
> +};
> +
> +static int
> +tasks_show(struct seq_file *f, void *v)
> +{
> +	u32 xid = 0;
> +	struct rpc_task *task = v;
> +	struct rpc_clnt *clnt = task->tk_client;
> +	const char *rpc_waitq = "none";
> +
> +	if (RPC_IS_QUEUED(task))
> +		rpc_waitq = rpc_qname(task->tk_waitqueue);
> +
> +	if (task->tk_rqstp)
> +		xid = be32_to_cpu(task->tk_rqstp->rq_xid);
> +
> +	seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
> +		task->tk_pid, task->tk_flags, task->tk_status,
> +		clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
> +		clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
> +		task->tk_action, rpc_waitq);
> +	return 0;
> +}
> +
> +static void *
> +tasks_start(struct seq_file *f, loff_t *ppos)
> +	__acquires(&clnt->cl_lock)
> +{
> +	struct rpc_clnt_iter *iter = f->private;
> +	loff_t pos = *ppos;
> +	struct rpc_clnt *clnt = iter->clnt;
> +	struct rpc_task *task;
> +
> +	iter->pos = pos + 1;
> +	spin_lock(&clnt->cl_lock);
> +	list_for_each_entry(task, &clnt->cl_tasks, tk_task)
> +		if (pos-- == 0)
> +			return task;
> +	return NULL;
> +}
> +
> +static void *
> +tasks_next(struct seq_file *f, void *v, loff_t *pos)
> +{
> +	struct rpc_clnt_iter *iter = f->private;
> +	struct rpc_clnt *clnt = iter->clnt;
> +	struct rpc_task *task = v;
> +	struct list_head *next = task->tk_task.next;
> +
> +	++iter->pos;
> +	++*pos;
> +
> +	/* If there's another task on list, return it */
> +	if (next == &clnt->cl_tasks)
> +		return NULL;
> +	return list_entry(next, struct rpc_task, tk_task);
> +}
> +
> +static void
> +tasks_stop(struct seq_file *f, void *v)
> +	__releases(&clnt->cl_lock)
> +{
> +	struct rpc_clnt_iter *iter = f->private;
> +	struct rpc_clnt *clnt = iter->clnt;
> +
> +	spin_unlock(&clnt->cl_lock);
> +}
> +
> +static const struct seq_operations tasks_seq_operations = {
> +	.start	= tasks_start,
> +	.next	= tasks_next,
> +	.stop	= tasks_stop,
> +	.show	= tasks_show,
> +};
> +
> +static int tasks_open(struct inode *inode, struct file *filp)
> +{
> +	int ret = seq_open_private(filp, &tasks_seq_operations,
> +					sizeof(struct rpc_clnt_iter));
> +
> +	if (ret == 0) {
> +		struct seq_file *seq = filp->private_data;
> +		struct rpc_clnt_iter *iter = seq->private;
> +
> +		iter->clnt = inode->i_private;
> +	}
> +
> +	return ret;
> +}
> +

Hmm...it occurs to me that we probably need to take a reference to the
clnt in the above function to ensure that it doesn't vanish until the
file is closed.

Let me fix that and resend before you merge this...


> +static const struct file_operations tasks_fops = {
> +	.owner		= THIS_MODULE,
> +	.open		= tasks_open,
> +	.read		= seq_read,
> +	.llseek		= seq_lseek,
> +	.release	= seq_release_private,
> +};
> +
> +int
> +rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
> +{
> +	char name[9]; /* 8 for hex digits + NULL terminator */
> +
> +	/* Already registered? */
> +	if (clnt->cl_debugfs)
> +		return 0;
> +
> +	snprintf(name, sizeof(name), "%8.8x", clnt->cl_clid);
> +
> +	/* make the per-client dir */
> +	clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir);
> +	if (!clnt->cl_debugfs)
> +		return -ENOMEM;
> +
> +	/* make tasks file */
> +	if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs,
> +				 clnt, &tasks_fops)) {
> +		debugfs_remove_recursive(clnt->cl_debugfs);
> +		clnt->cl_debugfs = NULL;
> +		return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
> +void
> +rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
> +{
> +	debugfs_remove_recursive(clnt->cl_debugfs);
> +	clnt->cl_debugfs = NULL;
> +}
> +
> +void __exit
> +sunrpc_debugfs_exit(void)
> +{
> +	debugfs_remove_recursive(topdir);
> +}
> +
> +int __init
> +sunrpc_debugfs_init(void)
> +{
> +	topdir = debugfs_create_dir("sunrpc", NULL);
> +	if (!topdir)
> +		goto out;
> +
> +	rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir);
> +	if (!rpc_clnt_dir)
> +		goto out_remove;
> +
> +	return 0;
> +out_remove:
> +	debugfs_remove_recursive(topdir);
> +	topdir = NULL;
> +out:
> +	return -ENOMEM;
> +}
> diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
> index f632e476ab6c..e37fbed87956 100644
> --- a/net/sunrpc/sunrpc_syms.c
> +++ b/net/sunrpc/sunrpc_syms.c
> @@ -97,6 +97,11 @@ init_sunrpc(void)
>  	err = register_rpc_pipefs();
>  	if (err)
>  		goto out4;
> +
> +	err = sunrpc_debugfs_init();
> +	if (err)
> +		goto out5;
> +
>  #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
>  	rpc_register_sysctl();
>  #endif
> @@ -104,6 +109,8 @@ init_sunrpc(void)
>  	init_socket_xprt();	/* clnt sock transport */
>  	return 0;
>  
> +out5:
> +	unregister_rpc_pipefs();
>  out4:
>  	unregister_pernet_subsys(&sunrpc_net_ops);
>  out3:
> @@ -120,6 +127,7 @@ cleanup_sunrpc(void)
>  	rpcauth_remove_module();
>  	cleanup_socket_xprt();
>  	svc_cleanup_xprt_sock();
> +	sunrpc_debugfs_exit();
>  	unregister_rpc_pipefs();
>  	rpc_destroy_mempool();
>  	unregister_pernet_subsys(&sunrpc_net_ops);


-- 
Jeff Layton <jlayton@poochiereds.net>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v3 0/5] sunrpc: add some debugfs files for dumping task and xprt info
  2014-11-25 19:00 ` [PATCH v2 0/4] " Jeff Layton
                     ` (3 preceding siblings ...)
  2014-11-25 19:01   ` [PATCH v2 4/4] sunrpc: add debugfs file for displaying client rpc_task queue Jeff Layton
@ 2014-11-26 19:44   ` Jeff Layton
  2014-11-26 19:44     ` [PATCH v3 1/5] lockd: eliminate LOCKD_DEBUG Jeff Layton
                       ` (4 more replies)
  4 siblings, 5 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-26 19:44 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

v3:
- add a patch that creates and populates a rpc_xprt directory
- take reference on rpc_clnt when "tasks" file is opened
- minor cleanups

v2:
- add a whole new directory hierarchy instead of a single
  client_tasks file
- respin patches to remove LOCKD_DEBUG/RPC_DEBUG/RPC_TRACEPOINTS defines

Ok, here is the latest (and hopefully last!) respin of the patches to
add some debugfs files to dump info about rpc_clnt and rpc_xprt
objects.

This set ensures that references are properly acquired so that the
objects don't disappear while we're working on them. I've also included
the patches to eliminate the RPC_DEBUG defines too as they should be
merged first to prevent conflicts.

Trond, can you consider these for v3.19?

Thanks!

Jeff Layton (5):
  lockd: eliminate LOCKD_DEBUG
  sunrpc: eliminate RPC_DEBUG
  sunrpc: eliminate RPC_TRACEPOINTS
  sunrpc: add debugfs file for displaying client rpc_task queue
  sunrpc: add a debugfs rpc_xprt directory with an info file in it

 fs/lockd/svclock.c                      |   2 +-
 include/linux/lockd/debug.h             |   6 +-
 include/linux/sunrpc/auth.h             |   2 +-
 include/linux/sunrpc/clnt.h             |   4 +
 include/linux/sunrpc/debug.h            |  64 +++++--
 include/linux/sunrpc/sched.h            |   8 +-
 include/linux/sunrpc/xprt.h             |   3 +
 include/uapi/linux/nfsd/debug.h         |   2 +-
 net/sunrpc/Kconfig                      |   1 +
 net/sunrpc/Makefile                     |   1 +
 net/sunrpc/auth.c                       |   4 +-
 net/sunrpc/auth_generic.c               |   2 +-
 net/sunrpc/auth_gss/auth_gss.c          |   2 +-
 net/sunrpc/auth_gss/gss_generic_token.c |   2 +-
 net/sunrpc/auth_gss/gss_krb5_crypto.c   |   2 +-
 net/sunrpc/auth_gss/gss_krb5_keys.c     |   2 +-
 net/sunrpc/auth_gss/gss_krb5_mech.c     |   2 +-
 net/sunrpc/auth_gss/gss_krb5_seal.c     |   2 +-
 net/sunrpc/auth_gss/gss_krb5_seqnum.c   |   2 +-
 net/sunrpc/auth_gss/gss_krb5_unseal.c   |   2 +-
 net/sunrpc/auth_gss/gss_krb5_wrap.c     |   2 +-
 net/sunrpc/auth_gss/gss_mech_switch.c   |   2 +-
 net/sunrpc/auth_gss/gss_rpc_xdr.h       |   2 +-
 net/sunrpc/auth_gss/svcauth_gss.c       |   2 +-
 net/sunrpc/auth_null.c                  |   4 +-
 net/sunrpc/auth_unix.c                  |   2 +-
 net/sunrpc/backchannel_rqst.c           |   2 +-
 net/sunrpc/clnt.c                       |  16 +-
 net/sunrpc/debugfs.c                    | 292 ++++++++++++++++++++++++++++++++
 net/sunrpc/rpcb_clnt.c                  |   2 +-
 net/sunrpc/sched.c                      |   4 +-
 net/sunrpc/sunrpc_syms.c                |  12 +-
 net/sunrpc/svc.c                        |   2 +-
 net/sunrpc/sysctl.c                     |   2 +-
 net/sunrpc/xprt.c                       |  10 +-
 net/sunrpc/xprtrdma/rpc_rdma.c          |   4 +-
 net/sunrpc/xprtrdma/transport.c         |   8 +-
 net/sunrpc/xprtrdma/verbs.c             |   8 +-
 net/sunrpc/xprtsock.c                   |   8 +-
 39 files changed, 427 insertions(+), 72 deletions(-)
 create mode 100644 net/sunrpc/debugfs.c

-- 
2.1.0


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v3 1/5] lockd: eliminate LOCKD_DEBUG
  2014-11-26 19:44   ` [PATCH v3 0/5] sunrpc: add some debugfs files for dumping task and xprt info Jeff Layton
@ 2014-11-26 19:44     ` Jeff Layton
  2014-11-26 19:44     ` [PATCH v3 2/5] sunrpc: eliminate RPC_DEBUG Jeff Layton
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-26 19:44 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

LOCKD_DEBUG is always the same value as CONFIG_SUNRPC_DEBUG, so we can
just use it instead.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
---
 fs/lockd/svclock.c          | 2 +-
 include/linux/lockd/debug.h | 6 +-----
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 13db95f54176..56598742dde4 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -53,7 +53,7 @@ static const struct rpc_call_ops nlmsvc_grant_ops;
 static LIST_HEAD(nlm_blocked);
 static DEFINE_SPINLOCK(nlm_blocked_lock);
 
-#ifdef LOCKD_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie)
 {
 	/*
diff --git a/include/linux/lockd/debug.h b/include/linux/lockd/debug.h
index 257d3779f2ab..0ca8109934e4 100644
--- a/include/linux/lockd/debug.h
+++ b/include/linux/lockd/debug.h
@@ -17,12 +17,8 @@
  * Enable lockd debugging.
  * Requires RPC_DEBUG.
  */
-#ifdef RPC_DEBUG
-# define LOCKD_DEBUG		1
-#endif
-
 #undef ifdebug
-#if defined(RPC_DEBUG) && defined(LOCKD_DEBUG)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define ifdebug(flag)		if (unlikely(nlm_debug & NLMDBG_##flag))
 #else
 # define ifdebug(flag)		if (0)
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 2/5] sunrpc: eliminate RPC_DEBUG
  2014-11-26 19:44   ` [PATCH v3 0/5] sunrpc: add some debugfs files for dumping task and xprt info Jeff Layton
  2014-11-26 19:44     ` [PATCH v3 1/5] lockd: eliminate LOCKD_DEBUG Jeff Layton
@ 2014-11-26 19:44     ` Jeff Layton
  2014-11-26 19:44     ` [PATCH v3 3/5] sunrpc: eliminate RPC_TRACEPOINTS Jeff Layton
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-26 19:44 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

It's always set to whatever CONFIG_SUNRPC_DEBUG is, so just use that.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
---
 include/linux/sunrpc/auth.h             | 2 +-
 include/linux/sunrpc/debug.h            | 9 +++------
 include/linux/sunrpc/sched.h            | 8 ++++----
 include/uapi/linux/nfsd/debug.h         | 2 +-
 net/sunrpc/auth.c                       | 4 ++--
 net/sunrpc/auth_generic.c               | 2 +-
 net/sunrpc/auth_gss/auth_gss.c          | 2 +-
 net/sunrpc/auth_gss/gss_generic_token.c | 2 +-
 net/sunrpc/auth_gss/gss_krb5_crypto.c   | 2 +-
 net/sunrpc/auth_gss/gss_krb5_keys.c     | 2 +-
 net/sunrpc/auth_gss/gss_krb5_mech.c     | 2 +-
 net/sunrpc/auth_gss/gss_krb5_seal.c     | 2 +-
 net/sunrpc/auth_gss/gss_krb5_seqnum.c   | 2 +-
 net/sunrpc/auth_gss/gss_krb5_unseal.c   | 2 +-
 net/sunrpc/auth_gss/gss_krb5_wrap.c     | 2 +-
 net/sunrpc/auth_gss/gss_mech_switch.c   | 2 +-
 net/sunrpc/auth_gss/gss_rpc_xdr.h       | 2 +-
 net/sunrpc/auth_gss/svcauth_gss.c       | 2 +-
 net/sunrpc/auth_null.c                  | 4 ++--
 net/sunrpc/auth_unix.c                  | 2 +-
 net/sunrpc/backchannel_rqst.c           | 2 +-
 net/sunrpc/clnt.c                       | 6 +++---
 net/sunrpc/rpcb_clnt.c                  | 2 +-
 net/sunrpc/sched.c                      | 4 ++--
 net/sunrpc/sunrpc_syms.c                | 4 ++--
 net/sunrpc/svc.c                        | 2 +-
 net/sunrpc/sysctl.c                     | 2 +-
 net/sunrpc/xprt.c                       | 2 +-
 net/sunrpc/xprtrdma/rpc_rdma.c          | 4 ++--
 net/sunrpc/xprtrdma/transport.c         | 8 ++++----
 net/sunrpc/xprtrdma/verbs.c             | 8 ++++----
 net/sunrpc/xprtsock.c                   | 8 ++++----
 32 files changed, 53 insertions(+), 56 deletions(-)

diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 8e030075fe79..a7cbb570cc5c 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -53,7 +53,7 @@ struct rpc_cred {
 	struct rcu_head		cr_rcu;
 	struct rpc_auth *	cr_auth;
 	const struct rpc_credops *cr_ops;
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	unsigned long		cr_magic;	/* 0x0f4aa4f0 */
 #endif
 	unsigned long		cr_expire;	/* when to gc */
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 9385bd74c860..51143757b8f7 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -14,9 +14,6 @@
 /*
  * Enable RPC debugging/profiling.
  */
-#ifdef CONFIG_SUNRPC_DEBUG
-#define  RPC_DEBUG
-#endif
 #ifdef CONFIG_TRACEPOINTS
 #define RPC_TRACEPOINTS
 #endif
@@ -25,7 +22,7 @@
 /*
  * Debugging macros etc
  */
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 extern unsigned int		rpc_debug;
 extern unsigned int		nfs_debug;
 extern unsigned int		nfsd_debug;
@@ -36,7 +33,7 @@ extern unsigned int		nlm_debug;
 #define dprintk_rcu(args...)	dfprintk_rcu(FACILITY, ## args)
 
 #undef ifdebug
-#ifdef RPC_DEBUG			
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define ifdebug(fac)		if (unlikely(rpc_debug & RPCDBG_##fac))
 
 # define dfprintk(fac, args...)	\
@@ -65,7 +62,7 @@ extern unsigned int		nlm_debug;
 /*
  * Sysctl interface for RPC debugging
  */
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 void		rpc_register_sysctl(void);
 void		rpc_unregister_sysctl(void);
 #endif
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 1a8959944c5f..fecdbf1b4797 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -79,7 +79,7 @@ struct rpc_task {
 	unsigned short		tk_flags;	/* misc flags */
 	unsigned short		tk_timeouts;	/* maj timeouts */
 
-#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
 	unsigned short		tk_pid;		/* debugging aid */
 #endif
 	unsigned char		tk_priority : 2,/* Task priority */
@@ -187,7 +187,7 @@ struct rpc_wait_queue {
 	unsigned char		nr;			/* # tasks remaining for cookie */
 	unsigned short		qlen;			/* total # tasks waiting in queue */
 	struct rpc_timer	timer_list;
-#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
 	const char *		name;
 #endif
 };
@@ -237,7 +237,7 @@ void		rpc_free(void *);
 int		rpciod_up(void);
 void		rpciod_down(void);
 int		__rpc_wait_for_completion_task(struct rpc_task *task, wait_bit_action_f *);
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 struct net;
 void		rpc_show_tasks(struct net *);
 #endif
@@ -251,7 +251,7 @@ static inline int rpc_wait_for_completion_task(struct rpc_task *task)
 	return __rpc_wait_for_completion_task(task, NULL);
 }
 
-#if defined(RPC_DEBUG) || defined (RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined (RPC_TRACEPOINTS)
 static inline const char * rpc_qname(const struct rpc_wait_queue *q)
 {
 	return ((q && q->name) ? q->name : "unknown");
diff --git a/include/uapi/linux/nfsd/debug.h b/include/uapi/linux/nfsd/debug.h
index a6f453c740b8..1fdc95bb2375 100644
--- a/include/uapi/linux/nfsd/debug.h
+++ b/include/uapi/linux/nfsd/debug.h
@@ -15,7 +15,7 @@
  * Enable debugging for nfsd.
  * Requires RPC_DEBUG.
  */
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define NFSD_DEBUG		1
 #endif
 
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 383eb919ac0b..47f38be4155f 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -16,7 +16,7 @@
 #include <linux/sunrpc/gss_api.h>
 #include <linux/spinlock.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
@@ -646,7 +646,7 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
 	cred->cr_auth = auth;
 	cred->cr_ops = ops;
 	cred->cr_expire = jiffies;
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	cred->cr_magic = RPCAUTH_CRED_MAGIC;
 #endif
 	cred->cr_uid = acred->uid;
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index 6f6b829c9e8e..41248b1820c7 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -14,7 +14,7 @@
 #include <linux/sunrpc/debug.h>
 #include <linux/sunrpc/sched.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 53ed8d3f8897..dace13d7638e 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -66,7 +66,7 @@ static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
 #define GSS_KEY_EXPIRE_TIMEO 240
 static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO;
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c
index c586e92bcf76..254defe446a7 100644
--- a/net/sunrpc/auth_gss/gss_generic_token.c
+++ b/net/sunrpc/auth_gss/gss_generic_token.c
@@ -38,7 +38,7 @@
 #include <linux/sunrpc/gss_asn1.h>
 
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index f5ed9f6ece06..b5408e8a37f2 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -45,7 +45,7 @@
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/sunrpc/xdr.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c
index 24589bd2a4b6..234fa8d0fd9b 100644
--- a/net/sunrpc/auth_gss/gss_krb5_keys.c
+++ b/net/sunrpc/auth_gss/gss_krb5_keys.c
@@ -61,7 +61,7 @@
 #include <linux/sunrpc/xdr.h>
 #include <linux/lcm.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 0d3c158ef8fa..28db442a0034 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -45,7 +45,7 @@
 #include <linux/crypto.h>
 #include <linux/sunrpc/gss_krb5_enctypes.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
index 42768e5c3994..1d74d653e6c0 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
@@ -64,7 +64,7 @@
 #include <linux/random.h>
 #include <linux/crypto.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
index 62ac90c62cb1..20d55c793eb6 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seqnum.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
@@ -35,7 +35,7 @@
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/crypto.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
index 6c981ddc19f8..dcf9515d9aef 100644
--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
@@ -62,7 +62,7 @@
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/crypto.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index 4b614c604fe0..ca7e92a32f84 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -35,7 +35,7 @@
 #include <linux/pagemap.h>
 #include <linux/crypto.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index 92d5ab99fbf3..7063d856a598 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -46,7 +46,7 @@
 #include <linux/sunrpc/gss_api.h>
 #include <linux/sunrpc/clnt.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.h b/net/sunrpc/auth_gss/gss_rpc_xdr.h
index 685a688f3d8a..9d88c6239f01 100644
--- a/net/sunrpc/auth_gss/gss_rpc_xdr.h
+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.h
@@ -25,7 +25,7 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/xprtsock.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index c548ab213f76..de856ddf5fed 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -51,7 +51,7 @@
 #include "gss_rpc_upcall.h"
 
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index 712c123e04e9..c2a2b584a056 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -10,7 +10,7 @@
 #include <linux/module.h>
 #include <linux/sunrpc/clnt.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
@@ -138,7 +138,7 @@ struct rpc_cred null_cred = {
 	.cr_ops		= &null_credops,
 	.cr_count	= ATOMIC_INIT(1),
 	.cr_flags	= 1UL << RPCAUTH_CRED_UPTODATE,
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	.cr_magic	= RPCAUTH_CRED_MAGIC,
 #endif
 };
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index d5d692366294..4feda2d0a833 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -25,7 +25,7 @@ struct unx_cred {
 
 #define UNX_WRITESLACK		(21 + (UNX_MAXNODENAME >> 2))
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
index 9761a0da964d..651f49ab601f 100644
--- a/net/sunrpc/backchannel_rqst.c
+++ b/net/sunrpc/backchannel_rqst.c
@@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <linux/export.h>
 #include <linux/sunrpc/bc_xprt.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 #define RPCDBG_FACILITY	RPCDBG_TRANS
 #endif
 
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 9acd6ce88db7..36c64ef460cf 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -42,7 +42,7 @@
 #include "sunrpc.h"
 #include "netns.h"
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_CALL
 #endif
 
@@ -1396,7 +1396,7 @@ rpc_restart_call(struct rpc_task *task)
 }
 EXPORT_SYMBOL_GPL(rpc_restart_call);
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static const char *rpc_proc_name(const struct rpc_task *task)
 {
 	const struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
@@ -2421,7 +2421,7 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int
 }
 EXPORT_SYMBOL_GPL(rpc_call_null);
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static void rpc_show_header(void)
 {
 	printk(KERN_INFO "-pid- flgs status -client- --rqstp- "
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 1891a1022c17..05202012bcfc 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -32,7 +32,7 @@
 
 #include "netns.h"
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_BIND
 #endif
 
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index fe3441abdbe5..574b2977fc4b 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -24,7 +24,7 @@
 
 #include "sunrpc.h"
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 #define RPCDBG_FACILITY		RPCDBG_SCHED
 #endif
 
@@ -258,7 +258,7 @@ static int rpc_wait_bit_killable(struct wait_bit_key *key)
 	return 0;
 }
 
-#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
 static void rpc_task_set_debuginfo(struct rpc_task *task)
 {
 	static atomic_t rpc_pid;
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index cd30120de9e4..f632e476ab6c 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -97,7 +97,7 @@ init_sunrpc(void)
 	err = register_rpc_pipefs();
 	if (err)
 		goto out4;
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	rpc_register_sysctl();
 #endif
 	svc_init_xprt_sock();	/* svc sock transport */
@@ -123,7 +123,7 @@ cleanup_sunrpc(void)
 	unregister_rpc_pipefs();
 	rpc_destroy_mempool();
 	unregister_pernet_subsys(&sunrpc_net_ops);
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	rpc_unregister_sysctl();
 #endif
 	rcu_barrier(); /* Wait for completion of call_rcu()'s */
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 371a8bbb43d6..2783fd80c229 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1042,7 +1042,7 @@ static void svc_unregister(const struct svc_serv *serv, struct net *net)
 /*
  * dprintk the given error with the address of the client that caused it.
  */
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static __printf(2, 3)
 void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
 {
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index c99c58e2ee66..887f0183b4c6 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -37,7 +37,7 @@ EXPORT_SYMBOL_GPL(nfsd_debug);
 unsigned int	nlm_debug;
 EXPORT_SYMBOL_GPL(nlm_debug);
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 
 static struct ctl_table_header *sunrpc_table_header;
 static struct ctl_table sunrpc_table[];
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 1b2e5e616cae..894d071426b2 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -57,7 +57,7 @@
  * Local variables
  */
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_XPRT
 #endif
 
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index 6166c985fe24..df01d124936c 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -49,11 +49,11 @@
 
 #include <linux/highmem.h>
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_TRANS
 #endif
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static const char transfertypes[][12] = {
 	"pure inline",	/* no chunks */
 	" read chunk",	/* some argument via rdma read */
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 6a4615dd0261..ef58ebadb3ae 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -55,7 +55,7 @@
 
 #include "xprt_rdma.h"
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_TRANS
 #endif
 
@@ -75,7 +75,7 @@ static unsigned int xprt_rdma_inline_write_padding;
 static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR;
                 int xprt_rdma_pad_optimize = 0;
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 
 static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE;
 static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE;
@@ -705,7 +705,7 @@ static void __exit xprt_rdma_cleanup(void)
 	int rc;
 
 	dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n");
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	if (sunrpc_table_header) {
 		unregister_sysctl_table(sunrpc_table_header);
 		sunrpc_table_header = NULL;
@@ -736,7 +736,7 @@ static int __init xprt_rdma_init(void)
 	dprintk("\tPadding %d\n\tMemreg %d\n",
 		xprt_rdma_inline_write_padding, xprt_rdma_memreg_strategy);
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	if (!sunrpc_table_header)
 		sunrpc_table_header = register_sysctl_table(sunrpc_table);
 #endif
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 61c41298b4ea..b92b04083e40 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -57,7 +57,7 @@
  * Globals/Macros
  */
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY	RPCDBG_TRANS
 #endif
 
@@ -313,7 +313,7 @@ rpcrdma_flush_cqs(struct rpcrdma_ep *ep)
 	rpcrdma_sendcq_upcall(ep->rep_attr.send_cq, ep);
 }
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 static const char * const conn[] = {
 	"address resolved",
 	"address error",
@@ -344,7 +344,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
 	struct rpcrdma_xprt *xprt = id->context;
 	struct rpcrdma_ia *ia = &xprt->rx_ia;
 	struct rpcrdma_ep *ep = &xprt->rx_ep;
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	struct sockaddr_in *addr = (struct sockaddr_in *) &ep->rep_remote_addr;
 #endif
 	struct ib_qp_attr attr;
@@ -408,7 +408,7 @@ connected:
 		break;
 	}
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	if (connstate == 1) {
 		int ird = attr.max_dest_rd_atomic;
 		int tird = ep->rep_remote_cma.responder_resources;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 31c015196a29..87ce7e8bb8dc 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -75,7 +75,7 @@ static unsigned int xs_tcp_fin_timeout __read_mostly = XS_TCP_LINGER_TO;
  * someone else's file names!
  */
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 
 static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
 static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
@@ -186,7 +186,7 @@ static struct ctl_table sunrpc_table[] = {
  */
 #define XS_IDLE_DISC_TO		(5U * 60 * HZ)
 
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # undef  RPC_DEBUG_DATA
 # define RPCDBG_FACILITY	RPCDBG_TRANS
 #endif
@@ -2991,7 +2991,7 @@ static struct xprt_class	xs_bc_tcp_transport = {
  */
 int init_socket_xprt(void)
 {
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	if (!sunrpc_table_header)
 		sunrpc_table_header = register_sysctl_table(sunrpc_table);
 #endif
@@ -3010,7 +3010,7 @@ int init_socket_xprt(void)
  */
 void cleanup_socket_xprt(void)
 {
-#ifdef RPC_DEBUG
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	if (sunrpc_table_header) {
 		unregister_sysctl_table(sunrpc_table_header);
 		sunrpc_table_header = NULL;
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 3/5] sunrpc: eliminate RPC_TRACEPOINTS
  2014-11-26 19:44   ` [PATCH v3 0/5] sunrpc: add some debugfs files for dumping task and xprt info Jeff Layton
  2014-11-26 19:44     ` [PATCH v3 1/5] lockd: eliminate LOCKD_DEBUG Jeff Layton
  2014-11-26 19:44     ` [PATCH v3 2/5] sunrpc: eliminate RPC_DEBUG Jeff Layton
@ 2014-11-26 19:44     ` Jeff Layton
  2014-11-26 19:44     ` [PATCH v3 4/5] sunrpc: add debugfs file for displaying client rpc_task queue Jeff Layton
  2014-11-26 19:44     ` [PATCH v3 5/5] sunrpc: add a debugfs rpc_xprt directory with an info file in it Jeff Layton
  4 siblings, 0 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-26 19:44 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

It's always set to the same value as CONFIG_TRACEPOINTS, so we can just
use that instead.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
---
 include/linux/sunrpc/debug.h | 9 ---------
 include/linux/sunrpc/sched.h | 6 +++---
 net/sunrpc/sched.c           | 2 +-
 3 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 51143757b8f7..43f38ee9668c 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -10,15 +10,6 @@
 
 #include <uapi/linux/sunrpc/debug.h>
 
-
-/*
- * Enable RPC debugging/profiling.
- */
-#ifdef CONFIG_TRACEPOINTS
-#define RPC_TRACEPOINTS
-#endif
-/* #define  RPC_PROFILE */
-
 /*
  * Debugging macros etc
  */
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index fecdbf1b4797..5f1e6bd4c316 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -79,7 +79,7 @@ struct rpc_task {
 	unsigned short		tk_flags;	/* misc flags */
 	unsigned short		tk_timeouts;	/* maj timeouts */
 
-#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
 	unsigned short		tk_pid;		/* debugging aid */
 #endif
 	unsigned char		tk_priority : 2,/* Task priority */
@@ -187,7 +187,7 @@ struct rpc_wait_queue {
 	unsigned char		nr;			/* # tasks remaining for cookie */
 	unsigned short		qlen;			/* total # tasks waiting in queue */
 	struct rpc_timer	timer_list;
-#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
 	const char *		name;
 #endif
 };
@@ -251,7 +251,7 @@ static inline int rpc_wait_for_completion_task(struct rpc_task *task)
 	return __rpc_wait_for_completion_task(task, NULL);
 }
 
-#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined (RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
 static inline const char * rpc_qname(const struct rpc_wait_queue *q)
 {
 	return ((q && q->name) ? q->name : "unknown");
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 574b2977fc4b..d20f2329eea3 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -258,7 +258,7 @@ static int rpc_wait_bit_killable(struct wait_bit_key *key)
 	return 0;
 }
 
-#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
 static void rpc_task_set_debuginfo(struct rpc_task *task)
 {
 	static atomic_t rpc_pid;
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 4/5] sunrpc: add debugfs file for displaying client rpc_task queue
  2014-11-26 19:44   ` [PATCH v3 0/5] sunrpc: add some debugfs files for dumping task and xprt info Jeff Layton
                       ` (2 preceding siblings ...)
  2014-11-26 19:44     ` [PATCH v3 3/5] sunrpc: eliminate RPC_TRACEPOINTS Jeff Layton
@ 2014-11-26 19:44     ` Jeff Layton
  2014-11-26 20:13       ` Anna Schumaker
  2014-11-26 19:44     ` [PATCH v3 5/5] sunrpc: add a debugfs rpc_xprt directory with an info file in it Jeff Layton
  4 siblings, 1 reply; 19+ messages in thread
From: Jeff Layton @ 2014-11-26 19:44 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

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: Jeff Layton <jlayton@primarydata.com>
---
 include/linux/sunrpc/clnt.h  |   4 +
 include/linux/sunrpc/debug.h |  31 +++++++
 net/sunrpc/Kconfig           |   1 +
 net/sunrpc/Makefile          |   1 +
 net/sunrpc/clnt.c            |  10 ++-
 net/sunrpc/debugfs.c         | 191 +++++++++++++++++++++++++++++++++++++++++++
 net/sunrpc/sunrpc_syms.c     |   8 ++
 7 files changed, 245 insertions(+), 1 deletion(-)
 create mode 100644 net/sunrpc/debugfs.c

diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 70736b98c721..d86acc63b25f 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -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 */
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 43f38ee9668c..835339707094 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -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_ */
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index 0754d0f466d2..fb78117b896c 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -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
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index e5a7a1cac8f3..15e6f6c23c5d 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -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
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 36c64ef460cf..05da12a33945 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -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;
 
diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
new file mode 100644
index 000000000000..3d7745683ca3
--- /dev/null
+++ b/net/sunrpc/debugfs.c
@@ -0,0 +1,191 @@
+/**
+ * debugfs interface for sunrpc
+ *
+ * (c) 2014 Jeff Layton <jlayton@primarydata.com>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/clnt.h>
+#include "netns.h"
+
+static struct dentry *topdir;
+static struct dentry *rpc_clnt_dir;
+
+struct rpc_clnt_iter {
+	struct rpc_clnt	*clnt;
+	loff_t		pos;
+};
+
+static int
+tasks_show(struct seq_file *f, void *v)
+{
+	u32 xid = 0;
+	struct rpc_task *task = v;
+	struct rpc_clnt *clnt = task->tk_client;
+	const char *rpc_waitq = "none";
+
+	if (RPC_IS_QUEUED(task))
+		rpc_waitq = rpc_qname(task->tk_waitqueue);
+
+	if (task->tk_rqstp)
+		xid = be32_to_cpu(task->tk_rqstp->rq_xid);
+
+	seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
+		task->tk_pid, task->tk_flags, task->tk_status,
+		clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
+		clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
+		task->tk_action, rpc_waitq);
+	return 0;
+}
+
+static void *
+tasks_start(struct seq_file *f, loff_t *ppos)
+	__acquires(&clnt->cl_lock)
+{
+	struct rpc_clnt_iter *iter = f->private;
+	loff_t pos = *ppos;
+	struct rpc_clnt *clnt = iter->clnt;
+	struct rpc_task *task;
+
+	iter->pos = pos + 1;
+	spin_lock(&clnt->cl_lock);
+	list_for_each_entry(task, &clnt->cl_tasks, tk_task)
+		if (pos-- == 0)
+			return task;
+	return NULL;
+}
+
+static void *
+tasks_next(struct seq_file *f, void *v, loff_t *pos)
+{
+	struct rpc_clnt_iter *iter = f->private;
+	struct rpc_clnt *clnt = iter->clnt;
+	struct rpc_task *task = v;
+	struct list_head *next = task->tk_task.next;
+
+	++iter->pos;
+	++*pos;
+
+	/* If there's another task on list, return it */
+	if (next == &clnt->cl_tasks)
+		return NULL;
+	return list_entry(next, struct rpc_task, tk_task);
+}
+
+static void
+tasks_stop(struct seq_file *f, void *v)
+	__releases(&clnt->cl_lock)
+{
+	struct rpc_clnt_iter *iter = f->private;
+	struct rpc_clnt *clnt = iter->clnt;
+
+	spin_unlock(&clnt->cl_lock);
+}
+
+static const struct seq_operations tasks_seq_operations = {
+	.start	= tasks_start,
+	.next	= tasks_next,
+	.stop	= tasks_stop,
+	.show	= tasks_show,
+};
+
+static int tasks_open(struct inode *inode, struct file *filp)
+{
+	int ret = seq_open_private(filp, &tasks_seq_operations,
+					sizeof(struct rpc_clnt_iter));
+
+	if (!ret) {
+		struct seq_file *seq = filp->private_data;
+		struct rpc_clnt_iter *iter = seq->private;
+
+		iter->clnt = inode->i_private;
+
+		if (!atomic_inc_not_zero(&iter->clnt->cl_count)) {
+			seq_release_private(inode, filp);
+			ret = -EINVAL;
+		}
+	}
+
+	return ret;
+}
+
+static int
+tasks_release(struct inode *inode, struct file *filp)
+{
+	struct seq_file *seq = filp->private_data;
+	struct rpc_clnt_iter *iter = seq->private;
+
+	rpc_release_client(iter->clnt);
+	return seq_release_private(inode, filp);
+}
+
+static const struct file_operations tasks_fops = {
+	.owner		= THIS_MODULE,
+	.open		= tasks_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= tasks_release,
+};
+
+int
+rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
+{
+	int len;
+	char name[9]; /* 8 for hex digits + NULL terminator */
+
+	/* Already registered? */
+	if (clnt->cl_debugfs)
+		return 0;
+
+	len = snprintf(name, sizeof(name), "%x", clnt->cl_clid);
+	if (len >= sizeof(name))
+		return -EINVAL;
+
+	/* make the per-client dir */
+	clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir);
+	if (!clnt->cl_debugfs)
+		return -ENOMEM;
+
+	/* make tasks file */
+	if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs,
+				 clnt, &tasks_fops)) {
+		debugfs_remove_recursive(clnt->cl_debugfs);
+		clnt->cl_debugfs = NULL;
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void
+rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
+{
+	debugfs_remove_recursive(clnt->cl_debugfs);
+	clnt->cl_debugfs = NULL;
+}
+
+void __exit
+sunrpc_debugfs_exit(void)
+{
+	debugfs_remove_recursive(topdir);
+}
+
+int __init
+sunrpc_debugfs_init(void)
+{
+	topdir = debugfs_create_dir("sunrpc", NULL);
+	if (!topdir)
+		goto out;
+
+	rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir);
+	if (!rpc_clnt_dir)
+		goto out_remove;
+
+	return 0;
+out_remove:
+	debugfs_remove_recursive(topdir);
+	topdir = NULL;
+out:
+	return -ENOMEM;
+}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index f632e476ab6c..e37fbed87956 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -97,6 +97,11 @@ init_sunrpc(void)
 	err = register_rpc_pipefs();
 	if (err)
 		goto out4;
+
+	err = sunrpc_debugfs_init();
+	if (err)
+		goto out5;
+
 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 	rpc_register_sysctl();
 #endif
@@ -104,6 +109,8 @@ init_sunrpc(void)
 	init_socket_xprt();	/* clnt sock transport */
 	return 0;
 
+out5:
+	unregister_rpc_pipefs();
 out4:
 	unregister_pernet_subsys(&sunrpc_net_ops);
 out3:
@@ -120,6 +127,7 @@ cleanup_sunrpc(void)
 	rpcauth_remove_module();
 	cleanup_socket_xprt();
 	svc_cleanup_xprt_sock();
+	sunrpc_debugfs_exit();
 	unregister_rpc_pipefs();
 	rpc_destroy_mempool();
 	unregister_pernet_subsys(&sunrpc_net_ops);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 5/5] sunrpc: add a debugfs rpc_xprt directory with an info file in it
  2014-11-26 19:44   ` [PATCH v3 0/5] sunrpc: add some debugfs files for dumping task and xprt info Jeff Layton
                       ` (3 preceding siblings ...)
  2014-11-26 19:44     ` [PATCH v3 4/5] sunrpc: add debugfs file for displaying client rpc_task queue Jeff Layton
@ 2014-11-26 19:44     ` Jeff Layton
  4 siblings, 0 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-26 19:44 UTC (permalink / raw)
  To: trond.myklebust; +Cc: Anna Schumaker, bfields, linux-nfs

Add a new directory heirarchy under the debugfs sunrpc/ directory:

    sunrpc/
        rpc_xprt/
            <xprt id>/

Within that directory, we can put files that give info about the
xprts. We do have the (minor) problem that there is no succinct,
unique identifier for rpc_xprts. So we generate them synthetically
with a static atomic_t counter.

For now, this directory just holds an "info" file, but we may add
other files to it in the future.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
---
 include/linux/sunrpc/debug.h |  15 ++++++
 include/linux/sunrpc/xprt.h  |   3 ++
 net/sunrpc/debugfs.c         | 115 ++++++++++++++++++++++++++++++++++++++++---
 net/sunrpc/xprt.c            |   8 +++
 4 files changed, 134 insertions(+), 7 deletions(-)

diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 835339707094..c57d8ea0716c 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -55,6 +55,7 @@ extern unsigned int		nlm_debug;
  */
 
 struct rpc_clnt;
+struct rpc_xprt;
 
 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 void		rpc_register_sysctl(void);
@@ -63,6 +64,8 @@ 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 *);
+int		rpc_xprt_debugfs_register(struct rpc_xprt *);
+void		rpc_xprt_debugfs_unregister(struct rpc_xprt *);
 #else
 static inline int
 sunrpc_debugfs_init(void)
@@ -87,6 +90,18 @@ rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
 {
 	return;
 }
+
+static inline int
+rpc_xprt_debugfs_register(struct rpc_xprt *xprt)
+{
+	return 0;
+}
+
+static inline void
+rpc_xprt_debugfs_unregister(struct rpc_xprt *xprt)
+{
+	return;
+}
 #endif
 
 #endif /* _LINUX_SUNRPC_DEBUG_H_ */
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index cf391eef2e6d..9d27ac45b909 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -239,6 +239,9 @@ struct rpc_xprt {
 	struct net		*xprt_net;
 	const char		*servername;
 	const char		*address_strings[RPC_DISPLAY_MAX];
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
+	struct dentry		*debugfs;		/* debugfs directory */
+#endif
 };
 
 #if defined(CONFIG_SUNRPC_BACKCHANNEL)
diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
index 3d7745683ca3..e811f390f9f6 100644
--- a/net/sunrpc/debugfs.c
+++ b/net/sunrpc/debugfs.c
@@ -11,6 +11,7 @@
 
 static struct dentry *topdir;
 static struct dentry *rpc_clnt_dir;
+static struct dentry *rpc_xprt_dir;
 
 struct rpc_clnt_iter {
 	struct rpc_clnt	*clnt;
@@ -131,8 +132,8 @@ static const struct file_operations tasks_fops = {
 int
 rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
 {
-	int len;
-	char name[9]; /* 8 for hex digits + NULL terminator */
+	int len, err;
+	char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */
 
 	/* Already registered? */
 	if (clnt->cl_debugfs)
@@ -148,14 +149,28 @@ rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
 		return -ENOMEM;
 
 	/* make tasks file */
+	err = -ENOMEM;
 	if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs,
-				 clnt, &tasks_fops)) {
-		debugfs_remove_recursive(clnt->cl_debugfs);
-		clnt->cl_debugfs = NULL;
-		return -ENOMEM;
-	}
+				 clnt, &tasks_fops))
+		goto out_err;
+
+	err = -EINVAL;
+	rcu_read_lock();
+	len = snprintf(name, sizeof(name), "../../rpc_xprt/%s",
+			rcu_dereference(clnt->cl_xprt)->debugfs->d_name.name);
+	rcu_read_unlock();
+	if (len >= sizeof(name))
+		goto out_err;
+
+	err = -ENOMEM;
+	if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name))
+		goto out_err;
 
 	return 0;
+out_err:
+	debugfs_remove_recursive(clnt->cl_debugfs);
+	clnt->cl_debugfs = NULL;
+	return err;
 }
 
 void
@@ -165,6 +180,88 @@ rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
 	clnt->cl_debugfs = NULL;
 }
 
+static int
+xprt_info_show(struct seq_file *f, void *v)
+{
+	struct rpc_xprt *xprt = f->private;
+
+	seq_printf(f, "netid: %s\n", xprt->address_strings[RPC_DISPLAY_NETID]);
+	seq_printf(f, "addr:  %s\n", xprt->address_strings[RPC_DISPLAY_ADDR]);
+	seq_printf(f, "port:  %s\n", xprt->address_strings[RPC_DISPLAY_PORT]);
+	seq_printf(f, "state: 0x%lx\n", xprt->state);
+	return 0;
+}
+
+static int
+xprt_info_open(struct inode *inode, struct file *filp)
+{
+	int ret;
+	struct rpc_xprt *xprt = inode->i_private;
+
+	ret = single_open(filp, xprt_info_show, xprt);
+
+	if (!ret) {
+		if (!xprt_get(xprt)) {
+			single_release(inode, filp);
+			ret = -EINVAL;
+		}
+	}
+	return ret;
+}
+
+static int
+xprt_info_release(struct inode *inode, struct file *filp)
+{
+	struct rpc_xprt *xprt = inode->i_private;
+
+	xprt_put(xprt);
+	return single_release(inode, filp);
+}
+
+static const struct file_operations xprt_info_fops = {
+	.owner		= THIS_MODULE,
+	.open		= xprt_info_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= xprt_info_release,
+};
+
+int
+rpc_xprt_debugfs_register(struct rpc_xprt *xprt)
+{
+	int len, id;
+	static atomic_t	cur_id;
+	char		name[9]; /* 8 hex digits + NULL term */
+
+	id = (unsigned int)atomic_inc_return(&cur_id);
+
+	len = snprintf(name, sizeof(name), "%x", id);
+	if (len >= sizeof(name))
+		return -EINVAL;
+
+	/* make the per-client dir */
+	xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir);
+	if (!xprt->debugfs)
+		return -ENOMEM;
+
+	/* make tasks file */
+	if (!debugfs_create_file("info", S_IFREG | S_IRUSR, xprt->debugfs,
+				 xprt, &xprt_info_fops)) {
+		debugfs_remove_recursive(xprt->debugfs);
+		xprt->debugfs = NULL;
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void
+rpc_xprt_debugfs_unregister(struct rpc_xprt *xprt)
+{
+	debugfs_remove_recursive(xprt->debugfs);
+	xprt->debugfs = NULL;
+}
+
 void __exit
 sunrpc_debugfs_exit(void)
 {
@@ -182,6 +279,10 @@ sunrpc_debugfs_init(void)
 	if (!rpc_clnt_dir)
 		goto out_remove;
 
+	rpc_xprt_dir = debugfs_create_dir("rpc_xprt", topdir);
+	if (!rpc_xprt_dir)
+		goto out_remove;
+
 	return 0;
 out_remove:
 	debugfs_remove_recursive(topdir);
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 894d071426b2..ebbefad21a37 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -1303,6 +1303,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net)
  */
 struct rpc_xprt *xprt_create_transport(struct xprt_create *args)
 {
+	int err;
 	struct rpc_xprt	*xprt;
 	struct xprt_class *t;
 
@@ -1343,6 +1344,12 @@ found:
 		return ERR_PTR(-ENOMEM);
 	}
 
+	err = rpc_xprt_debugfs_register(xprt);
+	if (err) {
+		xprt_destroy(xprt);
+		return ERR_PTR(err);
+	}
+
 	dprintk("RPC:       created transport %p with %u slots\n", xprt,
 			xprt->max_reqs);
 out:
@@ -1359,6 +1366,7 @@ static void xprt_destroy(struct rpc_xprt *xprt)
 	dprintk("RPC:       destroying transport %p\n", xprt);
 	del_timer_sync(&xprt->timer);
 
+	rpc_xprt_debugfs_unregister(xprt);
 	rpc_destroy_wait_queue(&xprt->binding);
 	rpc_destroy_wait_queue(&xprt->pending);
 	rpc_destroy_wait_queue(&xprt->sending);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 4/5] sunrpc: add debugfs file for displaying client rpc_task queue
  2014-11-26 19:44     ` [PATCH v3 4/5] sunrpc: add debugfs file for displaying client rpc_task queue Jeff Layton
@ 2014-11-26 20:13       ` Anna Schumaker
  2014-11-26 20:15         ` Anna Schumaker
  0 siblings, 1 reply; 19+ messages in thread
From: Anna Schumaker @ 2014-11-26 20:13 UTC (permalink / raw)
  To: Jeff Layton, trond.myklebust; +Cc: bfields, linux-nfs

Hi Jeff,

On 11/26/2014 02:44 PM, Jeff Layton wrote:
> 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.

What do I have to do to get tasks to show up in the tasks file?  I'm running xfstests and occasionally running "cat" on 0/tasks and 3/tasks, but both are empty.

Anna

> 
> Signed-off-by: Jeff Layton <jlayton@primarydata.com>
> ---
>  include/linux/sunrpc/clnt.h  |   4 +
>  include/linux/sunrpc/debug.h |  31 +++++++
>  net/sunrpc/Kconfig           |   1 +
>  net/sunrpc/Makefile          |   1 +
>  net/sunrpc/clnt.c            |  10 ++-
>  net/sunrpc/debugfs.c         | 191 +++++++++++++++++++++++++++++++++++++++++++
>  net/sunrpc/sunrpc_syms.c     |   8 ++
>  7 files changed, 245 insertions(+), 1 deletion(-)
>  create mode 100644 net/sunrpc/debugfs.c
> 
> diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
> index 70736b98c721..d86acc63b25f 100644
> --- a/include/linux/sunrpc/clnt.h
> +++ b/include/linux/sunrpc/clnt.h
> @@ -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 */
> diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
> index 43f38ee9668c..835339707094 100644
> --- a/include/linux/sunrpc/debug.h
> +++ b/include/linux/sunrpc/debug.h
> @@ -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_ */
> diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
> index 0754d0f466d2..fb78117b896c 100644
> --- a/net/sunrpc/Kconfig
> +++ b/net/sunrpc/Kconfig
> @@ -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
> diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
> index e5a7a1cac8f3..15e6f6c23c5d 100644
> --- a/net/sunrpc/Makefile
> +++ b/net/sunrpc/Makefile
> @@ -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
> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
> index 36c64ef460cf..05da12a33945 100644
> --- a/net/sunrpc/clnt.c
> +++ b/net/sunrpc/clnt.c
> @@ -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;
>  
> diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
> new file mode 100644
> index 000000000000..3d7745683ca3
> --- /dev/null
> +++ b/net/sunrpc/debugfs.c
> @@ -0,0 +1,191 @@
> +/**
> + * debugfs interface for sunrpc
> + *
> + * (c) 2014 Jeff Layton <jlayton@primarydata.com>
> + */
> +
> +#include <linux/debugfs.h>
> +#include <linux/sunrpc/sched.h>
> +#include <linux/sunrpc/clnt.h>
> +#include "netns.h"
> +
> +static struct dentry *topdir;
> +static struct dentry *rpc_clnt_dir;
> +
> +struct rpc_clnt_iter {
> +	struct rpc_clnt	*clnt;
> +	loff_t		pos;
> +};
> +
> +static int
> +tasks_show(struct seq_file *f, void *v)
> +{
> +	u32 xid = 0;
> +	struct rpc_task *task = v;
> +	struct rpc_clnt *clnt = task->tk_client;
> +	const char *rpc_waitq = "none";
> +
> +	if (RPC_IS_QUEUED(task))
> +		rpc_waitq = rpc_qname(task->tk_waitqueue);
> +
> +	if (task->tk_rqstp)
> +		xid = be32_to_cpu(task->tk_rqstp->rq_xid);
> +
> +	seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
> +		task->tk_pid, task->tk_flags, task->tk_status,
> +		clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
> +		clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
> +		task->tk_action, rpc_waitq);
> +	return 0;
> +}
> +
> +static void *
> +tasks_start(struct seq_file *f, loff_t *ppos)
> +	__acquires(&clnt->cl_lock)
> +{
> +	struct rpc_clnt_iter *iter = f->private;
> +	loff_t pos = *ppos;
> +	struct rpc_clnt *clnt = iter->clnt;
> +	struct rpc_task *task;
> +
> +	iter->pos = pos + 1;
> +	spin_lock(&clnt->cl_lock);
> +	list_for_each_entry(task, &clnt->cl_tasks, tk_task)
> +		if (pos-- == 0)
> +			return task;
> +	return NULL;
> +}
> +
> +static void *
> +tasks_next(struct seq_file *f, void *v, loff_t *pos)
> +{
> +	struct rpc_clnt_iter *iter = f->private;
> +	struct rpc_clnt *clnt = iter->clnt;
> +	struct rpc_task *task = v;
> +	struct list_head *next = task->tk_task.next;
> +
> +	++iter->pos;
> +	++*pos;
> +
> +	/* If there's another task on list, return it */
> +	if (next == &clnt->cl_tasks)
> +		return NULL;
> +	return list_entry(next, struct rpc_task, tk_task);
> +}
> +
> +static void
> +tasks_stop(struct seq_file *f, void *v)
> +	__releases(&clnt->cl_lock)
> +{
> +	struct rpc_clnt_iter *iter = f->private;
> +	struct rpc_clnt *clnt = iter->clnt;
> +
> +	spin_unlock(&clnt->cl_lock);
> +}
> +
> +static const struct seq_operations tasks_seq_operations = {
> +	.start	= tasks_start,
> +	.next	= tasks_next,
> +	.stop	= tasks_stop,
> +	.show	= tasks_show,
> +};
> +
> +static int tasks_open(struct inode *inode, struct file *filp)
> +{
> +	int ret = seq_open_private(filp, &tasks_seq_operations,
> +					sizeof(struct rpc_clnt_iter));
> +
> +	if (!ret) {
> +		struct seq_file *seq = filp->private_data;
> +		struct rpc_clnt_iter *iter = seq->private;
> +
> +		iter->clnt = inode->i_private;
> +
> +		if (!atomic_inc_not_zero(&iter->clnt->cl_count)) {
> +			seq_release_private(inode, filp);
> +			ret = -EINVAL;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static int
> +tasks_release(struct inode *inode, struct file *filp)
> +{
> +	struct seq_file *seq = filp->private_data;
> +	struct rpc_clnt_iter *iter = seq->private;
> +
> +	rpc_release_client(iter->clnt);
> +	return seq_release_private(inode, filp);
> +}
> +
> +static const struct file_operations tasks_fops = {
> +	.owner		= THIS_MODULE,
> +	.open		= tasks_open,
> +	.read		= seq_read,
> +	.llseek		= seq_lseek,
> +	.release	= tasks_release,
> +};
> +
> +int
> +rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
> +{
> +	int len;
> +	char name[9]; /* 8 for hex digits + NULL terminator */
> +
> +	/* Already registered? */
> +	if (clnt->cl_debugfs)
> +		return 0;
> +
> +	len = snprintf(name, sizeof(name), "%x", clnt->cl_clid);
> +	if (len >= sizeof(name))
> +		return -EINVAL;
> +
> +	/* make the per-client dir */
> +	clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir);
> +	if (!clnt->cl_debugfs)
> +		return -ENOMEM;
> +
> +	/* make tasks file */
> +	if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs,
> +				 clnt, &tasks_fops)) {
> +		debugfs_remove_recursive(clnt->cl_debugfs);
> +		clnt->cl_debugfs = NULL;
> +		return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
> +void
> +rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
> +{
> +	debugfs_remove_recursive(clnt->cl_debugfs);
> +	clnt->cl_debugfs = NULL;
> +}
> +
> +void __exit
> +sunrpc_debugfs_exit(void)
> +{
> +	debugfs_remove_recursive(topdir);
> +}
> +
> +int __init
> +sunrpc_debugfs_init(void)
> +{
> +	topdir = debugfs_create_dir("sunrpc", NULL);
> +	if (!topdir)
> +		goto out;
> +
> +	rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir);
> +	if (!rpc_clnt_dir)
> +		goto out_remove;
> +
> +	return 0;
> +out_remove:
> +	debugfs_remove_recursive(topdir);
> +	topdir = NULL;
> +out:
> +	return -ENOMEM;
> +}
> diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
> index f632e476ab6c..e37fbed87956 100644
> --- a/net/sunrpc/sunrpc_syms.c
> +++ b/net/sunrpc/sunrpc_syms.c
> @@ -97,6 +97,11 @@ init_sunrpc(void)
>  	err = register_rpc_pipefs();
>  	if (err)
>  		goto out4;
> +
> +	err = sunrpc_debugfs_init();
> +	if (err)
> +		goto out5;
> +
>  #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
>  	rpc_register_sysctl();
>  #endif
> @@ -104,6 +109,8 @@ init_sunrpc(void)
>  	init_socket_xprt();	/* clnt sock transport */
>  	return 0;
>  
> +out5:
> +	unregister_rpc_pipefs();
>  out4:
>  	unregister_pernet_subsys(&sunrpc_net_ops);
>  out3:
> @@ -120,6 +127,7 @@ cleanup_sunrpc(void)
>  	rpcauth_remove_module();
>  	cleanup_socket_xprt();
>  	svc_cleanup_xprt_sock();
> +	sunrpc_debugfs_exit();
>  	unregister_rpc_pipefs();
>  	rpc_destroy_mempool();
>  	unregister_pernet_subsys(&sunrpc_net_ops);
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 4/5] sunrpc: add debugfs file for displaying client rpc_task queue
  2014-11-26 20:13       ` Anna Schumaker
@ 2014-11-26 20:15         ` Anna Schumaker
  2014-11-26 20:52           ` Jeff Layton
  0 siblings, 1 reply; 19+ messages in thread
From: Anna Schumaker @ 2014-11-26 20:15 UTC (permalink / raw)
  To: Jeff Layton, trond.myklebust; +Cc: bfields, linux-nfs

On 11/26/2014 03:13 PM, Anna Schumaker wrote:
> Hi Jeff,
> 
> On 11/26/2014 02:44 PM, Jeff Layton wrote:
>> 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.
> 
> What do I have to do to get tasks to show up in the tasks file?  I'm running xfstests and occasionally running "cat" on 0/tasks and 3/tasks, but both are empty.

Ah, apparently I had to wait for generic/074 to run.  Now things are showing up!

Anna

> 
> Anna
> 
>>
>> Signed-off-by: Jeff Layton <jlayton@primarydata.com>
>> ---
>>  include/linux/sunrpc/clnt.h  |   4 +
>>  include/linux/sunrpc/debug.h |  31 +++++++
>>  net/sunrpc/Kconfig           |   1 +
>>  net/sunrpc/Makefile          |   1 +
>>  net/sunrpc/clnt.c            |  10 ++-
>>  net/sunrpc/debugfs.c         | 191 +++++++++++++++++++++++++++++++++++++++++++
>>  net/sunrpc/sunrpc_syms.c     |   8 ++
>>  7 files changed, 245 insertions(+), 1 deletion(-)
>>  create mode 100644 net/sunrpc/debugfs.c
>>
>> diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
>> index 70736b98c721..d86acc63b25f 100644
>> --- a/include/linux/sunrpc/clnt.h
>> +++ b/include/linux/sunrpc/clnt.h
>> @@ -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 */
>> diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
>> index 43f38ee9668c..835339707094 100644
>> --- a/include/linux/sunrpc/debug.h
>> +++ b/include/linux/sunrpc/debug.h
>> @@ -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_ */
>> diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
>> index 0754d0f466d2..fb78117b896c 100644
>> --- a/net/sunrpc/Kconfig
>> +++ b/net/sunrpc/Kconfig
>> @@ -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
>> diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
>> index e5a7a1cac8f3..15e6f6c23c5d 100644
>> --- a/net/sunrpc/Makefile
>> +++ b/net/sunrpc/Makefile
>> @@ -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
>> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
>> index 36c64ef460cf..05da12a33945 100644
>> --- a/net/sunrpc/clnt.c
>> +++ b/net/sunrpc/clnt.c
>> @@ -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;
>>  
>> diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
>> new file mode 100644
>> index 000000000000..3d7745683ca3
>> --- /dev/null
>> +++ b/net/sunrpc/debugfs.c
>> @@ -0,0 +1,191 @@
>> +/**
>> + * debugfs interface for sunrpc
>> + *
>> + * (c) 2014 Jeff Layton <jlayton@primarydata.com>
>> + */
>> +
>> +#include <linux/debugfs.h>
>> +#include <linux/sunrpc/sched.h>
>> +#include <linux/sunrpc/clnt.h>
>> +#include "netns.h"
>> +
>> +static struct dentry *topdir;
>> +static struct dentry *rpc_clnt_dir;
>> +
>> +struct rpc_clnt_iter {
>> +	struct rpc_clnt	*clnt;
>> +	loff_t		pos;
>> +};
>> +
>> +static int
>> +tasks_show(struct seq_file *f, void *v)
>> +{
>> +	u32 xid = 0;
>> +	struct rpc_task *task = v;
>> +	struct rpc_clnt *clnt = task->tk_client;
>> +	const char *rpc_waitq = "none";
>> +
>> +	if (RPC_IS_QUEUED(task))
>> +		rpc_waitq = rpc_qname(task->tk_waitqueue);
>> +
>> +	if (task->tk_rqstp)
>> +		xid = be32_to_cpu(task->tk_rqstp->rq_xid);
>> +
>> +	seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
>> +		task->tk_pid, task->tk_flags, task->tk_status,
>> +		clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
>> +		clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
>> +		task->tk_action, rpc_waitq);
>> +	return 0;
>> +}
>> +
>> +static void *
>> +tasks_start(struct seq_file *f, loff_t *ppos)
>> +	__acquires(&clnt->cl_lock)
>> +{
>> +	struct rpc_clnt_iter *iter = f->private;
>> +	loff_t pos = *ppos;
>> +	struct rpc_clnt *clnt = iter->clnt;
>> +	struct rpc_task *task;
>> +
>> +	iter->pos = pos + 1;
>> +	spin_lock(&clnt->cl_lock);
>> +	list_for_each_entry(task, &clnt->cl_tasks, tk_task)
>> +		if (pos-- == 0)
>> +			return task;
>> +	return NULL;
>> +}
>> +
>> +static void *
>> +tasks_next(struct seq_file *f, void *v, loff_t *pos)
>> +{
>> +	struct rpc_clnt_iter *iter = f->private;
>> +	struct rpc_clnt *clnt = iter->clnt;
>> +	struct rpc_task *task = v;
>> +	struct list_head *next = task->tk_task.next;
>> +
>> +	++iter->pos;
>> +	++*pos;
>> +
>> +	/* If there's another task on list, return it */
>> +	if (next == &clnt->cl_tasks)
>> +		return NULL;
>> +	return list_entry(next, struct rpc_task, tk_task);
>> +}
>> +
>> +static void
>> +tasks_stop(struct seq_file *f, void *v)
>> +	__releases(&clnt->cl_lock)
>> +{
>> +	struct rpc_clnt_iter *iter = f->private;
>> +	struct rpc_clnt *clnt = iter->clnt;
>> +
>> +	spin_unlock(&clnt->cl_lock);
>> +}
>> +
>> +static const struct seq_operations tasks_seq_operations = {
>> +	.start	= tasks_start,
>> +	.next	= tasks_next,
>> +	.stop	= tasks_stop,
>> +	.show	= tasks_show,
>> +};
>> +
>> +static int tasks_open(struct inode *inode, struct file *filp)
>> +{
>> +	int ret = seq_open_private(filp, &tasks_seq_operations,
>> +					sizeof(struct rpc_clnt_iter));
>> +
>> +	if (!ret) {
>> +		struct seq_file *seq = filp->private_data;
>> +		struct rpc_clnt_iter *iter = seq->private;
>> +
>> +		iter->clnt = inode->i_private;
>> +
>> +		if (!atomic_inc_not_zero(&iter->clnt->cl_count)) {
>> +			seq_release_private(inode, filp);
>> +			ret = -EINVAL;
>> +		}
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static int
>> +tasks_release(struct inode *inode, struct file *filp)
>> +{
>> +	struct seq_file *seq = filp->private_data;
>> +	struct rpc_clnt_iter *iter = seq->private;
>> +
>> +	rpc_release_client(iter->clnt);
>> +	return seq_release_private(inode, filp);
>> +}
>> +
>> +static const struct file_operations tasks_fops = {
>> +	.owner		= THIS_MODULE,
>> +	.open		= tasks_open,
>> +	.read		= seq_read,
>> +	.llseek		= seq_lseek,
>> +	.release	= tasks_release,
>> +};
>> +
>> +int
>> +rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
>> +{
>> +	int len;
>> +	char name[9]; /* 8 for hex digits + NULL terminator */
>> +
>> +	/* Already registered? */
>> +	if (clnt->cl_debugfs)
>> +		return 0;
>> +
>> +	len = snprintf(name, sizeof(name), "%x", clnt->cl_clid);
>> +	if (len >= sizeof(name))
>> +		return -EINVAL;
>> +
>> +	/* make the per-client dir */
>> +	clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir);
>> +	if (!clnt->cl_debugfs)
>> +		return -ENOMEM;
>> +
>> +	/* make tasks file */
>> +	if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs,
>> +				 clnt, &tasks_fops)) {
>> +		debugfs_remove_recursive(clnt->cl_debugfs);
>> +		clnt->cl_debugfs = NULL;
>> +		return -ENOMEM;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +void
>> +rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
>> +{
>> +	debugfs_remove_recursive(clnt->cl_debugfs);
>> +	clnt->cl_debugfs = NULL;
>> +}
>> +
>> +void __exit
>> +sunrpc_debugfs_exit(void)
>> +{
>> +	debugfs_remove_recursive(topdir);
>> +}
>> +
>> +int __init
>> +sunrpc_debugfs_init(void)
>> +{
>> +	topdir = debugfs_create_dir("sunrpc", NULL);
>> +	if (!topdir)
>> +		goto out;
>> +
>> +	rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir);
>> +	if (!rpc_clnt_dir)
>> +		goto out_remove;
>> +
>> +	return 0;
>> +out_remove:
>> +	debugfs_remove_recursive(topdir);
>> +	topdir = NULL;
>> +out:
>> +	return -ENOMEM;
>> +}
>> diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
>> index f632e476ab6c..e37fbed87956 100644
>> --- a/net/sunrpc/sunrpc_syms.c
>> +++ b/net/sunrpc/sunrpc_syms.c
>> @@ -97,6 +97,11 @@ init_sunrpc(void)
>>  	err = register_rpc_pipefs();
>>  	if (err)
>>  		goto out4;
>> +
>> +	err = sunrpc_debugfs_init();
>> +	if (err)
>> +		goto out5;
>> +
>>  #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
>>  	rpc_register_sysctl();
>>  #endif
>> @@ -104,6 +109,8 @@ init_sunrpc(void)
>>  	init_socket_xprt();	/* clnt sock transport */
>>  	return 0;
>>  
>> +out5:
>> +	unregister_rpc_pipefs();
>>  out4:
>>  	unregister_pernet_subsys(&sunrpc_net_ops);
>>  out3:
>> @@ -120,6 +127,7 @@ cleanup_sunrpc(void)
>>  	rpcauth_remove_module();
>>  	cleanup_socket_xprt();
>>  	svc_cleanup_xprt_sock();
>> +	sunrpc_debugfs_exit();
>>  	unregister_rpc_pipefs();
>>  	rpc_destroy_mempool();
>>  	unregister_pernet_subsys(&sunrpc_net_ops);
>>
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 4/5] sunrpc: add debugfs file for displaying client rpc_task queue
  2014-11-26 20:15         ` Anna Schumaker
@ 2014-11-26 20:52           ` Jeff Layton
  0 siblings, 0 replies; 19+ messages in thread
From: Jeff Layton @ 2014-11-26 20:52 UTC (permalink / raw)
  To: Anna Schumaker; +Cc: trond.myklebust, bfields, linux-nfs

On Wed, 26 Nov 2014 15:15:42 -0500
Anna Schumaker <Anna.Schumaker@netapp.com> wrote:

> On 11/26/2014 03:13 PM, Anna Schumaker wrote:
> > Hi Jeff,
> > 
> > On 11/26/2014 02:44 PM, Jeff Layton wrote:
> >> 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.
> > 
> > What do I have to do to get tasks to show up in the tasks file?  I'm running xfstests and occasionally running "cat" on 0/tasks and 3/tasks, but both are empty.
> 
> Ah, apparently I had to wait for generic/074 to run.  Now things are showing up!
> 
> Anna
> 

Ok, cool!

Yes, if you have relatively quick clients and servers then it can be
hard to catch them in the act. FWIW, I think this will primarily be of
use when there are problems on the client and the queue ends up blocked
for some reason.

> > 
> > Anna
> > 
> >>
> >> Signed-off-by: Jeff Layton <jlayton@primarydata.com>
> >> ---
> >>  include/linux/sunrpc/clnt.h  |   4 +
> >>  include/linux/sunrpc/debug.h |  31 +++++++
> >>  net/sunrpc/Kconfig           |   1 +
> >>  net/sunrpc/Makefile          |   1 +
> >>  net/sunrpc/clnt.c            |  10 ++-
> >>  net/sunrpc/debugfs.c         | 191 +++++++++++++++++++++++++++++++++++++++++++
> >>  net/sunrpc/sunrpc_syms.c     |   8 ++
> >>  7 files changed, 245 insertions(+), 1 deletion(-)
> >>  create mode 100644 net/sunrpc/debugfs.c
> >>
> >> diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
> >> index 70736b98c721..d86acc63b25f 100644
> >> --- a/include/linux/sunrpc/clnt.h
> >> +++ b/include/linux/sunrpc/clnt.h
> >> @@ -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 */
> >> diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
> >> index 43f38ee9668c..835339707094 100644
> >> --- a/include/linux/sunrpc/debug.h
> >> +++ b/include/linux/sunrpc/debug.h
> >> @@ -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_ */
> >> diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
> >> index 0754d0f466d2..fb78117b896c 100644
> >> --- a/net/sunrpc/Kconfig
> >> +++ b/net/sunrpc/Kconfig
> >> @@ -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
> >> diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
> >> index e5a7a1cac8f3..15e6f6c23c5d 100644
> >> --- a/net/sunrpc/Makefile
> >> +++ b/net/sunrpc/Makefile
> >> @@ -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
> >> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
> >> index 36c64ef460cf..05da12a33945 100644
> >> --- a/net/sunrpc/clnt.c
> >> +++ b/net/sunrpc/clnt.c
> >> @@ -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;
> >>  
> >> diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
> >> new file mode 100644
> >> index 000000000000..3d7745683ca3
> >> --- /dev/null
> >> +++ b/net/sunrpc/debugfs.c
> >> @@ -0,0 +1,191 @@
> >> +/**
> >> + * debugfs interface for sunrpc
> >> + *
> >> + * (c) 2014 Jeff Layton <jlayton@primarydata.com>
> >> + */
> >> +
> >> +#include <linux/debugfs.h>
> >> +#include <linux/sunrpc/sched.h>
> >> +#include <linux/sunrpc/clnt.h>
> >> +#include "netns.h"
> >> +
> >> +static struct dentry *topdir;
> >> +static struct dentry *rpc_clnt_dir;
> >> +
> >> +struct rpc_clnt_iter {
> >> +	struct rpc_clnt	*clnt;
> >> +	loff_t		pos;
> >> +};
> >> +
> >> +static int
> >> +tasks_show(struct seq_file *f, void *v)
> >> +{
> >> +	u32 xid = 0;
> >> +	struct rpc_task *task = v;
> >> +	struct rpc_clnt *clnt = task->tk_client;
> >> +	const char *rpc_waitq = "none";
> >> +
> >> +	if (RPC_IS_QUEUED(task))
> >> +		rpc_waitq = rpc_qname(task->tk_waitqueue);
> >> +
> >> +	if (task->tk_rqstp)
> >> +		xid = be32_to_cpu(task->tk_rqstp->rq_xid);
> >> +
> >> +	seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
> >> +		task->tk_pid, task->tk_flags, task->tk_status,
> >> +		clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
> >> +		clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
> >> +		task->tk_action, rpc_waitq);
> >> +	return 0;
> >> +}
> >> +
> >> +static void *
> >> +tasks_start(struct seq_file *f, loff_t *ppos)
> >> +	__acquires(&clnt->cl_lock)
> >> +{
> >> +	struct rpc_clnt_iter *iter = f->private;
> >> +	loff_t pos = *ppos;
> >> +	struct rpc_clnt *clnt = iter->clnt;
> >> +	struct rpc_task *task;
> >> +
> >> +	iter->pos = pos + 1;
> >> +	spin_lock(&clnt->cl_lock);
> >> +	list_for_each_entry(task, &clnt->cl_tasks, tk_task)
> >> +		if (pos-- == 0)
> >> +			return task;
> >> +	return NULL;
> >> +}
> >> +
> >> +static void *
> >> +tasks_next(struct seq_file *f, void *v, loff_t *pos)
> >> +{
> >> +	struct rpc_clnt_iter *iter = f->private;
> >> +	struct rpc_clnt *clnt = iter->clnt;
> >> +	struct rpc_task *task = v;
> >> +	struct list_head *next = task->tk_task.next;
> >> +
> >> +	++iter->pos;
> >> +	++*pos;
> >> +
> >> +	/* If there's another task on list, return it */
> >> +	if (next == &clnt->cl_tasks)
> >> +		return NULL;
> >> +	return list_entry(next, struct rpc_task, tk_task);
> >> +}
> >> +
> >> +static void
> >> +tasks_stop(struct seq_file *f, void *v)
> >> +	__releases(&clnt->cl_lock)
> >> +{
> >> +	struct rpc_clnt_iter *iter = f->private;
> >> +	struct rpc_clnt *clnt = iter->clnt;
> >> +
> >> +	spin_unlock(&clnt->cl_lock);
> >> +}
> >> +
> >> +static const struct seq_operations tasks_seq_operations = {
> >> +	.start	= tasks_start,
> >> +	.next	= tasks_next,
> >> +	.stop	= tasks_stop,
> >> +	.show	= tasks_show,
> >> +};
> >> +
> >> +static int tasks_open(struct inode *inode, struct file *filp)
> >> +{
> >> +	int ret = seq_open_private(filp, &tasks_seq_operations,
> >> +					sizeof(struct rpc_clnt_iter));
> >> +
> >> +	if (!ret) {
> >> +		struct seq_file *seq = filp->private_data;
> >> +		struct rpc_clnt_iter *iter = seq->private;
> >> +
> >> +		iter->clnt = inode->i_private;
> >> +
> >> +		if (!atomic_inc_not_zero(&iter->clnt->cl_count)) {
> >> +			seq_release_private(inode, filp);
> >> +			ret = -EINVAL;
> >> +		}
> >> +	}
> >> +
> >> +	return ret;
> >> +}
> >> +
> >> +static int
> >> +tasks_release(struct inode *inode, struct file *filp)
> >> +{
> >> +	struct seq_file *seq = filp->private_data;
> >> +	struct rpc_clnt_iter *iter = seq->private;
> >> +
> >> +	rpc_release_client(iter->clnt);
> >> +	return seq_release_private(inode, filp);
> >> +}
> >> +
> >> +static const struct file_operations tasks_fops = {
> >> +	.owner		= THIS_MODULE,
> >> +	.open		= tasks_open,
> >> +	.read		= seq_read,
> >> +	.llseek		= seq_lseek,
> >> +	.release	= tasks_release,
> >> +};
> >> +
> >> +int
> >> +rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
> >> +{
> >> +	int len;
> >> +	char name[9]; /* 8 for hex digits + NULL terminator */
> >> +
> >> +	/* Already registered? */
> >> +	if (clnt->cl_debugfs)
> >> +		return 0;
> >> +
> >> +	len = snprintf(name, sizeof(name), "%x", clnt->cl_clid);
> >> +	if (len >= sizeof(name))
> >> +		return -EINVAL;
> >> +
> >> +	/* make the per-client dir */
> >> +	clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir);
> >> +	if (!clnt->cl_debugfs)
> >> +		return -ENOMEM;
> >> +
> >> +	/* make tasks file */
> >> +	if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs,
> >> +				 clnt, &tasks_fops)) {
> >> +		debugfs_remove_recursive(clnt->cl_debugfs);
> >> +		clnt->cl_debugfs = NULL;
> >> +		return -ENOMEM;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +void
> >> +rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
> >> +{
> >> +	debugfs_remove_recursive(clnt->cl_debugfs);
> >> +	clnt->cl_debugfs = NULL;
> >> +}
> >> +
> >> +void __exit
> >> +sunrpc_debugfs_exit(void)
> >> +{
> >> +	debugfs_remove_recursive(topdir);
> >> +}
> >> +
> >> +int __init
> >> +sunrpc_debugfs_init(void)
> >> +{
> >> +	topdir = debugfs_create_dir("sunrpc", NULL);
> >> +	if (!topdir)
> >> +		goto out;
> >> +
> >> +	rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir);
> >> +	if (!rpc_clnt_dir)
> >> +		goto out_remove;
> >> +
> >> +	return 0;
> >> +out_remove:
> >> +	debugfs_remove_recursive(topdir);
> >> +	topdir = NULL;
> >> +out:
> >> +	return -ENOMEM;
> >> +}
> >> diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
> >> index f632e476ab6c..e37fbed87956 100644
> >> --- a/net/sunrpc/sunrpc_syms.c
> >> +++ b/net/sunrpc/sunrpc_syms.c
> >> @@ -97,6 +97,11 @@ init_sunrpc(void)
> >>  	err = register_rpc_pipefs();
> >>  	if (err)
> >>  		goto out4;
> >> +
> >> +	err = sunrpc_debugfs_init();
> >> +	if (err)
> >> +		goto out5;
> >> +
> >>  #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
> >>  	rpc_register_sysctl();
> >>  #endif
> >> @@ -104,6 +109,8 @@ init_sunrpc(void)
> >>  	init_socket_xprt();	/* clnt sock transport */
> >>  	return 0;
> >>  
> >> +out5:
> >> +	unregister_rpc_pipefs();
> >>  out4:
> >>  	unregister_pernet_subsys(&sunrpc_net_ops);
> >>  out3:
> >> @@ -120,6 +127,7 @@ cleanup_sunrpc(void)
> >>  	rpcauth_remove_module();
> >>  	cleanup_socket_xprt();
> >>  	svc_cleanup_xprt_sock();
> >> +	sunrpc_debugfs_exit();
> >>  	unregister_rpc_pipefs();
> >>  	rpc_destroy_mempool();
> >>  	unregister_pernet_subsys(&sunrpc_net_ops);
> >>
> > 
> 


-- 
Jeff Layton <jlayton@primarydata.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2014-11-26 20:52 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-28 18:24 [PATCH] sunrpc: add debugfs file for displaying client rpc_task queue Jeff Layton
2014-10-28 18:30 ` Jeff Layton
2014-11-24 19:20   ` Trond Myklebust
2014-11-24 21:35     ` Jeff Layton
2014-11-25 19:00 ` [PATCH v2 0/4] " Jeff Layton
2014-11-25 19:00   ` [PATCH v2 1/4] lockd: eliminate LOCKD_DEBUG Jeff Layton
2014-11-25 19:00   ` [PATCH v2 2/4] sunrpc: eliminate RPC_DEBUG Jeff Layton
2014-11-25 19:00   ` [PATCH v2 3/4] sunrpc: eliminate RPC_TRACEPOINTS Jeff Layton
2014-11-25 19:01   ` [PATCH v2 4/4] sunrpc: add debugfs file for displaying client rpc_task queue Jeff Layton
2014-11-25 21:00     ` Jeff Layton
2014-11-26 19:44   ` [PATCH v3 0/5] sunrpc: add some debugfs files for dumping task and xprt info Jeff Layton
2014-11-26 19:44     ` [PATCH v3 1/5] lockd: eliminate LOCKD_DEBUG Jeff Layton
2014-11-26 19:44     ` [PATCH v3 2/5] sunrpc: eliminate RPC_DEBUG Jeff Layton
2014-11-26 19:44     ` [PATCH v3 3/5] sunrpc: eliminate RPC_TRACEPOINTS Jeff Layton
2014-11-26 19:44     ` [PATCH v3 4/5] sunrpc: add debugfs file for displaying client rpc_task queue Jeff Layton
2014-11-26 20:13       ` Anna Schumaker
2014-11-26 20:15         ` Anna Schumaker
2014-11-26 20:52           ` Jeff Layton
2014-11-26 19:44     ` [PATCH v3 5/5] sunrpc: add a debugfs rpc_xprt directory with an info file in it Jeff Layton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox