aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 18:13:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 18:13:13 -0500
commite20db597b6264de55ea6636fc79b1e4aaa89d129 (patch)
treefa650cb9cfad4b22598ae9867ca92baf57491a9d /net
parent3a5dc1fafb016560315fe45bb4ef8bde259dd1bc (diff)
parent388f0c776781fe64ce951701bfe712b2182a31f2 (diff)
Merge tag 'nfs-for-3.19-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Highlights include: Features: - NFSv4.2 client support for hole punching and preallocation. - Further RPC/RDMA client improvements. - Add more RPC transport debugging tracepoints. - Add RPC debugging tools in debugfs. Bugfixes: - Stable fix for layoutget error handling - Fix a change in COMMIT behaviour resulting from the recent io code updates" * tag 'nfs-for-3.19-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (28 commits) sunrpc: add a debugfs rpc_xprt directory with an info file in it sunrpc: add debugfs file for displaying client rpc_task queue nfs: Add DEALLOCATE support nfs: Add ALLOCATE support NFS: Clean up nfs4_init_callback() NFS: SETCLIENTID XDR buffer sizes are incorrect SUNRPC: serialize iostats updates xprtrdma: Display async errors xprtrdma: Enable pad optimization xprtrdma: Re-write rpcrdma_flush_cqs() xprtrdma: Refactor tasklet scheduling xprtrdma: unmap all FMRs during transport disconnect xprtrdma: Cap req_cqinit xprtrdma: Return an errno from rpcrdma_register_external() nfs: define nfs_inc_fscache_stats and using it as possible nfs: replace nfs_add_stats with nfs_inc_stats when add one NFS: Deletion of unnecessary checks before the function call "nfs_put_client" sunrpc: eliminate RPC_TRACEPOINTS sunrpc: eliminate RPC_DEBUG lockd: eliminate LOCKD_DEBUG ...
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/Kconfig1
-rw-r--r--net/sunrpc/Makefile1
-rw-r--r--net/sunrpc/auth.c4
-rw-r--r--net/sunrpc/auth_generic.c2
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c2
-rw-r--r--net/sunrpc/auth_gss/gss_generic_token.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_keys.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seal.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seqnum.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_unseal.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c2
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c2
-rw-r--r--net/sunrpc/auth_gss/gss_rpc_xdr.h2
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c2
-rw-r--r--net/sunrpc/auth_null.c4
-rw-r--r--net/sunrpc/auth_unix.c2
-rw-r--r--net/sunrpc/backchannel_rqst.c2
-rw-r--r--net/sunrpc/clnt.c16
-rw-r--r--net/sunrpc/debugfs.c292
-rw-r--r--net/sunrpc/rpcb_clnt.c2
-rw-r--r--net/sunrpc/sched.c4
-rw-r--r--net/sunrpc/stats.c21
-rw-r--r--net/sunrpc/sunrpc_syms.c12
-rw-r--r--net/sunrpc/svc.c23
-rw-r--r--net/sunrpc/svc_xprt.c31
-rw-r--r--net/sunrpc/sysctl.c2
-rw-r--r--net/sunrpc/xprt.c19
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c4
-rw-r--r--net/sunrpc/xprtrdma/transport.c12
-rw-r--r--net/sunrpc/xprtrdma/verbs.c122
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h6
-rw-r--r--net/sunrpc/xprtsock.c77
34 files changed, 536 insertions, 147 deletions
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
35config SUNRPC_DEBUG 35config SUNRPC_DEBUG
36 bool "RPC: Enable dprintk debugging" 36 bool "RPC: Enable dprintk debugging"
37 depends on SUNRPC && SYSCTL 37 depends on SUNRPC && SYSCTL
38 select DEBUG_FS
38 help 39 help
39 This option enables a sysctl-based debugging interface 40 This option enables a sysctl-based debugging interface
40 that is be used by the 'rpcdebug' utility to turn on or off 41 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 \
14 addr.o rpcb_clnt.o timer.o xdr.o \ 14 addr.o rpcb_clnt.o timer.o xdr.o \
15 sunrpc_syms.o cache.o rpc_pipe.o \ 15 sunrpc_syms.o cache.o rpc_pipe.o \
16 svc_xprt.o 16 svc_xprt.o
17sunrpc-$(CONFIG_SUNRPC_DEBUG) += debugfs.o
17sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o 18sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o
18sunrpc-$(CONFIG_PROC_FS) += stats.o 19sunrpc-$(CONFIG_PROC_FS) += stats.o
19sunrpc-$(CONFIG_SYSCTL) += sysctl.o 20sunrpc-$(CONFIG_SYSCTL) += sysctl.o
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 @@
16#include <linux/sunrpc/gss_api.h> 16#include <linux/sunrpc/gss_api.h>
17#include <linux/spinlock.h> 17#include <linux/spinlock.h>
18 18
19#ifdef RPC_DEBUG 19#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
20# define RPCDBG_FACILITY RPCDBG_AUTH 20# define RPCDBG_FACILITY RPCDBG_AUTH
21#endif 21#endif
22 22
@@ -646,7 +646,7 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
646 cred->cr_auth = auth; 646 cred->cr_auth = auth;
647 cred->cr_ops = ops; 647 cred->cr_ops = ops;
648 cred->cr_expire = jiffies; 648 cred->cr_expire = jiffies;
649#ifdef RPC_DEBUG 649#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
650 cred->cr_magic = RPCAUTH_CRED_MAGIC; 650 cred->cr_magic = RPCAUTH_CRED_MAGIC;
651#endif 651#endif
652 cred->cr_uid = acred->uid; 652 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 @@
14#include <linux/sunrpc/debug.h> 14#include <linux/sunrpc/debug.h>
15#include <linux/sunrpc/sched.h> 15#include <linux/sunrpc/sched.h>
16 16
17#ifdef RPC_DEBUG 17#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
18# define RPCDBG_FACILITY RPCDBG_AUTH 18# define RPCDBG_FACILITY RPCDBG_AUTH
19#endif 19#endif
20 20
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;
66#define GSS_KEY_EXPIRE_TIMEO 240 66#define GSS_KEY_EXPIRE_TIMEO 240
67static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO; 67static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO;
68 68
69#ifdef RPC_DEBUG 69#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
70# define RPCDBG_FACILITY RPCDBG_AUTH 70# define RPCDBG_FACILITY RPCDBG_AUTH
71#endif 71#endif
72 72
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 @@
38#include <linux/sunrpc/gss_asn1.h> 38#include <linux/sunrpc/gss_asn1.h>
39 39
40 40
41#ifdef RPC_DEBUG 41#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
42# define RPCDBG_FACILITY RPCDBG_AUTH 42# define RPCDBG_FACILITY RPCDBG_AUTH
43#endif 43#endif
44 44
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 @@
45#include <linux/sunrpc/gss_krb5.h> 45#include <linux/sunrpc/gss_krb5.h>
46#include <linux/sunrpc/xdr.h> 46#include <linux/sunrpc/xdr.h>
47 47
48#ifdef RPC_DEBUG 48#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
49# define RPCDBG_FACILITY RPCDBG_AUTH 49# define RPCDBG_FACILITY RPCDBG_AUTH
50#endif 50#endif
51 51
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 @@
61#include <linux/sunrpc/xdr.h> 61#include <linux/sunrpc/xdr.h>
62#include <linux/lcm.h> 62#include <linux/lcm.h>
63 63
64#ifdef RPC_DEBUG 64#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
65# define RPCDBG_FACILITY RPCDBG_AUTH 65# define RPCDBG_FACILITY RPCDBG_AUTH
66#endif 66#endif
67 67
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 @@
45#include <linux/crypto.h> 45#include <linux/crypto.h>
46#include <linux/sunrpc/gss_krb5_enctypes.h> 46#include <linux/sunrpc/gss_krb5_enctypes.h>
47 47
48#ifdef RPC_DEBUG 48#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
49# define RPCDBG_FACILITY RPCDBG_AUTH 49# define RPCDBG_FACILITY RPCDBG_AUTH
50#endif 50#endif
51 51
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 @@
64#include <linux/random.h> 64#include <linux/random.h>
65#include <linux/crypto.h> 65#include <linux/crypto.h>
66 66
67#ifdef RPC_DEBUG 67#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
68# define RPCDBG_FACILITY RPCDBG_AUTH 68# define RPCDBG_FACILITY RPCDBG_AUTH
69#endif 69#endif
70 70
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 @@
35#include <linux/sunrpc/gss_krb5.h> 35#include <linux/sunrpc/gss_krb5.h>
36#include <linux/crypto.h> 36#include <linux/crypto.h>
37 37
38#ifdef RPC_DEBUG 38#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
39# define RPCDBG_FACILITY RPCDBG_AUTH 39# define RPCDBG_FACILITY RPCDBG_AUTH
40#endif 40#endif
41 41
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 @@
62#include <linux/sunrpc/gss_krb5.h> 62#include <linux/sunrpc/gss_krb5.h>
63#include <linux/crypto.h> 63#include <linux/crypto.h>
64 64
65#ifdef RPC_DEBUG 65#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
66# define RPCDBG_FACILITY RPCDBG_AUTH 66# define RPCDBG_FACILITY RPCDBG_AUTH
67#endif 67#endif
68 68
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 @@
35#include <linux/pagemap.h> 35#include <linux/pagemap.h>
36#include <linux/crypto.h> 36#include <linux/crypto.h>
37 37
38#ifdef RPC_DEBUG 38#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
39# define RPCDBG_FACILITY RPCDBG_AUTH 39# define RPCDBG_FACILITY RPCDBG_AUTH
40#endif 40#endif
41 41
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 @@
46#include <linux/sunrpc/gss_api.h> 46#include <linux/sunrpc/gss_api.h>
47#include <linux/sunrpc/clnt.h> 47#include <linux/sunrpc/clnt.h>
48 48
49#ifdef RPC_DEBUG 49#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
50# define RPCDBG_FACILITY RPCDBG_AUTH 50# define RPCDBG_FACILITY RPCDBG_AUTH
51#endif 51#endif
52 52
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 @@
25#include <linux/sunrpc/clnt.h> 25#include <linux/sunrpc/clnt.h>
26#include <linux/sunrpc/xprtsock.h> 26#include <linux/sunrpc/xprtsock.h>
27 27
28#ifdef RPC_DEBUG 28#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
29# define RPCDBG_FACILITY RPCDBG_AUTH 29# define RPCDBG_FACILITY RPCDBG_AUTH
30#endif 30#endif
31 31
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 @@
51#include "gss_rpc_upcall.h" 51#include "gss_rpc_upcall.h"
52 52
53 53
54#ifdef RPC_DEBUG 54#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
55# define RPCDBG_FACILITY RPCDBG_AUTH 55# define RPCDBG_FACILITY RPCDBG_AUTH
56#endif 56#endif
57 57
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 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/sunrpc/clnt.h> 11#include <linux/sunrpc/clnt.h>
12 12
13#ifdef RPC_DEBUG 13#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
14# define RPCDBG_FACILITY RPCDBG_AUTH 14# define RPCDBG_FACILITY RPCDBG_AUTH
15#endif 15#endif
16 16
@@ -138,7 +138,7 @@ struct rpc_cred null_cred = {
138 .cr_ops = &null_credops, 138 .cr_ops = &null_credops,
139 .cr_count = ATOMIC_INIT(1), 139 .cr_count = ATOMIC_INIT(1),
140 .cr_flags = 1UL << RPCAUTH_CRED_UPTODATE, 140 .cr_flags = 1UL << RPCAUTH_CRED_UPTODATE,
141#ifdef RPC_DEBUG 141#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
142 .cr_magic = RPCAUTH_CRED_MAGIC, 142 .cr_magic = RPCAUTH_CRED_MAGIC,
143#endif 143#endif
144}; 144};
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 {
25 25
26#define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2)) 26#define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2))
27 27
28#ifdef RPC_DEBUG 28#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
29# define RPCDBG_FACILITY RPCDBG_AUTH 29# define RPCDBG_FACILITY RPCDBG_AUTH
30#endif 30#endif
31 31
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.
27#include <linux/export.h> 27#include <linux/export.h>
28#include <linux/sunrpc/bc_xprt.h> 28#include <linux/sunrpc/bc_xprt.h>
29 29
30#ifdef RPC_DEBUG 30#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
31#define RPCDBG_FACILITY RPCDBG_TRANS 31#define RPCDBG_FACILITY RPCDBG_TRANS
32#endif 32#endif
33 33
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 9acd6ce88db7..05da12a33945 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -42,7 +42,7 @@
42#include "sunrpc.h" 42#include "sunrpc.h"
43#include "netns.h" 43#include "netns.h"
44 44
45#ifdef RPC_DEBUG 45#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
46# define RPCDBG_FACILITY RPCDBG_CALL 46# define RPCDBG_FACILITY RPCDBG_CALL
47#endif 47#endif
48 48
@@ -305,6 +305,10 @@ static int rpc_client_register(struct rpc_clnt *clnt,
305 struct super_block *pipefs_sb; 305 struct super_block *pipefs_sb;
306 int err; 306 int err;
307 307
308 err = rpc_clnt_debugfs_register(clnt);
309 if (err)
310 return err;
311
308 pipefs_sb = rpc_get_sb_net(net); 312 pipefs_sb = rpc_get_sb_net(net);
309 if (pipefs_sb) { 313 if (pipefs_sb) {
310 err = rpc_setup_pipedir(pipefs_sb, clnt); 314 err = rpc_setup_pipedir(pipefs_sb, clnt);
@@ -331,6 +335,7 @@ err_auth:
331out: 335out:
332 if (pipefs_sb) 336 if (pipefs_sb)
333 rpc_put_sb_net(net); 337 rpc_put_sb_net(net);
338 rpc_clnt_debugfs_unregister(clnt);
334 return err; 339 return err;
335} 340}
336 341
@@ -670,6 +675,7 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
670 675
671 rpc_unregister_client(clnt); 676 rpc_unregister_client(clnt);
672 __rpc_clnt_remove_pipedir(clnt); 677 __rpc_clnt_remove_pipedir(clnt);
678 rpc_clnt_debugfs_unregister(clnt);
673 679
674 /* 680 /*
675 * A new transport was created. "clnt" therefore 681 * A new transport was created. "clnt" therefore
@@ -771,6 +777,7 @@ rpc_free_client(struct rpc_clnt *clnt)
771 rcu_dereference(clnt->cl_xprt)->servername); 777 rcu_dereference(clnt->cl_xprt)->servername);
772 if (clnt->cl_parent != clnt) 778 if (clnt->cl_parent != clnt)
773 parent = clnt->cl_parent; 779 parent = clnt->cl_parent;
780 rpc_clnt_debugfs_unregister(clnt);
774 rpc_clnt_remove_pipedir(clnt); 781 rpc_clnt_remove_pipedir(clnt);
775 rpc_unregister_client(clnt); 782 rpc_unregister_client(clnt);
776 rpc_free_iostats(clnt->cl_metrics); 783 rpc_free_iostats(clnt->cl_metrics);
@@ -1396,8 +1403,9 @@ rpc_restart_call(struct rpc_task *task)
1396} 1403}
1397EXPORT_SYMBOL_GPL(rpc_restart_call); 1404EXPORT_SYMBOL_GPL(rpc_restart_call);
1398 1405
1399#ifdef RPC_DEBUG 1406#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
1400static const char *rpc_proc_name(const struct rpc_task *task) 1407const char
1408*rpc_proc_name(const struct rpc_task *task)
1401{ 1409{
1402 const struct rpc_procinfo *proc = task->tk_msg.rpc_proc; 1410 const struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
1403 1411
@@ -2421,7 +2429,7 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int
2421} 2429}
2422EXPORT_SYMBOL_GPL(rpc_call_null); 2430EXPORT_SYMBOL_GPL(rpc_call_null);
2423 2431
2424#ifdef RPC_DEBUG 2432#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
2425static void rpc_show_header(void) 2433static void rpc_show_header(void)
2426{ 2434{
2427 printk(KERN_INFO "-pid- flgs status -client- --rqstp- " 2435 printk(KERN_INFO "-pid- flgs status -client- --rqstp- "
diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
new file mode 100644
index 000000000000..e811f390f9f6
--- /dev/null
+++ b/net/sunrpc/debugfs.c
@@ -0,0 +1,292 @@
1/**
2 * debugfs interface for sunrpc
3 *
4 * (c) 2014 Jeff Layton <jlayton@primarydata.com>
5 */
6
7#include <linux/debugfs.h>
8#include <linux/sunrpc/sched.h>
9#include <linux/sunrpc/clnt.h>
10#include "netns.h"
11
12static struct dentry *topdir;
13static struct dentry *rpc_clnt_dir;
14static struct dentry *rpc_xprt_dir;
15
16struct rpc_clnt_iter {
17 struct rpc_clnt *clnt;
18 loff_t pos;
19};
20
21static int
22tasks_show(struct seq_file *f, void *v)
23{
24 u32 xid = 0;
25 struct rpc_task *task = v;
26 struct rpc_clnt *clnt = task->tk_client;
27 const char *rpc_waitq = "none";
28
29 if (RPC_IS_QUEUED(task))
30 rpc_waitq = rpc_qname(task->tk_waitqueue);
31
32 if (task->tk_rqstp)
33 xid = be32_to_cpu(task->tk_rqstp->rq_xid);
34
35 seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
36 task->tk_pid, task->tk_flags, task->tk_status,
37 clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
38 clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
39 task->tk_action, rpc_waitq);
40 return 0;
41}
42
43static void *
44tasks_start(struct seq_file *f, loff_t *ppos)
45 __acquires(&clnt->cl_lock)
46{
47 struct rpc_clnt_iter *iter = f->private;
48 loff_t pos = *ppos;
49 struct rpc_clnt *clnt = iter->clnt;
50 struct rpc_task *task;
51
52 iter->pos = pos + 1;
53 spin_lock(&clnt->cl_lock);
54 list_for_each_entry(task, &clnt->cl_tasks, tk_task)
55 if (pos-- == 0)
56 return task;
57 return NULL;
58}
59
60static void *
61tasks_next(struct seq_file *f, void *v, loff_t *pos)
62{
63 struct rpc_clnt_iter *iter = f->private;
64 struct rpc_clnt *clnt = iter->clnt;
65 struct rpc_task *task = v;
66 struct list_head *next = task->tk_task.next;
67
68 ++iter->pos;
69 ++*pos;
70
71 /* If there's another task on list, return it */
72 if (next == &clnt->cl_tasks)
73 return NULL;
74 return list_entry(next, struct rpc_task, tk_task);
75}
76
77static void
78tasks_stop(struct seq_file *f, void *v)
79 __releases(&clnt->cl_lock)
80{
81 struct rpc_clnt_iter *iter = f->private;
82 struct rpc_clnt *clnt = iter->clnt;
83
84 spin_unlock(&clnt->cl_lock);
85}
86
87static const struct seq_operations tasks_seq_operations = {
88 .start = tasks_start,
89 .next = tasks_next,
90 .stop = tasks_stop,
91 .show = tasks_show,
92};
93
94static int tasks_open(struct inode *inode, struct file *filp)
95{
96 int ret = seq_open_private(filp, &tasks_seq_operations,
97 sizeof(struct rpc_clnt_iter));
98
99 if (!ret) {
100 struct seq_file *seq = filp->private_data;
101 struct rpc_clnt_iter *iter = seq->private;
102
103 iter->clnt = inode->i_private;
104
105 if (!atomic_inc_not_zero(&iter->clnt->cl_count)) {
106 seq_release_private(inode, filp);
107 ret = -EINVAL;
108 }
109 }
110
111 return ret;
112}
113
114static int
115tasks_release(struct inode *inode, struct file *filp)
116{
117 struct seq_file *seq = filp->private_data;
118 struct rpc_clnt_iter *iter = seq->private;
119
120 rpc_release_client(iter->clnt);
121 return seq_release_private(inode, filp);
122}
123
124static const struct file_operations tasks_fops = {
125 .owner = THIS_MODULE,
126 .open = tasks_open,
127 .read = seq_read,
128 .llseek = seq_lseek,
129 .release = tasks_release,
130};
131
132int
133rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
134{
135 int len, err;
136 char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */
137
138 /* Already registered? */
139 if (clnt->cl_debugfs)
140 return 0;
141
142 len = snprintf(name, sizeof(name), "%x", clnt->cl_clid);
143 if (len >= sizeof(name))
144 return -EINVAL;
145
146 /* make the per-client dir */
147 clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir);
148 if (!clnt->cl_debugfs)
149 return -ENOMEM;
150
151 /* make tasks file */
152 err = -ENOMEM;
153 if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs,
154 clnt, &tasks_fops))
155 goto out_err;
156
157 err = -EINVAL;
158 rcu_read_lock();
159 len = snprintf(name, sizeof(name), "../../rpc_xprt/%s",
160 rcu_dereference(clnt->cl_xprt)->debugfs->d_name.name);
161 rcu_read_unlock();
162 if (len >= sizeof(name))
163 goto out_err;
164
165 err = -ENOMEM;
166 if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name))
167 goto out_err;
168
169 return 0;
170out_err:
171 debugfs_remove_recursive(clnt->cl_debugfs);
172 clnt->cl_debugfs = NULL;
173 return err;
174}
175
176void
177rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
178{
179 debugfs_remove_recursive(clnt->cl_debugfs);
180 clnt->cl_debugfs = NULL;
181}
182
183static int
184xprt_info_show(struct seq_file *f, void *v)
185{
186 struct rpc_xprt *xprt = f->private;
187
188 seq_printf(f, "netid: %s\n", xprt->address_strings[RPC_DISPLAY_NETID]);
189 seq_printf(f, "addr: %s\n", xprt->address_strings[RPC_DISPLAY_ADDR]);
190 seq_printf(f, "port: %s\n", xprt->address_strings[RPC_DISPLAY_PORT]);
191 seq_printf(f, "state: 0x%lx\n", xprt->state);
192 return 0;
193}
194
195static int
196xprt_info_open(struct inode *inode, struct file *filp)
197{
198 int ret;
199 struct rpc_xprt *xprt = inode->i_private;
200
201 ret = single_open(filp, xprt_info_show, xprt);
202
203 if (!ret) {
204 if (!xprt_get(xprt)) {
205 single_release(inode, filp);
206 ret = -EINVAL;
207 }
208 }
209 return ret;
210}
211
212static int
213xprt_info_release(struct inode *inode, struct file *filp)
214{
215 struct rpc_xprt *xprt = inode->i_private;
216
217 xprt_put(xprt);
218 return single_release(inode, filp);
219}
220
221static const struct file_operations xprt_info_fops = {
222 .owner = THIS_MODULE,
223 .open = xprt_info_open,
224 .read = seq_read,
225 .llseek = seq_lseek,
226 .release = xprt_info_release,
227};
228
229int
230rpc_xprt_debugfs_register(struct rpc_xprt *xprt)
231{
232 int len, id;
233 static atomic_t cur_id;
234 char name[9]; /* 8 hex digits + NULL term */
235
236 id = (unsigned int)atomic_inc_return(&cur_id);
237
238 len = snprintf(name, sizeof(name), "%x", id);
239 if (len >= sizeof(name))
240 return -EINVAL;
241
242 /* make the per-client dir */
243 xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir);
244 if (!xprt->debugfs)
245 return -ENOMEM;
246
247 /* make tasks file */
248 if (!debugfs_create_file("info", S_IFREG | S_IRUSR, xprt->debugfs,
249 xprt, &xprt_info_fops)) {
250 debugfs_remove_recursive(xprt->debugfs);
251 xprt->debugfs = NULL;
252 return -ENOMEM;
253 }
254
255 return 0;
256}
257
258void
259rpc_xprt_debugfs_unregister(struct rpc_xprt *xprt)
260{
261 debugfs_remove_recursive(xprt->debugfs);
262 xprt->debugfs = NULL;
263}
264
265void __exit
266sunrpc_debugfs_exit(void)
267{
268 debugfs_remove_recursive(topdir);
269}
270
271int __init
272sunrpc_debugfs_init(void)
273{
274 topdir = debugfs_create_dir("sunrpc", NULL);
275 if (!topdir)
276 goto out;
277
278 rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir);
279 if (!rpc_clnt_dir)
280 goto out_remove;
281
282 rpc_xprt_dir = debugfs_create_dir("rpc_xprt", topdir);
283 if (!rpc_xprt_dir)
284 goto out_remove;
285
286 return 0;
287out_remove:
288 debugfs_remove_recursive(topdir);
289 topdir = NULL;
290out:
291 return -ENOMEM;
292}
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 @@
32 32
33#include "netns.h" 33#include "netns.h"
34 34
35#ifdef RPC_DEBUG 35#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
36# define RPCDBG_FACILITY RPCDBG_BIND 36# define RPCDBG_FACILITY RPCDBG_BIND
37#endif 37#endif
38 38
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index fe3441abdbe5..d20f2329eea3 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -24,7 +24,7 @@
24 24
25#include "sunrpc.h" 25#include "sunrpc.h"
26 26
27#ifdef RPC_DEBUG 27#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
28#define RPCDBG_FACILITY RPCDBG_SCHED 28#define RPCDBG_FACILITY RPCDBG_SCHED
29#endif 29#endif
30 30
@@ -258,7 +258,7 @@ static int rpc_wait_bit_killable(struct wait_bit_key *key)
258 return 0; 258 return 0;
259} 259}
260 260
261#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS) 261#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
262static void rpc_task_set_debuginfo(struct rpc_task *task) 262static void rpc_task_set_debuginfo(struct rpc_task *task)
263{ 263{
264 static atomic_t rpc_pid; 264 static atomic_t rpc_pid;
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 54530490944e..9711a155bc50 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -116,7 +116,15 @@ EXPORT_SYMBOL_GPL(svc_seq_show);
116 */ 116 */
117struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) 117struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt)
118{ 118{
119 return kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL); 119 struct rpc_iostats *stats;
120 int i;
121
122 stats = kcalloc(clnt->cl_maxproc, sizeof(*stats), GFP_KERNEL);
123 if (stats) {
124 for (i = 0; i < clnt->cl_maxproc; i++)
125 spin_lock_init(&stats[i].om_lock);
126 }
127 return stats;
120} 128}
121EXPORT_SYMBOL_GPL(rpc_alloc_iostats); 129EXPORT_SYMBOL_GPL(rpc_alloc_iostats);
122 130
@@ -135,20 +143,21 @@ EXPORT_SYMBOL_GPL(rpc_free_iostats);
135 * rpc_count_iostats - tally up per-task stats 143 * rpc_count_iostats - tally up per-task stats
136 * @task: completed rpc_task 144 * @task: completed rpc_task
137 * @stats: array of stat structures 145 * @stats: array of stat structures
138 *
139 * Relies on the caller for serialization.
140 */ 146 */
141void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats) 147void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats)
142{ 148{
143 struct rpc_rqst *req = task->tk_rqstp; 149 struct rpc_rqst *req = task->tk_rqstp;
144 struct rpc_iostats *op_metrics; 150 struct rpc_iostats *op_metrics;
145 ktime_t delta; 151 ktime_t delta, now;
146 152
147 if (!stats || !req) 153 if (!stats || !req)
148 return; 154 return;
149 155
156 now = ktime_get();
150 op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx]; 157 op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx];
151 158
159 spin_lock(&op_metrics->om_lock);
160
152 op_metrics->om_ops++; 161 op_metrics->om_ops++;
153 op_metrics->om_ntrans += req->rq_ntrans; 162 op_metrics->om_ntrans += req->rq_ntrans;
154 op_metrics->om_timeouts += task->tk_timeouts; 163 op_metrics->om_timeouts += task->tk_timeouts;
@@ -161,8 +170,10 @@ void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats)
161 170
162 op_metrics->om_rtt = ktime_add(op_metrics->om_rtt, req->rq_rtt); 171 op_metrics->om_rtt = ktime_add(op_metrics->om_rtt, req->rq_rtt);
163 172
164 delta = ktime_sub(ktime_get(), task->tk_start); 173 delta = ktime_sub(now, task->tk_start);
165 op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta); 174 op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta);
175
176 spin_unlock(&op_metrics->om_lock);
166} 177}
167EXPORT_SYMBOL_GPL(rpc_count_iostats); 178EXPORT_SYMBOL_GPL(rpc_count_iostats);
168 179
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index cd30120de9e4..e37fbed87956 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -97,13 +97,20 @@ init_sunrpc(void)
97 err = register_rpc_pipefs(); 97 err = register_rpc_pipefs();
98 if (err) 98 if (err)
99 goto out4; 99 goto out4;
100#ifdef RPC_DEBUG 100
101 err = sunrpc_debugfs_init();
102 if (err)
103 goto out5;
104
105#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
101 rpc_register_sysctl(); 106 rpc_register_sysctl();
102#endif 107#endif
103 svc_init_xprt_sock(); /* svc sock transport */ 108 svc_init_xprt_sock(); /* svc sock transport */
104 init_socket_xprt(); /* clnt sock transport */ 109 init_socket_xprt(); /* clnt sock transport */
105 return 0; 110 return 0;
106 111
112out5:
113 unregister_rpc_pipefs();
107out4: 114out4:
108 unregister_pernet_subsys(&sunrpc_net_ops); 115 unregister_pernet_subsys(&sunrpc_net_ops);
109out3: 116out3:
@@ -120,10 +127,11 @@ cleanup_sunrpc(void)
120 rpcauth_remove_module(); 127 rpcauth_remove_module();
121 cleanup_socket_xprt(); 128 cleanup_socket_xprt();
122 svc_cleanup_xprt_sock(); 129 svc_cleanup_xprt_sock();
130 sunrpc_debugfs_exit();
123 unregister_rpc_pipefs(); 131 unregister_rpc_pipefs();
124 rpc_destroy_mempool(); 132 rpc_destroy_mempool();
125 unregister_pernet_subsys(&sunrpc_net_ops); 133 unregister_pernet_subsys(&sunrpc_net_ops);
126#ifdef RPC_DEBUG 134#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
127 rpc_unregister_sysctl(); 135 rpc_unregister_sysctl();
128#endif 136#endif
129 rcu_barrier(); /* Wait for completion of call_rcu()'s */ 137 rcu_barrier(); /* Wait for completion of call_rcu()'s */
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index ca8a7958f4e6..2783fd80c229 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -28,6 +28,8 @@
28#include <linux/sunrpc/clnt.h> 28#include <linux/sunrpc/clnt.h>
29#include <linux/sunrpc/bc_xprt.h> 29#include <linux/sunrpc/bc_xprt.h>
30 30
31#include <trace/events/sunrpc.h>
32
31#define RPCDBG_FACILITY RPCDBG_SVCDSP 33#define RPCDBG_FACILITY RPCDBG_SVCDSP
32 34
33static void svc_unregister(const struct svc_serv *serv, struct net *net); 35static void svc_unregister(const struct svc_serv *serv, struct net *net);
@@ -1040,7 +1042,7 @@ static void svc_unregister(const struct svc_serv *serv, struct net *net)
1040/* 1042/*
1041 * dprintk the given error with the address of the client that caused it. 1043 * dprintk the given error with the address of the client that caused it.
1042 */ 1044 */
1043#ifdef RPC_DEBUG 1045#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
1044static __printf(2, 3) 1046static __printf(2, 3)
1045void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) 1047void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
1046{ 1048{
@@ -1314,24 +1316,25 @@ svc_process(struct svc_rqst *rqstp)
1314 rqstp->rq_res.tail[0].iov_base = NULL; 1316 rqstp->rq_res.tail[0].iov_base = NULL;
1315 rqstp->rq_res.tail[0].iov_len = 0; 1317 rqstp->rq_res.tail[0].iov_len = 0;
1316 1318
1317 rqstp->rq_xid = svc_getu32(argv);
1318
1319 dir = svc_getnl(argv); 1319 dir = svc_getnl(argv);
1320 if (dir != 0) { 1320 if (dir != 0) {
1321 /* direction != CALL */ 1321 /* direction != CALL */
1322 svc_printk(rqstp, "bad direction %d, dropping request\n", dir); 1322 svc_printk(rqstp, "bad direction %d, dropping request\n", dir);
1323 serv->sv_stats->rpcbadfmt++; 1323 serv->sv_stats->rpcbadfmt++;
1324 svc_drop(rqstp); 1324 goto out_drop;
1325 return 0;
1326 } 1325 }
1327 1326
1328 /* Returns 1 for send, 0 for drop */ 1327 /* Returns 1 for send, 0 for drop */
1329 if (svc_process_common(rqstp, argv, resv)) 1328 if (likely(svc_process_common(rqstp, argv, resv))) {
1330 return svc_send(rqstp); 1329 int ret = svc_send(rqstp);
1331 else { 1330
1332 svc_drop(rqstp); 1331 trace_svc_process(rqstp, ret);
1333 return 0; 1332 return ret;
1334 } 1333 }
1334out_drop:
1335 trace_svc_process(rqstp, 0);
1336 svc_drop(rqstp);
1337 return 0;
1335} 1338}
1336 1339
1337#if defined(CONFIG_SUNRPC_BACKCHANNEL) 1340#if defined(CONFIG_SUNRPC_BACKCHANNEL)
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index c179ca2a5aa4..bbb3b044b877 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -15,6 +15,7 @@
15#include <linux/sunrpc/svcsock.h> 15#include <linux/sunrpc/svcsock.h>
16#include <linux/sunrpc/xprt.h> 16#include <linux/sunrpc/xprt.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <trace/events/sunrpc.h>
18 19
19#define RPCDBG_FACILITY RPCDBG_SVCXPRT 20#define RPCDBG_FACILITY RPCDBG_SVCXPRT
20 21
@@ -773,35 +774,43 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
773 774
774 err = svc_alloc_arg(rqstp); 775 err = svc_alloc_arg(rqstp);
775 if (err) 776 if (err)
776 return err; 777 goto out;
777 778
778 try_to_freeze(); 779 try_to_freeze();
779 cond_resched(); 780 cond_resched();
781 err = -EINTR;
780 if (signalled() || kthread_should_stop()) 782 if (signalled() || kthread_should_stop())
781 return -EINTR; 783 goto out;
782 784
783 xprt = svc_get_next_xprt(rqstp, timeout); 785 xprt = svc_get_next_xprt(rqstp, timeout);
784 if (IS_ERR(xprt)) 786 if (IS_ERR(xprt)) {
785 return PTR_ERR(xprt); 787 err = PTR_ERR(xprt);
788 goto out;
789 }
786 790
787 len = svc_handle_xprt(rqstp, xprt); 791 len = svc_handle_xprt(rqstp, xprt);
788 792
789 /* No data, incomplete (TCP) read, or accept() */ 793 /* No data, incomplete (TCP) read, or accept() */
794 err = -EAGAIN;
790 if (len <= 0) 795 if (len <= 0)
791 goto out; 796 goto out_release;
792 797
793 clear_bit(XPT_OLD, &xprt->xpt_flags); 798 clear_bit(XPT_OLD, &xprt->xpt_flags);
794 799
795 rqstp->rq_secure = xprt->xpt_ops->xpo_secure_port(rqstp); 800 rqstp->rq_secure = xprt->xpt_ops->xpo_secure_port(rqstp);
796 rqstp->rq_chandle.defer = svc_defer; 801 rqstp->rq_chandle.defer = svc_defer;
802 rqstp->rq_xid = svc_getu32(&rqstp->rq_arg.head[0]);
797 803
798 if (serv->sv_stats) 804 if (serv->sv_stats)
799 serv->sv_stats->netcnt++; 805 serv->sv_stats->netcnt++;
806 trace_svc_recv(rqstp, len);
800 return len; 807 return len;
801out: 808out_release:
802 rqstp->rq_res.len = 0; 809 rqstp->rq_res.len = 0;
803 svc_xprt_release(rqstp); 810 svc_xprt_release(rqstp);
804 return -EAGAIN; 811out:
812 trace_svc_recv(rqstp, err);
813 return err;
805} 814}
806EXPORT_SYMBOL_GPL(svc_recv); 815EXPORT_SYMBOL_GPL(svc_recv);
807 816
@@ -821,12 +830,12 @@ EXPORT_SYMBOL_GPL(svc_drop);
821int svc_send(struct svc_rqst *rqstp) 830int svc_send(struct svc_rqst *rqstp)
822{ 831{
823 struct svc_xprt *xprt; 832 struct svc_xprt *xprt;
824 int len; 833 int len = -EFAULT;
825 struct xdr_buf *xb; 834 struct xdr_buf *xb;
826 835
827 xprt = rqstp->rq_xprt; 836 xprt = rqstp->rq_xprt;
828 if (!xprt) 837 if (!xprt)
829 return -EFAULT; 838 goto out;
830 839
831 /* release the receive skb before sending the reply */ 840 /* release the receive skb before sending the reply */
832 rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp); 841 rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
@@ -849,7 +858,9 @@ int svc_send(struct svc_rqst *rqstp)
849 svc_xprt_release(rqstp); 858 svc_xprt_release(rqstp);
850 859
851 if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN) 860 if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN)
852 return 0; 861 len = 0;
862out:
863 trace_svc_send(rqstp, len);
853 return len; 864 return len;
854} 865}
855 866
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);
37unsigned int nlm_debug; 37unsigned int nlm_debug;
38EXPORT_SYMBOL_GPL(nlm_debug); 38EXPORT_SYMBOL_GPL(nlm_debug);
39 39
40#ifdef RPC_DEBUG 40#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
41 41
42static struct ctl_table_header *sunrpc_table_header; 42static struct ctl_table_header *sunrpc_table_header;
43static struct ctl_table sunrpc_table[]; 43static struct ctl_table sunrpc_table[];
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 56e4e150e80e..ebbefad21a37 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -49,13 +49,15 @@
49#include <linux/sunrpc/metrics.h> 49#include <linux/sunrpc/metrics.h>
50#include <linux/sunrpc/bc_xprt.h> 50#include <linux/sunrpc/bc_xprt.h>
51 51
52#include <trace/events/sunrpc.h>
53
52#include "sunrpc.h" 54#include "sunrpc.h"
53 55
54/* 56/*
55 * Local variables 57 * Local variables
56 */ 58 */
57 59
58#ifdef RPC_DEBUG 60#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
59# define RPCDBG_FACILITY RPCDBG_XPRT 61# define RPCDBG_FACILITY RPCDBG_XPRT
60#endif 62#endif
61 63
@@ -772,11 +774,14 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
772 struct rpc_rqst *entry; 774 struct rpc_rqst *entry;
773 775
774 list_for_each_entry(entry, &xprt->recv, rq_list) 776 list_for_each_entry(entry, &xprt->recv, rq_list)
775 if (entry->rq_xid == xid) 777 if (entry->rq_xid == xid) {
778 trace_xprt_lookup_rqst(xprt, xid, 0);
776 return entry; 779 return entry;
780 }
777 781
778 dprintk("RPC: xprt_lookup_rqst did not find xid %08x\n", 782 dprintk("RPC: xprt_lookup_rqst did not find xid %08x\n",
779 ntohl(xid)); 783 ntohl(xid));
784 trace_xprt_lookup_rqst(xprt, xid, -ENOENT);
780 xprt->stat.bad_xids++; 785 xprt->stat.bad_xids++;
781 return NULL; 786 return NULL;
782} 787}
@@ -810,6 +815,7 @@ void xprt_complete_rqst(struct rpc_task *task, int copied)
810 815
811 dprintk("RPC: %5u xid %08x complete (%d bytes received)\n", 816 dprintk("RPC: %5u xid %08x complete (%d bytes received)\n",
812 task->tk_pid, ntohl(req->rq_xid), copied); 817 task->tk_pid, ntohl(req->rq_xid), copied);
818 trace_xprt_complete_rqst(xprt, req->rq_xid, copied);
813 819
814 xprt->stat.recvs++; 820 xprt->stat.recvs++;
815 req->rq_rtt = ktime_sub(ktime_get(), req->rq_xtime); 821 req->rq_rtt = ktime_sub(ktime_get(), req->rq_xtime);
@@ -926,6 +932,7 @@ void xprt_transmit(struct rpc_task *task)
926 932
927 req->rq_xtime = ktime_get(); 933 req->rq_xtime = ktime_get();
928 status = xprt->ops->send_request(task); 934 status = xprt->ops->send_request(task);
935 trace_xprt_transmit(xprt, req->rq_xid, status);
929 if (status != 0) { 936 if (status != 0) {
930 task->tk_status = status; 937 task->tk_status = status;
931 return; 938 return;
@@ -1296,6 +1303,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net)
1296 */ 1303 */
1297struct rpc_xprt *xprt_create_transport(struct xprt_create *args) 1304struct rpc_xprt *xprt_create_transport(struct xprt_create *args)
1298{ 1305{
1306 int err;
1299 struct rpc_xprt *xprt; 1307 struct rpc_xprt *xprt;
1300 struct xprt_class *t; 1308 struct xprt_class *t;
1301 1309
@@ -1336,6 +1344,12 @@ found:
1336 return ERR_PTR(-ENOMEM); 1344 return ERR_PTR(-ENOMEM);
1337 } 1345 }
1338 1346
1347 err = rpc_xprt_debugfs_register(xprt);
1348 if (err) {
1349 xprt_destroy(xprt);
1350 return ERR_PTR(err);
1351 }
1352
1339 dprintk("RPC: created transport %p with %u slots\n", xprt, 1353 dprintk("RPC: created transport %p with %u slots\n", xprt,
1340 xprt->max_reqs); 1354 xprt->max_reqs);
1341out: 1355out:
@@ -1352,6 +1366,7 @@ static void xprt_destroy(struct rpc_xprt *xprt)
1352 dprintk("RPC: destroying transport %p\n", xprt); 1366 dprintk("RPC: destroying transport %p\n", xprt);
1353 del_timer_sync(&xprt->timer); 1367 del_timer_sync(&xprt->timer);
1354 1368
1369 rpc_xprt_debugfs_unregister(xprt);
1355 rpc_destroy_wait_queue(&xprt->binding); 1370 rpc_destroy_wait_queue(&xprt->binding);
1356 rpc_destroy_wait_queue(&xprt->pending); 1371 rpc_destroy_wait_queue(&xprt->pending);
1357 rpc_destroy_wait_queue(&xprt->sending); 1372 rpc_destroy_wait_queue(&xprt->sending);
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 @@
49 49
50#include <linux/highmem.h> 50#include <linux/highmem.h>
51 51
52#ifdef RPC_DEBUG 52#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
53# define RPCDBG_FACILITY RPCDBG_TRANS 53# define RPCDBG_FACILITY RPCDBG_TRANS
54#endif 54#endif
55 55
56#ifdef RPC_DEBUG 56#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
57static const char transfertypes[][12] = { 57static const char transfertypes[][12] = {
58 "pure inline", /* no chunks */ 58 "pure inline", /* no chunks */
59 " read chunk", /* some argument via rdma read */ 59 " read chunk", /* some argument via rdma read */
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 6a4615dd0261..bbd6155d3e34 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -55,7 +55,7 @@
55 55
56#include "xprt_rdma.h" 56#include "xprt_rdma.h"
57 57
58#ifdef RPC_DEBUG 58#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
59# define RPCDBG_FACILITY RPCDBG_TRANS 59# define RPCDBG_FACILITY RPCDBG_TRANS
60#endif 60#endif
61 61
@@ -73,9 +73,9 @@ static unsigned int xprt_rdma_max_inline_read = RPCRDMA_DEF_INLINE;
73static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE; 73static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE;
74static unsigned int xprt_rdma_inline_write_padding; 74static unsigned int xprt_rdma_inline_write_padding;
75static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR; 75static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR;
76 int xprt_rdma_pad_optimize = 0; 76 int xprt_rdma_pad_optimize = 1;
77 77
78#ifdef RPC_DEBUG 78#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
79 79
80static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE; 80static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE;
81static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE; 81static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE;
@@ -599,7 +599,7 @@ xprt_rdma_send_request(struct rpc_task *task)
599 599
600 if (req->rl_niovs == 0) 600 if (req->rl_niovs == 0)
601 rc = rpcrdma_marshal_req(rqst); 601 rc = rpcrdma_marshal_req(rqst);
602 else if (r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR) 602 else if (r_xprt->rx_ia.ri_memreg_strategy != RPCRDMA_ALLPHYSICAL)
603 rc = rpcrdma_marshal_chunks(rqst, 0); 603 rc = rpcrdma_marshal_chunks(rqst, 0);
604 if (rc < 0) 604 if (rc < 0)
605 goto failed_marshal; 605 goto failed_marshal;
@@ -705,7 +705,7 @@ static void __exit xprt_rdma_cleanup(void)
705 int rc; 705 int rc;
706 706
707 dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n"); 707 dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n");
708#ifdef RPC_DEBUG 708#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
709 if (sunrpc_table_header) { 709 if (sunrpc_table_header) {
710 unregister_sysctl_table(sunrpc_table_header); 710 unregister_sysctl_table(sunrpc_table_header);
711 sunrpc_table_header = NULL; 711 sunrpc_table_header = NULL;
@@ -736,7 +736,7 @@ static int __init xprt_rdma_init(void)
736 dprintk("\tPadding %d\n\tMemreg %d\n", 736 dprintk("\tPadding %d\n\tMemreg %d\n",
737 xprt_rdma_inline_write_padding, xprt_rdma_memreg_strategy); 737 xprt_rdma_inline_write_padding, xprt_rdma_memreg_strategy);
738 738
739#ifdef RPC_DEBUG 739#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
740 if (!sunrpc_table_header) 740 if (!sunrpc_table_header)
741 sunrpc_table_header = register_sysctl_table(sunrpc_table); 741 sunrpc_table_header = register_sysctl_table(sunrpc_table);
742#endif 742#endif
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 61c41298b4ea..c98e40643910 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -57,11 +57,12 @@
57 * Globals/Macros 57 * Globals/Macros
58 */ 58 */
59 59
60#ifdef RPC_DEBUG 60#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
61# define RPCDBG_FACILITY RPCDBG_TRANS 61# define RPCDBG_FACILITY RPCDBG_TRANS
62#endif 62#endif
63 63
64static void rpcrdma_reset_frmrs(struct rpcrdma_ia *); 64static void rpcrdma_reset_frmrs(struct rpcrdma_ia *);
65static void rpcrdma_reset_fmrs(struct rpcrdma_ia *);
65 66
66/* 67/*
67 * internal functions 68 * internal functions
@@ -105,13 +106,51 @@ rpcrdma_run_tasklet(unsigned long data)
105 106
106static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL); 107static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL);
107 108
109static const char * const async_event[] = {
110 "CQ error",
111 "QP fatal error",
112 "QP request error",
113 "QP access error",
114 "communication established",
115 "send queue drained",
116 "path migration successful",
117 "path mig error",
118 "device fatal error",
119 "port active",
120 "port error",
121 "LID change",
122 "P_key change",
123 "SM change",
124 "SRQ error",
125 "SRQ limit reached",
126 "last WQE reached",
127 "client reregister",
128 "GID change",
129};
130
131#define ASYNC_MSG(status) \
132 ((status) < ARRAY_SIZE(async_event) ? \
133 async_event[(status)] : "unknown async error")
134
135static void
136rpcrdma_schedule_tasklet(struct list_head *sched_list)
137{
138 unsigned long flags;
139
140 spin_lock_irqsave(&rpcrdma_tk_lock_g, flags);
141 list_splice_tail(sched_list, &rpcrdma_tasklets_g);
142 spin_unlock_irqrestore(&rpcrdma_tk_lock_g, flags);
143 tasklet_schedule(&rpcrdma_tasklet_g);
144}
145
108static void 146static void
109rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context) 147rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context)
110{ 148{
111 struct rpcrdma_ep *ep = context; 149 struct rpcrdma_ep *ep = context;
112 150
113 dprintk("RPC: %s: QP error %X on device %s ep %p\n", 151 pr_err("RPC: %s: %s on device %s ep %p\n",
114 __func__, event->event, event->device->name, context); 152 __func__, ASYNC_MSG(event->event),
153 event->device->name, context);
115 if (ep->rep_connected == 1) { 154 if (ep->rep_connected == 1) {
116 ep->rep_connected = -EIO; 155 ep->rep_connected = -EIO;
117 ep->rep_func(ep); 156 ep->rep_func(ep);
@@ -124,8 +163,9 @@ rpcrdma_cq_async_error_upcall(struct ib_event *event, void *context)
124{ 163{
125 struct rpcrdma_ep *ep = context; 164 struct rpcrdma_ep *ep = context;
126 165
127 dprintk("RPC: %s: CQ error %X on device %s ep %p\n", 166 pr_err("RPC: %s: %s on device %s ep %p\n",
128 __func__, event->event, event->device->name, context); 167 __func__, ASYNC_MSG(event->event),
168 event->device->name, context);
129 if (ep->rep_connected == 1) { 169 if (ep->rep_connected == 1) {
130 ep->rep_connected = -EIO; 170 ep->rep_connected = -EIO;
131 ep->rep_func(ep); 171 ep->rep_func(ep);
@@ -243,7 +283,6 @@ rpcrdma_recvcq_poll(struct ib_cq *cq, struct rpcrdma_ep *ep)
243 struct list_head sched_list; 283 struct list_head sched_list;
244 struct ib_wc *wcs; 284 struct ib_wc *wcs;
245 int budget, count, rc; 285 int budget, count, rc;
246 unsigned long flags;
247 286
248 INIT_LIST_HEAD(&sched_list); 287 INIT_LIST_HEAD(&sched_list);
249 budget = RPCRDMA_WC_BUDGET / RPCRDMA_POLLSIZE; 288 budget = RPCRDMA_WC_BUDGET / RPCRDMA_POLLSIZE;
@@ -261,10 +300,7 @@ rpcrdma_recvcq_poll(struct ib_cq *cq, struct rpcrdma_ep *ep)
261 rc = 0; 300 rc = 0;
262 301
263out_schedule: 302out_schedule:
264 spin_lock_irqsave(&rpcrdma_tk_lock_g, flags); 303 rpcrdma_schedule_tasklet(&sched_list);
265 list_splice_tail(&sched_list, &rpcrdma_tasklets_g);
266 spin_unlock_irqrestore(&rpcrdma_tk_lock_g, flags);
267 tasklet_schedule(&rpcrdma_tasklet_g);
268 return rc; 304 return rc;
269} 305}
270 306
@@ -309,11 +345,18 @@ rpcrdma_recvcq_upcall(struct ib_cq *cq, void *cq_context)
309static void 345static void
310rpcrdma_flush_cqs(struct rpcrdma_ep *ep) 346rpcrdma_flush_cqs(struct rpcrdma_ep *ep)
311{ 347{
312 rpcrdma_recvcq_upcall(ep->rep_attr.recv_cq, ep); 348 struct ib_wc wc;
313 rpcrdma_sendcq_upcall(ep->rep_attr.send_cq, ep); 349 LIST_HEAD(sched_list);
350
351 while (ib_poll_cq(ep->rep_attr.recv_cq, 1, &wc) > 0)
352 rpcrdma_recvcq_process_wc(&wc, &sched_list);
353 if (!list_empty(&sched_list))
354 rpcrdma_schedule_tasklet(&sched_list);
355 while (ib_poll_cq(ep->rep_attr.send_cq, 1, &wc) > 0)
356 rpcrdma_sendcq_process_wc(&wc);
314} 357}
315 358
316#ifdef RPC_DEBUG 359#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
317static const char * const conn[] = { 360static const char * const conn[] = {
318 "address resolved", 361 "address resolved",
319 "address error", 362 "address error",
@@ -344,7 +387,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
344 struct rpcrdma_xprt *xprt = id->context; 387 struct rpcrdma_xprt *xprt = id->context;
345 struct rpcrdma_ia *ia = &xprt->rx_ia; 388 struct rpcrdma_ia *ia = &xprt->rx_ia;
346 struct rpcrdma_ep *ep = &xprt->rx_ep; 389 struct rpcrdma_ep *ep = &xprt->rx_ep;
347#ifdef RPC_DEBUG 390#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
348 struct sockaddr_in *addr = (struct sockaddr_in *) &ep->rep_remote_addr; 391 struct sockaddr_in *addr = (struct sockaddr_in *) &ep->rep_remote_addr;
349#endif 392#endif
350 struct ib_qp_attr attr; 393 struct ib_qp_attr attr;
@@ -408,7 +451,7 @@ connected:
408 break; 451 break;
409 } 452 }
410 453
411#ifdef RPC_DEBUG 454#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
412 if (connstate == 1) { 455 if (connstate == 1) {
413 int ird = attr.max_dest_rd_atomic; 456 int ird = attr.max_dest_rd_atomic;
414 int tird = ep->rep_remote_cma.responder_resources; 457 int tird = ep->rep_remote_cma.responder_resources;
@@ -733,7 +776,9 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
733 776
734 /* set trigger for requesting send completion */ 777 /* set trigger for requesting send completion */
735 ep->rep_cqinit = ep->rep_attr.cap.max_send_wr/2 - 1; 778 ep->rep_cqinit = ep->rep_attr.cap.max_send_wr/2 - 1;
736 if (ep->rep_cqinit <= 2) 779 if (ep->rep_cqinit > RPCRDMA_MAX_UNSIGNALED_SENDS)
780 ep->rep_cqinit = RPCRDMA_MAX_UNSIGNALED_SENDS;
781 else if (ep->rep_cqinit <= 2)
737 ep->rep_cqinit = 0; 782 ep->rep_cqinit = 0;
738 INIT_CQCOUNT(ep); 783 INIT_CQCOUNT(ep);
739 ep->rep_ia = ia; 784 ep->rep_ia = ia;
@@ -866,8 +911,19 @@ retry:
866 rpcrdma_ep_disconnect(ep, ia); 911 rpcrdma_ep_disconnect(ep, ia);
867 rpcrdma_flush_cqs(ep); 912 rpcrdma_flush_cqs(ep);
868 913
869 if (ia->ri_memreg_strategy == RPCRDMA_FRMR) 914 switch (ia->ri_memreg_strategy) {
915 case RPCRDMA_FRMR:
870 rpcrdma_reset_frmrs(ia); 916 rpcrdma_reset_frmrs(ia);
917 break;
918 case RPCRDMA_MTHCAFMR:
919 rpcrdma_reset_fmrs(ia);
920 break;
921 case RPCRDMA_ALLPHYSICAL:
922 break;
923 default:
924 rc = -EIO;
925 goto out;
926 }
871 927
872 xprt = container_of(ia, struct rpcrdma_xprt, rx_ia); 928 xprt = container_of(ia, struct rpcrdma_xprt, rx_ia);
873 id = rpcrdma_create_id(xprt, ia, 929 id = rpcrdma_create_id(xprt, ia,
@@ -1287,6 +1343,34 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
1287 kfree(buf->rb_pool); 1343 kfree(buf->rb_pool);
1288} 1344}
1289 1345
1346/* After a disconnect, unmap all FMRs.
1347 *
1348 * This is invoked only in the transport connect worker in order
1349 * to serialize with rpcrdma_register_fmr_external().
1350 */
1351static void
1352rpcrdma_reset_fmrs(struct rpcrdma_ia *ia)
1353{
1354 struct rpcrdma_xprt *r_xprt =
1355 container_of(ia, struct rpcrdma_xprt, rx_ia);
1356 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
1357 struct list_head *pos;
1358 struct rpcrdma_mw *r;
1359 LIST_HEAD(l);
1360 int rc;
1361
1362 list_for_each(pos, &buf->rb_all) {
1363 r = list_entry(pos, struct rpcrdma_mw, mw_all);
1364
1365 INIT_LIST_HEAD(&l);
1366 list_add(&r->r.fmr->list, &l);
1367 rc = ib_unmap_fmr(&l);
1368 if (rc)
1369 dprintk("RPC: %s: ib_unmap_fmr failed %i\n",
1370 __func__, rc);
1371 }
1372}
1373
1290/* After a disconnect, a flushed FAST_REG_MR can leave an FRMR in 1374/* After a disconnect, a flushed FAST_REG_MR can leave an FRMR in
1291 * an unusable state. Find FRMRs in this state and dereg / reg 1375 * an unusable state. Find FRMRs in this state and dereg / reg
1292 * each. FRMRs that are VALID and attached to an rpcrdma_req are 1376 * each. FRMRs that are VALID and attached to an rpcrdma_req are
@@ -1918,10 +2002,10 @@ rpcrdma_register_external(struct rpcrdma_mr_seg *seg,
1918 break; 2002 break;
1919 2003
1920 default: 2004 default:
1921 return -1; 2005 return -EIO;
1922 } 2006 }
1923 if (rc) 2007 if (rc)
1924 return -1; 2008 return rc;
1925 2009
1926 return nsegs; 2010 return nsegs;
1927} 2011}
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index ac7fc9a31342..b799041b75bf 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -97,6 +97,12 @@ struct rpcrdma_ep {
97 struct ib_wc rep_recv_wcs[RPCRDMA_POLLSIZE]; 97 struct ib_wc rep_recv_wcs[RPCRDMA_POLLSIZE];
98}; 98};
99 99
100/*
101 * Force a signaled SEND Work Request every so often,
102 * in case the provider needs to do some housekeeping.
103 */
104#define RPCRDMA_MAX_UNSIGNALED_SENDS (32)
105
100#define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit) 106#define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit)
101#define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount) 107#define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount)
102 108
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 3b305ab17afe..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;
75 * someone else's file names! 75 * someone else's file names!
76 */ 76 */
77 77
78#ifdef RPC_DEBUG 78#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
79 79
80static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; 80static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
81static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; 81static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
@@ -186,7 +186,7 @@ static struct ctl_table sunrpc_table[] = {
186 */ 186 */
187#define XS_IDLE_DISC_TO (5U * 60 * HZ) 187#define XS_IDLE_DISC_TO (5U * 60 * HZ)
188 188
189#ifdef RPC_DEBUG 189#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
190# undef RPC_DEBUG_DATA 190# undef RPC_DEBUG_DATA
191# define RPCDBG_FACILITY RPCDBG_TRANS 191# define RPCDBG_FACILITY RPCDBG_TRANS
192#endif 192#endif
@@ -216,65 +216,6 @@ static inline void xs_pktdump(char *msg, u32 *packet, unsigned int count)
216} 216}
217#endif 217#endif
218 218
219struct sock_xprt {
220 struct rpc_xprt xprt;
221
222 /*
223 * Network layer
224 */
225 struct socket * sock;
226 struct sock * inet;
227
228 /*
229 * State of TCP reply receive
230 */
231 __be32 tcp_fraghdr,
232 tcp_xid,
233 tcp_calldir;
234
235 u32 tcp_offset,
236 tcp_reclen;
237
238 unsigned long tcp_copied,
239 tcp_flags;
240
241 /*
242 * Connection of transports
243 */
244 struct delayed_work connect_worker;
245 struct sockaddr_storage srcaddr;
246 unsigned short srcport;
247
248 /*
249 * UDP socket buffer size parameters
250 */
251 size_t rcvsize,
252 sndsize;
253
254 /*
255 * Saved socket callback addresses
256 */
257 void (*old_data_ready)(struct sock *);
258 void (*old_state_change)(struct sock *);
259 void (*old_write_space)(struct sock *);
260 void (*old_error_report)(struct sock *);
261};
262
263/*
264 * TCP receive state flags
265 */
266#define TCP_RCV_LAST_FRAG (1UL << 0)
267#define TCP_RCV_COPY_FRAGHDR (1UL << 1)
268#define TCP_RCV_COPY_XID (1UL << 2)
269#define TCP_RCV_COPY_DATA (1UL << 3)
270#define TCP_RCV_READ_CALLDIR (1UL << 4)
271#define TCP_RCV_COPY_CALLDIR (1UL << 5)
272
273/*
274 * TCP RPC flags
275 */
276#define TCP_RPC_REPLY (1UL << 6)
277
278static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) 219static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
279{ 220{
280 return (struct rpc_xprt *) sk->sk_user_data; 221 return (struct rpc_xprt *) sk->sk_user_data;
@@ -1415,6 +1356,7 @@ static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, uns
1415 1356
1416 dprintk("RPC: xs_tcp_data_recv started\n"); 1357 dprintk("RPC: xs_tcp_data_recv started\n");
1417 do { 1358 do {
1359 trace_xs_tcp_data_recv(transport);
1418 /* Read in a new fragment marker if necessary */ 1360 /* Read in a new fragment marker if necessary */
1419 /* Can we ever really expect to get completely empty fragments? */ 1361 /* Can we ever really expect to get completely empty fragments? */
1420 if (transport->tcp_flags & TCP_RCV_COPY_FRAGHDR) { 1362 if (transport->tcp_flags & TCP_RCV_COPY_FRAGHDR) {
@@ -1439,6 +1381,7 @@ static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, uns
1439 /* Skip over any trailing bytes on short reads */ 1381 /* Skip over any trailing bytes on short reads */
1440 xs_tcp_read_discard(transport, &desc); 1382 xs_tcp_read_discard(transport, &desc);
1441 } while (desc.count); 1383 } while (desc.count);
1384 trace_xs_tcp_data_recv(transport);
1442 dprintk("RPC: xs_tcp_data_recv done\n"); 1385 dprintk("RPC: xs_tcp_data_recv done\n");
1443 return len - desc.count; 1386 return len - desc.count;
1444} 1387}
@@ -1454,12 +1397,15 @@ static void xs_tcp_data_ready(struct sock *sk)
1454 struct rpc_xprt *xprt; 1397 struct rpc_xprt *xprt;
1455 read_descriptor_t rd_desc; 1398 read_descriptor_t rd_desc;
1456 int read; 1399 int read;
1400 unsigned long total = 0;
1457 1401
1458 dprintk("RPC: xs_tcp_data_ready...\n"); 1402 dprintk("RPC: xs_tcp_data_ready...\n");
1459 1403
1460 read_lock_bh(&sk->sk_callback_lock); 1404 read_lock_bh(&sk->sk_callback_lock);
1461 if (!(xprt = xprt_from_sock(sk))) 1405 if (!(xprt = xprt_from_sock(sk))) {
1406 read = 0;
1462 goto out; 1407 goto out;
1408 }
1463 /* Any data means we had a useful conversation, so 1409 /* Any data means we had a useful conversation, so
1464 * the we don't need to delay the next reconnect 1410 * the we don't need to delay the next reconnect
1465 */ 1411 */
@@ -1471,8 +1417,11 @@ static void xs_tcp_data_ready(struct sock *sk)
1471 do { 1417 do {
1472 rd_desc.count = 65536; 1418 rd_desc.count = 65536;
1473 read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); 1419 read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
1420 if (read > 0)
1421 total += read;
1474 } while (read > 0); 1422 } while (read > 0);
1475out: 1423out:
1424 trace_xs_tcp_data_ready(xprt, read, total);
1476 read_unlock_bh(&sk->sk_callback_lock); 1425 read_unlock_bh(&sk->sk_callback_lock);
1477} 1426}
1478 1427
@@ -3042,7 +2991,7 @@ static struct xprt_class xs_bc_tcp_transport = {
3042 */ 2991 */
3043int init_socket_xprt(void) 2992int init_socket_xprt(void)
3044{ 2993{
3045#ifdef RPC_DEBUG 2994#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
3046 if (!sunrpc_table_header) 2995 if (!sunrpc_table_header)
3047 sunrpc_table_header = register_sysctl_table(sunrpc_table); 2996 sunrpc_table_header = register_sysctl_table(sunrpc_table);
3048#endif 2997#endif
@@ -3061,7 +3010,7 @@ int init_socket_xprt(void)
3061 */ 3010 */
3062void cleanup_socket_xprt(void) 3011void cleanup_socket_xprt(void)
3063{ 3012{
3064#ifdef RPC_DEBUG 3013#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
3065 if (sunrpc_table_header) { 3014 if (sunrpc_table_header) {
3066 unregister_sysctl_table(sunrpc_table_header); 3015 unregister_sysctl_table(sunrpc_table_header);
3067 sunrpc_table_header = NULL; 3016 sunrpc_table_header = NULL;