diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 18:13:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 18:13:13 -0500 |
commit | e20db597b6264de55ea6636fc79b1e4aaa89d129 (patch) | |
tree | fa650cb9cfad4b22598ae9867ca92baf57491a9d /net | |
parent | 3a5dc1fafb016560315fe45bb4ef8bde259dd1bc (diff) | |
parent | 388f0c776781fe64ce951701bfe712b2182a31f2 (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')
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 | |||
35 | config SUNRPC_DEBUG | 35 | config 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 |
17 | sunrpc-$(CONFIG_SUNRPC_DEBUG) += debugfs.o | ||
17 | sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o | 18 | sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o |
18 | sunrpc-$(CONFIG_PROC_FS) += stats.o | 19 | sunrpc-$(CONFIG_PROC_FS) += stats.o |
19 | sunrpc-$(CONFIG_SYSCTL) += sysctl.o | 20 | sunrpc-$(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 |
67 | static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO; | 67 | static 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: | |||
331 | out: | 335 | out: |
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 | } |
1397 | EXPORT_SYMBOL_GPL(rpc_restart_call); | 1404 | EXPORT_SYMBOL_GPL(rpc_restart_call); |
1398 | 1405 | ||
1399 | #ifdef RPC_DEBUG | 1406 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
1400 | static const char *rpc_proc_name(const struct rpc_task *task) | 1407 | const 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 | } |
2422 | EXPORT_SYMBOL_GPL(rpc_call_null); | 2430 | EXPORT_SYMBOL_GPL(rpc_call_null); |
2423 | 2431 | ||
2424 | #ifdef RPC_DEBUG | 2432 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
2425 | static void rpc_show_header(void) | 2433 | static 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 | |||
12 | static struct dentry *topdir; | ||
13 | static struct dentry *rpc_clnt_dir; | ||
14 | static struct dentry *rpc_xprt_dir; | ||
15 | |||
16 | struct rpc_clnt_iter { | ||
17 | struct rpc_clnt *clnt; | ||
18 | loff_t pos; | ||
19 | }; | ||
20 | |||
21 | static int | ||
22 | tasks_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 | |||
43 | static void * | ||
44 | tasks_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 | |||
60 | static void * | ||
61 | tasks_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 | |||
77 | static void | ||
78 | tasks_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 | |||
87 | static 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 | |||
94 | static 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 | |||
114 | static int | ||
115 | tasks_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 | |||
124 | static 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 | |||
132 | int | ||
133 | rpc_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; | ||
170 | out_err: | ||
171 | debugfs_remove_recursive(clnt->cl_debugfs); | ||
172 | clnt->cl_debugfs = NULL; | ||
173 | return err; | ||
174 | } | ||
175 | |||
176 | void | ||
177 | rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt) | ||
178 | { | ||
179 | debugfs_remove_recursive(clnt->cl_debugfs); | ||
180 | clnt->cl_debugfs = NULL; | ||
181 | } | ||
182 | |||
183 | static int | ||
184 | xprt_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 | |||
195 | static int | ||
196 | xprt_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 | |||
212 | static int | ||
213 | xprt_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 | |||
221 | static 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 | |||
229 | int | ||
230 | rpc_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 | |||
258 | void | ||
259 | rpc_xprt_debugfs_unregister(struct rpc_xprt *xprt) | ||
260 | { | ||
261 | debugfs_remove_recursive(xprt->debugfs); | ||
262 | xprt->debugfs = NULL; | ||
263 | } | ||
264 | |||
265 | void __exit | ||
266 | sunrpc_debugfs_exit(void) | ||
267 | { | ||
268 | debugfs_remove_recursive(topdir); | ||
269 | } | ||
270 | |||
271 | int __init | ||
272 | sunrpc_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; | ||
287 | out_remove: | ||
288 | debugfs_remove_recursive(topdir); | ||
289 | topdir = NULL; | ||
290 | out: | ||
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) |
262 | static void rpc_task_set_debuginfo(struct rpc_task *task) | 262 | static 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 | */ |
117 | struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) | 117 | struct 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 | } |
121 | EXPORT_SYMBOL_GPL(rpc_alloc_iostats); | 129 | EXPORT_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 | */ |
141 | void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats) | 147 | void 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 | } |
167 | EXPORT_SYMBOL_GPL(rpc_count_iostats); | 178 | EXPORT_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 | ||
112 | out5: | ||
113 | unregister_rpc_pipefs(); | ||
107 | out4: | 114 | out4: |
108 | unregister_pernet_subsys(&sunrpc_net_ops); | 115 | unregister_pernet_subsys(&sunrpc_net_ops); |
109 | out3: | 116 | out3: |
@@ -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 | ||
33 | static void svc_unregister(const struct svc_serv *serv, struct net *net); | 35 | static 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) |
1044 | static __printf(2, 3) | 1046 | static __printf(2, 3) |
1045 | void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) | 1047 | void 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 | } |
1334 | out_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; |
801 | out: | 808 | out_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; | 811 | out: |
812 | trace_svc_recv(rqstp, err); | ||
813 | return err; | ||
805 | } | 814 | } |
806 | EXPORT_SYMBOL_GPL(svc_recv); | 815 | EXPORT_SYMBOL_GPL(svc_recv); |
807 | 816 | ||
@@ -821,12 +830,12 @@ EXPORT_SYMBOL_GPL(svc_drop); | |||
821 | int svc_send(struct svc_rqst *rqstp) | 830 | int 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; |
862 | out: | ||
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); | |||
37 | unsigned int nlm_debug; | 37 | unsigned int nlm_debug; |
38 | EXPORT_SYMBOL_GPL(nlm_debug); | 38 | EXPORT_SYMBOL_GPL(nlm_debug); |
39 | 39 | ||
40 | #ifdef RPC_DEBUG | 40 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
41 | 41 | ||
42 | static struct ctl_table_header *sunrpc_table_header; | 42 | static struct ctl_table_header *sunrpc_table_header; |
43 | static struct ctl_table sunrpc_table[]; | 43 | static 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 | */ |
1297 | struct rpc_xprt *xprt_create_transport(struct xprt_create *args) | 1304 | struct 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); |
1341 | out: | 1355 | out: |
@@ -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) |
57 | static const char transfertypes[][12] = { | 57 | static 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; | |||
73 | static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE; | 73 | static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE; |
74 | static unsigned int xprt_rdma_inline_write_padding; | 74 | static unsigned int xprt_rdma_inline_write_padding; |
75 | static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR; | 75 | static 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 | ||
80 | static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE; | 80 | static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE; |
81 | static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE; | 81 | static 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 | ||
64 | static void rpcrdma_reset_frmrs(struct rpcrdma_ia *); | 64 | static void rpcrdma_reset_frmrs(struct rpcrdma_ia *); |
65 | static 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 | ||
106 | static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL); | 107 | static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL); |
107 | 108 | ||
109 | static 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 | |||
135 | static void | ||
136 | rpcrdma_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 | |||
108 | static void | 146 | static void |
109 | rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context) | 147 | rpcrdma_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 | ||
263 | out_schedule: | 302 | out_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) | |||
309 | static void | 345 | static void |
310 | rpcrdma_flush_cqs(struct rpcrdma_ep *ep) | 346 | rpcrdma_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) |
317 | static const char * const conn[] = { | 360 | static 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 | */ | ||
1351 | static void | ||
1352 | rpcrdma_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 | ||
80 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; | 80 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; |
81 | static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; | 81 | static 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 | ||
219 | struct 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 | |||
278 | static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) | 219 | static 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); |
1475 | out: | 1423 | out: |
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 | */ |
3043 | int init_socket_xprt(void) | 2992 | int 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 | */ |
3062 | void cleanup_socket_xprt(void) | 3011 | void 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; |