linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/27] NFSD operation monitoring tracepoints
@ 2020-09-21 18:10 Chuck Lever
  2020-09-21 18:10 ` [PATCH v2 01/27] NFS: Move generic FS show macros to global header Chuck Lever
                   ` (27 more replies)
  0 siblings, 28 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:10 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Hi-

As I've been working on various server bugs, I've been adding
tracepoints that record NFS operation arguments. Here's an updated
snapshot of this work for your review and comment.

The idea here is to provide a degree of NFS traffic observability
without needing network capture. Tracepoints are generally lighter-
weight than full network capture, allowing effective capture-time
data reduction:

- One or a handful of these can be enabled at a time
- Each tracepoint records much less data per operation than capture
- Extra capture-time filtering can reduce data amount even further
- Some of these operations are infrequent enough that their
 tracepoint could be enabled persistently without a significant
 performance impact (for example, for security auditing)

The topic branch has been updated as well:

git://git.linux-nfs.org/projects/cel/cel-2.6.git nfsd-more-tracepoints


Changes since RFC:
* s/SPDK/SPDX and corrected the spelling of Christoph's surname
* Fixed a build error noticed by <lkp@intel.com>
* Introduced generic headers for VFS and NFS protocol display macros
* nfsd4_compoundstatus now displays NFS4ERR codes symbolically
* The svc_process tracepoint now displays the RPC procedure symbolically
* NFSD dispatcher now displays procedure names and status codes symbolically
* fh_verify tracepoint tentatively included; it adds a lot of noise, but perhaps not much value
* Cleaned up the remaining PROC() macros in the server code
* Removed trace_printk's that were introduced during the RFC series
* Removed redundant nfsd4_close tracepoint

---

Chuck Lever (27):
      NFS: Move generic FS show macros to global header
      NFS: Move NFS protocol display macros to global header
      NFSD: Add SPDX header for fs/nfsd/trace.c
      SUNRPC: Move the svc_xdr_recvfrom() tracepoint
      SUNRPC: Add svc_xdr_authenticate tracepoint
      lockd: Replace PROC() macro with open code
      NFSACL: Replace PROC() macro with open code
      SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
      NFSD: Clean up the show_nf_may macro
      NFSD: Remove extra "0x" in tracepoint format specifier
      NFSD: Constify @fh argument of knfsd_fh_hash()
      NFSD: Add tracepoint in nfsd_setattr()
      NFSD: Add tracepoint for nfsd_access()
      NFSD: nfsd_compound_status tracepoint should record XID
      NFSD: Add client ID lifetime tracepoints
      NFSD: Add tracepoints to report NFSv4 session state
      NFSD: Add a tracepoint to report the current filehandle
      NFSD: Add GETATTR tracepoint
      NFSD: Add tracepoint in nfsd4_stateid_preprocess()
      NFSD: Add tracepoint to report arguments to NFSv4 OPEN
      NFSD: Add a tracepoint for DELEGRETURN
      NFSD: Add a lookup tracepoint
      NFSD: Add lock and locku tracepoints
      NFSD: Add tracepoints to record the result of TEST_STATEID and FREE_STATEID
      NFSD: Rename nfsd_ tracepoints to nfsd4_
      NFSD: Add tracepoints in the NFS dispatcher
      NFSD: Replace dprintk callsites in fs/nfsd/nfsfh.c


 fs/lockd/svc4proc.c           | 263 +++++++++--
 fs/lockd/svcproc.c            | 265 +++++++++--
 fs/nfs/callback_xdr.c         |   2 +
 fs/nfs/nfs4trace.h            | 387 ++--------------
 fs/nfs/nfstrace.h             | 113 +----
 fs/nfs/pnfs.h                 |   4 -
 fs/nfsd/nfs2acl.c             |  79 +++-
 fs/nfsd/nfs3acl.c             |  54 ++-
 fs/nfsd/nfs3proc.c            |  25 +
 fs/nfsd/nfs4callback.c        |  28 +-
 fs/nfsd/nfs4layouts.c         |  16 +-
 fs/nfsd/nfs4proc.c            |  43 +-
 fs/nfsd/nfs4state.c           | 100 ++--
 fs/nfsd/nfsd.h                |   1 +
 fs/nfsd/nfsfh.c               |  36 +-
 fs/nfsd/nfsfh.h               |   7 +-
 fs/nfsd/nfsproc.c             |  21 +
 fs/nfsd/nfssvc.c              | 198 +++++---
 fs/nfsd/trace.c               |   1 +
 fs/nfsd/trace.h               | 844 ++++++++++++++++++++++++++++++----
 fs/nfsd/vfs.c                 |  18 +-
 fs/nfsd/xdr4.h                |   3 +-
 include/linux/nfs4.h          |   4 +
 include/linux/sunrpc/svc.h    |   1 +
 include/trace/events/fs.h     |  30 ++
 include/trace/events/nfs.h    | 511 ++++++++++++++++++++
 include/trace/events/sunrpc.h |  33 +-
 include/uapi/linux/nfsacl.h   |   2 +
 net/sunrpc/svc_xprt.c         |   4 +-
 net/sunrpc/svcauth.c          |   5 +-
 30 files changed, 2187 insertions(+), 911 deletions(-)
 create mode 100644 include/trace/events/nfs.h

--
Chuck Lever


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

* [PATCH v2 01/27] NFS: Move generic FS show macros to global header
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
@ 2020-09-21 18:10 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 02/27] NFS: Move NFS protocol display " Chuck Lever
                   ` (26 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:10 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Refactor: surface useful show_ macros to other trace consumers.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfs/nfs4trace.h        |   59 +++++-------------
 fs/nfs/nfstrace.h         |  122 ++++---------------------------------
 include/trace/events/fs.h |  147 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 175 insertions(+), 153 deletions(-)
 create mode 100644 include/trace/events/fs.h

diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h
index b4f852d4d099..502b13651c94 100644
--- a/fs/nfs/nfs4trace.h
+++ b/fs/nfs/nfs4trace.h
@@ -10,6 +10,8 @@
 
 #include <linux/tracepoint.h>
 
+#include <trace/events/fs.h>
+
 TRACE_DEFINE_ENUM(EPERM);
 TRACE_DEFINE_ENUM(ENOENT);
 TRACE_DEFINE_ENUM(EIO);
@@ -313,19 +315,6 @@ TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS);
 		{ NFS4ERR_RESET_TO_MDS, "RESET_TO_MDS" }, \
 		{ NFS4ERR_RESET_TO_PNFS, "RESET_TO_PNFS" })
 
-#define show_open_flags(flags) \
-	__print_flags(flags, "|", \
-		{ O_CREAT, "O_CREAT" }, \
-		{ O_EXCL, "O_EXCL" }, \
-		{ O_TRUNC, "O_TRUNC" }, \
-		{ O_DIRECT, "O_DIRECT" })
-
-#define show_fmode_flags(mode) \
-	__print_flags(mode, "|", \
-		{ ((__force unsigned long)FMODE_READ), "READ" }, \
-		{ ((__force unsigned long)FMODE_WRITE), "WRITE" }, \
-		{ ((__force unsigned long)FMODE_EXEC), "EXEC" })
-
 #define show_nfs_fattr_flags(valid) \
 	__print_flags((unsigned long)valid, "|", \
 		{ NFS_ATTR_FATTR_TYPE, "TYPE" }, \
@@ -748,8 +737,8 @@ DECLARE_EVENT_CLASS(nfs4_open_event,
 
 		TP_STRUCT__entry(
 			__field(unsigned long, error)
-			__field(unsigned int, flags)
-			__field(unsigned int, fmode)
+			__field(unsigned long, flags)
+			__field(unsigned long, fmode)
 			__field(dev_t, dev)
 			__field(u32, fhandle)
 			__field(u64, fileid)
@@ -767,7 +756,7 @@ DECLARE_EVENT_CLASS(nfs4_open_event,
 
 			__entry->error = -error;
 			__entry->flags = flags;
-			__entry->fmode = (__force unsigned int)ctx->mode;
+			__entry->fmode = (__force unsigned long)ctx->mode;
 			__entry->dev = ctx->dentry->d_sb->s_dev;
 			if (!IS_ERR_OR_NULL(state)) {
 				inode = state->inode;
@@ -797,14 +786,14 @@ DECLARE_EVENT_CLASS(nfs4_open_event,
 		),
 
 		TP_printk(
-			"error=%ld (%s) flags=%d (%s) fmode=%s "
+			"error=%ld (%s) flags=%lu (%s) fmode=%s "
 			"fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"name=%02x:%02x:%llu/%s stateid=%d:0x%08x "
 			"openstateid=%d:0x%08x",
 			 -__entry->error,
 			 show_nfsv4_errors(__entry->error),
 			 __entry->flags,
-			 show_open_flags(__entry->flags),
+			 show_fcntl_open_flags(__entry->flags),
 			 show_fmode_flags(__entry->fmode),
 			 MAJOR(__entry->dev), MINOR(__entry->dev),
 			 (unsigned long long)__entry->fileid,
@@ -916,24 +905,6 @@ TRACE_EVENT(nfs4_close,
 		)
 );
 
-TRACE_DEFINE_ENUM(F_GETLK);
-TRACE_DEFINE_ENUM(F_SETLK);
-TRACE_DEFINE_ENUM(F_SETLKW);
-TRACE_DEFINE_ENUM(F_RDLCK);
-TRACE_DEFINE_ENUM(F_WRLCK);
-TRACE_DEFINE_ENUM(F_UNLCK);
-
-#define show_lock_cmd(type) \
-	__print_symbolic((int)type, \
-		{ F_GETLK, "GETLK" }, \
-		{ F_SETLK, "SETLK" }, \
-		{ F_SETLKW, "SETLKW" })
-#define show_lock_type(type) \
-	__print_symbolic((int)type, \
-		{ F_RDLCK, "RDLCK" }, \
-		{ F_WRLCK, "WRLCK" }, \
-		{ F_UNLCK, "UNLCK" })
-
 DECLARE_EVENT_CLASS(nfs4_lock_event,
 		TP_PROTO(
 			const struct file_lock *request,
@@ -946,8 +917,8 @@ DECLARE_EVENT_CLASS(nfs4_lock_event,
 
 		TP_STRUCT__entry(
 			__field(unsigned long, error)
-			__field(int, cmd)
-			__field(char, type)
+			__field(unsigned long, cmd)
+			__field(unsigned long, type)
 			__field(loff_t, start)
 			__field(loff_t, end)
 			__field(dev_t, dev)
@@ -980,8 +951,8 @@ DECLARE_EVENT_CLASS(nfs4_lock_event,
 			"stateid=%d:0x%08x",
 			-__entry->error,
 			show_nfsv4_errors(__entry->error),
-			show_lock_cmd(__entry->cmd),
-			show_lock_type(__entry->type),
+			show_fcntl_cmd(__entry->cmd),
+			show_fcntl_lock_type(__entry->type),
 			(long long)__entry->start,
 			(long long)__entry->end,
 			MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -1016,8 +987,8 @@ TRACE_EVENT(nfs4_set_lock,
 
 		TP_STRUCT__entry(
 			__field(unsigned long, error)
-			__field(int, cmd)
-			__field(char, type)
+			__field(unsigned long, cmd)
+			__field(unsigned long, type)
 			__field(loff_t, start)
 			__field(loff_t, end)
 			__field(dev_t, dev)
@@ -1056,8 +1027,8 @@ TRACE_EVENT(nfs4_set_lock,
 			"stateid=%d:0x%08x lockstateid=%d:0x%08x",
 			-__entry->error,
 			show_nfsv4_errors(__entry->error),
-			show_lock_cmd(__entry->cmd),
-			show_lock_type(__entry->type),
+			show_fcntl_cmd(__entry->cmd),
+			show_fcntl_lock_type(__entry->type),
 			(long long)__entry->start,
 			(long long)__entry->end,
 			MAJOR(__entry->dev), MINOR(__entry->dev),
diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h
index 5a59dcdce0b2..91677dea7e3d 100644
--- a/fs/nfs/nfstrace.h
+++ b/fs/nfs/nfstrace.h
@@ -11,27 +11,7 @@
 #include <linux/tracepoint.h>
 #include <linux/iversion.h>
 
-TRACE_DEFINE_ENUM(DT_UNKNOWN);
-TRACE_DEFINE_ENUM(DT_FIFO);
-TRACE_DEFINE_ENUM(DT_CHR);
-TRACE_DEFINE_ENUM(DT_DIR);
-TRACE_DEFINE_ENUM(DT_BLK);
-TRACE_DEFINE_ENUM(DT_REG);
-TRACE_DEFINE_ENUM(DT_LNK);
-TRACE_DEFINE_ENUM(DT_SOCK);
-TRACE_DEFINE_ENUM(DT_WHT);
-
-#define nfs_show_file_type(ftype) \
-	__print_symbolic(ftype, \
-			{ DT_UNKNOWN, "UNKNOWN" }, \
-			{ DT_FIFO, "FIFO" }, \
-			{ DT_CHR, "CHR" }, \
-			{ DT_DIR, "DIR" }, \
-			{ DT_BLK, "BLK" }, \
-			{ DT_REG, "REG" }, \
-			{ DT_LNK, "LNK" }, \
-			{ DT_SOCK, "SOCK" }, \
-			{ DT_WHT, "WHT" })
+#include <trace/events/fs.h>
 
 TRACE_DEFINE_ENUM(NFS_INO_INVALID_DATA);
 TRACE_DEFINE_ENUM(NFS_INO_INVALID_ATIME);
@@ -159,7 +139,7 @@ DECLARE_EVENT_CLASS(nfs_inode_event_done,
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
 			__entry->type,
-			nfs_show_file_type(__entry->type),
+			show_dirent_type(__entry->type),
 			(unsigned long long)__entry->version,
 			(long long)__entry->size,
 			__entry->cache_validity,
@@ -250,7 +230,7 @@ TRACE_EVENT(nfs_access_exit,
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
 			__entry->type,
-			nfs_show_file_type(__entry->type),
+			show_dirent_type(__entry->type),
 			(unsigned long long)__entry->version,
 			(long long)__entry->size,
 			__entry->cache_validity,
@@ -261,38 +241,6 @@ TRACE_EVENT(nfs_access_exit,
 		)
 );
 
-TRACE_DEFINE_ENUM(LOOKUP_FOLLOW);
-TRACE_DEFINE_ENUM(LOOKUP_DIRECTORY);
-TRACE_DEFINE_ENUM(LOOKUP_AUTOMOUNT);
-TRACE_DEFINE_ENUM(LOOKUP_PARENT);
-TRACE_DEFINE_ENUM(LOOKUP_REVAL);
-TRACE_DEFINE_ENUM(LOOKUP_RCU);
-TRACE_DEFINE_ENUM(LOOKUP_OPEN);
-TRACE_DEFINE_ENUM(LOOKUP_CREATE);
-TRACE_DEFINE_ENUM(LOOKUP_EXCL);
-TRACE_DEFINE_ENUM(LOOKUP_RENAME_TARGET);
-TRACE_DEFINE_ENUM(LOOKUP_JUMPED);
-TRACE_DEFINE_ENUM(LOOKUP_ROOT);
-TRACE_DEFINE_ENUM(LOOKUP_EMPTY);
-TRACE_DEFINE_ENUM(LOOKUP_DOWN);
-
-#define show_lookup_flags(flags) \
-	__print_flags(flags, "|", \
-			{ LOOKUP_FOLLOW, "FOLLOW" }, \
-			{ LOOKUP_DIRECTORY, "DIRECTORY" }, \
-			{ LOOKUP_AUTOMOUNT, "AUTOMOUNT" }, \
-			{ LOOKUP_PARENT, "PARENT" }, \
-			{ LOOKUP_REVAL, "REVAL" }, \
-			{ LOOKUP_RCU, "RCU" }, \
-			{ LOOKUP_OPEN, "OPEN" }, \
-			{ LOOKUP_CREATE, "CREATE" }, \
-			{ LOOKUP_EXCL, "EXCL" }, \
-			{ LOOKUP_RENAME_TARGET, "RENAME_TARGET" }, \
-			{ LOOKUP_JUMPED, "JUMPED" }, \
-			{ LOOKUP_ROOT, "ROOT" }, \
-			{ LOOKUP_EMPTY, "EMPTY" }, \
-			{ LOOKUP_DOWN, "DOWN" })
-
 DECLARE_EVENT_CLASS(nfs_lookup_event,
 		TP_PROTO(
 			const struct inode *dir,
@@ -319,7 +267,7 @@ DECLARE_EVENT_CLASS(nfs_lookup_event,
 		TP_printk(
 			"flags=0x%lx (%s) name=%02x:%02x:%llu/%s",
 			__entry->flags,
-			show_lookup_flags(__entry->flags),
+			show_vfs_lookup_flags(__entry->flags),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->dir,
 			__get_str(name)
@@ -365,7 +313,7 @@ DECLARE_EVENT_CLASS(nfs_lookup_event_done,
 			"error=%ld (%s) flags=0x%lx (%s) name=%02x:%02x:%llu/%s",
 			-__entry->error, nfs_show_status(__entry->error),
 			__entry->flags,
-			show_lookup_flags(__entry->flags),
+			show_vfs_lookup_flags(__entry->flags),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->dir,
 			__get_str(name)
@@ -387,50 +335,6 @@ DEFINE_NFS_LOOKUP_EVENT_DONE(nfs_lookup_exit);
 DEFINE_NFS_LOOKUP_EVENT(nfs_lookup_revalidate_enter);
 DEFINE_NFS_LOOKUP_EVENT_DONE(nfs_lookup_revalidate_exit);
 
-TRACE_DEFINE_ENUM(O_WRONLY);
-TRACE_DEFINE_ENUM(O_RDWR);
-TRACE_DEFINE_ENUM(O_CREAT);
-TRACE_DEFINE_ENUM(O_EXCL);
-TRACE_DEFINE_ENUM(O_NOCTTY);
-TRACE_DEFINE_ENUM(O_TRUNC);
-TRACE_DEFINE_ENUM(O_APPEND);
-TRACE_DEFINE_ENUM(O_NONBLOCK);
-TRACE_DEFINE_ENUM(O_DSYNC);
-TRACE_DEFINE_ENUM(O_DIRECT);
-TRACE_DEFINE_ENUM(O_LARGEFILE);
-TRACE_DEFINE_ENUM(O_DIRECTORY);
-TRACE_DEFINE_ENUM(O_NOFOLLOW);
-TRACE_DEFINE_ENUM(O_NOATIME);
-TRACE_DEFINE_ENUM(O_CLOEXEC);
-
-#define show_open_flags(flags) \
-	__print_flags(flags, "|", \
-		{ O_WRONLY, "O_WRONLY" }, \
-		{ O_RDWR, "O_RDWR" }, \
-		{ O_CREAT, "O_CREAT" }, \
-		{ O_EXCL, "O_EXCL" }, \
-		{ O_NOCTTY, "O_NOCTTY" }, \
-		{ O_TRUNC, "O_TRUNC" }, \
-		{ O_APPEND, "O_APPEND" }, \
-		{ O_NONBLOCK, "O_NONBLOCK" }, \
-		{ O_DSYNC, "O_DSYNC" }, \
-		{ O_DIRECT, "O_DIRECT" }, \
-		{ O_LARGEFILE, "O_LARGEFILE" }, \
-		{ O_DIRECTORY, "O_DIRECTORY" }, \
-		{ O_NOFOLLOW, "O_NOFOLLOW" }, \
-		{ O_NOATIME, "O_NOATIME" }, \
-		{ O_CLOEXEC, "O_CLOEXEC" })
-
-TRACE_DEFINE_ENUM(FMODE_READ);
-TRACE_DEFINE_ENUM(FMODE_WRITE);
-TRACE_DEFINE_ENUM(FMODE_EXEC);
-
-#define show_fmode_flags(mode) \
-	__print_flags(mode, "|", \
-		{ ((__force unsigned long)FMODE_READ), "READ" }, \
-		{ ((__force unsigned long)FMODE_WRITE), "WRITE" }, \
-		{ ((__force unsigned long)FMODE_EXEC), "EXEC" })
-
 TRACE_EVENT(nfs_atomic_open_enter,
 		TP_PROTO(
 			const struct inode *dir,
@@ -442,7 +346,7 @@ TRACE_EVENT(nfs_atomic_open_enter,
 
 		TP_STRUCT__entry(
 			__field(unsigned long, flags)
-			__field(unsigned int, fmode)
+			__field(unsigned long, fmode)
 			__field(dev_t, dev)
 			__field(u64, dir)
 			__string(name, ctx->dentry->d_name.name)
@@ -452,14 +356,14 @@ TRACE_EVENT(nfs_atomic_open_enter,
 			__entry->dev = dir->i_sb->s_dev;
 			__entry->dir = NFS_FILEID(dir);
 			__entry->flags = flags;
-			__entry->fmode = (__force unsigned int)ctx->mode;
+			__entry->fmode = (__force unsigned long)ctx->mode;
 			__assign_str(name, ctx->dentry->d_name.name);
 		),
 
 		TP_printk(
 			"flags=0x%lx (%s) fmode=%s name=%02x:%02x:%llu/%s",
 			__entry->flags,
-			show_open_flags(__entry->flags),
+			show_fcntl_open_flags(__entry->flags),
 			show_fmode_flags(__entry->fmode),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->dir,
@@ -480,7 +384,7 @@ TRACE_EVENT(nfs_atomic_open_exit,
 		TP_STRUCT__entry(
 			__field(unsigned long, error)
 			__field(unsigned long, flags)
-			__field(unsigned int, fmode)
+			__field(unsigned long, fmode)
 			__field(dev_t, dev)
 			__field(u64, dir)
 			__string(name, ctx->dentry->d_name.name)
@@ -491,7 +395,7 @@ TRACE_EVENT(nfs_atomic_open_exit,
 			__entry->dev = dir->i_sb->s_dev;
 			__entry->dir = NFS_FILEID(dir);
 			__entry->flags = flags;
-			__entry->fmode = (__force unsigned int)ctx->mode;
+			__entry->fmode = (__force unsigned long)ctx->mode;
 			__assign_str(name, ctx->dentry->d_name.name);
 		),
 
@@ -500,7 +404,7 @@ TRACE_EVENT(nfs_atomic_open_exit,
 			"name=%02x:%02x:%llu/%s",
 			-__entry->error, nfs_show_status(__entry->error),
 			__entry->flags,
-			show_open_flags(__entry->flags),
+			show_fcntl_open_flags(__entry->flags),
 			show_fmode_flags(__entry->fmode),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->dir,
@@ -534,7 +438,7 @@ TRACE_EVENT(nfs_create_enter,
 		TP_printk(
 			"flags=0x%lx (%s) name=%02x:%02x:%llu/%s",
 			__entry->flags,
-			show_open_flags(__entry->flags),
+			show_fcntl_open_flags(__entry->flags),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->dir,
 			__get_str(name)
@@ -571,7 +475,7 @@ TRACE_EVENT(nfs_create_exit,
 			"error=%ld (%s) flags=0x%lx (%s) name=%02x:%02x:%llu/%s",
 			-__entry->error, nfs_show_status(__entry->error),
 			__entry->flags,
-			show_open_flags(__entry->flags),
+			show_fcntl_open_flags(__entry->flags),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->dir,
 			__get_str(name)
diff --git a/include/trace/events/fs.h b/include/trace/events/fs.h
new file mode 100644
index 000000000000..8ea0e84e425a
--- /dev/null
+++ b/include/trace/events/fs.h
@@ -0,0 +1,147 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Display helpers for generic filesystem items
+ *
+ * Author: Chuck Lever <chuck.lever@oracle.com>
+ *
+ * Copyright (c) 2020, Oracle and/or its affiliates.
+ */
+
+#include <linux/fs.h>
+
+#define show_dirent_type(x) \
+	__print_symbolic(x, \
+		{ DT_UNKNOWN,		"UNKNOWN" }, \
+		{ DT_FIFO,		"FIFO" }, \
+		{ DT_CHR,		"CHR" }, \
+		{ DT_DIR,		"DIR" }, \
+		{ DT_BLK,		"BLK" }, \
+		{ DT_REG,		"REG" }, \
+		{ DT_LNK,		"LNK" }, \
+		{ DT_SOCK,		"SOCK" }, \
+		{ DT_WHT,		"WHT" })
+
+#define show_fcntl_open_flags(x) \
+	__print_flags(x, "|", \
+		{ O_WRONLY,		"O_WRONLY" }, \
+		{ O_RDWR,		"O_RDWR" }, \
+		{ O_CREAT,		"O_CREAT" }, \
+		{ O_EXCL,		"O_EXCL" }, \
+		{ O_NOCTTY,		"O_NOCTTY" }, \
+		{ O_TRUNC,		"O_TRUNC" }, \
+		{ O_APPEND,		"O_APPEND" }, \
+		{ O_NONBLOCK,		"O_NONBLOCK" }, \
+		{ O_DSYNC,		"O_DSYNC" }, \
+		{ O_DIRECT,		"O_DIRECT" }, \
+		{ O_LARGEFILE,		"O_LARGEFILE" }, \
+		{ O_DIRECTORY,		"O_DIRECTORY" }, \
+		{ O_NOFOLLOW,		"O_NOFOLLOW" }, \
+		{ O_NOATIME,		"O_NOATIME" }, \
+		{ O_CLOEXEC,		"O_CLOEXEC" })
+
+#define show_fmode_flags(x) \
+	__print_flags(x, "|", \
+		{ (__force unsigned long)FMODE_READ,		"READ" }, \
+		{ (__force unsigned long)FMODE_WRITE,		"WRITE" }, \
+		{ (__force unsigned long)FMODE_LSEEK,		"LSEEK" }, \
+		{ (__force unsigned long)FMODE_PREAD,		"PREAD" }, \
+		{ (__force unsigned long)FMODE_PWRITE,		"PWRITE" }, \
+		{ (__force unsigned long)FMODE_EXEC,		"EXEC" }, \
+		{ (__force unsigned long)FMODE_NDELAY,		"NDELAY" }, \
+		{ (__force unsigned long)FMODE_EXCL,		"EXCL" }, \
+		{ (__force unsigned long)FMODE_WRITE_IOCTL,	"WRITE_IOCTL" }, \
+		{ (__force unsigned long)FMODE_32BITHASH,	"32BITHASH" }, \
+		{ (__force unsigned long)FMODE_64BITHASH,	"64BITHASH" }, \
+		{ (__force unsigned long)FMODE_NOCMTIME, 	"NOCMTIME" }, \
+		{ (__force unsigned long)FMODE_RANDOM,		"RANDOM" }, \
+		{ (__force unsigned long)FMODE_UNSIGNED_OFFSET,	"UNSIGNED_OFFSET" }, \
+		{ (__force unsigned long)FMODE_PATH,		"PATH" }, \
+		{ (__force unsigned long)FMODE_ATOMIC_POS,	"ATOMIC_POS" }, \
+		{ (__force unsigned long)FMODE_WRITER,		"WRITER" }, \
+		{ (__force unsigned long)FMODE_CAN_READ,	"CAN_READ" }, \
+		{ (__force unsigned long)FMODE_CAN_WRITE,	"CAN_WRITE" }, \
+		{ (__force unsigned long)FMODE_OPENED,		"OPENED" }, \
+		{ (__force unsigned long)FMODE_CREATED,		"CREATED" }, \
+		{ (__force unsigned long)FMODE_STREAM,		"STREAM" }, \
+		{ (__force unsigned long)FMODE_NONOTIFY,	"NONOTIFY" }, \
+		{ (__force unsigned long)FMODE_NOWAIT,		"NOWAIT" }, \
+		{ (__force unsigned long)FMODE_NEED_UNMOUNT,	"NEED_UNMOUNT" }, \
+		{ (__force unsigned long)FMODE_NOACCOUNT,	"NOACCOUNT" }, \
+		{ (__force unsigned long)FMODE_BUF_RASYNC,	"BUF_RASYNC" })
+
+#ifdef CONFIG_64BIT
+#define show_fcntl_cmd(x) \
+	__print_symbolic(x, \
+		{ F_DUPFD,		"DUPFD" }, \
+		{ F_GETFD,		"GETFD" }, \
+		{ F_SETFD,		"SETFD" }, \
+		{ F_GETFL,		"GETFL" }, \
+		{ F_SETFL,		"SETFL" }, \
+		{ F_GETLK,		"GETLK" }, \
+		{ F_SETLK,		"SETLK" }, \
+		{ F_SETLKW,		"SETLKW" }, \
+		{ F_SETOWN,		"SETOWN" }, \
+		{ F_GETOWN,		"GETOWN" }, \
+		{ F_SETSIG,		"SETSIG" }, \
+		{ F_GETSIG,		"GETSIG" }, \
+		{ F_SETOWN_EX,		"SETOWN_EX" }, \
+		{ F_GETOWN_EX,		"GETOWN_EX" }, \
+		{ F_GETOWNER_UIDS,	"GETOWNER_UIDS" }, \
+		{ F_OFD_GETLK,		"OFD_GETLK" }, \
+		{ F_OFD_SETLK,		"OFD_SETLK" }, \
+		{ F_OFD_SETLKW,		"OFD_SETLKW" })
+#else /* CONFIG_64BIT */
+#define show_fcntl_cmd(x) \
+	__print_symbolic(x, \
+		{ F_DUPFD,		"DUPFD" }, \
+		{ F_GETFD,		"GETFD" }, \
+		{ F_SETFD,		"SETFD" }, \
+		{ F_GETFL,		"GETFL" }, \
+		{ F_SETFL,		"SETFL" }, \
+		{ F_GETLK,		"GETLK" }, \
+		{ F_SETLK,		"SETLK" }, \
+		{ F_SETLKW,		"SETLKW" }, \
+		{ F_SETOWN,		"SETOWN" }, \
+		{ F_GETOWN,		"GETOWN" }, \
+		{ F_SETSIG,		"SETSIG" }, \
+		{ F_GETSIG,		"GETSIG" }, \
+		{ F_GETLK64,		"GETLK64" }, \
+		{ F_SETLK64,		"SETLK64" }, \
+		{ F_SETLKW64,		"SETLKW64" }, \
+		{ F_SETOWN_EX,		"SETOWN_EX" }, \
+		{ F_GETOWN_EX,		"GETOWN_EX" }, \
+		{ F_GETOWNER_UIDS,	"GETOWNER_UIDS" }, \
+		{ F_OFD_GETLK,		"OFD_GETLK" }, \
+		{ F_OFD_SETLK,		"OFD_SETLK" }, \
+		{ F_OFD_SETLKW,		"OFD_SETLKW" })
+#endif /* CONFIG_64BIT */
+
+#define show_fcntl_lock_type(x) \
+	__print_symbolic(x, \
+		{ F_RDLCK,		"RDLCK" }, \
+		{ F_WRLCK,		"WRLCK" }, \
+		{ F_UNLCK,		"UNLCK" })
+
+#define show_vfs_lookup_flags(flags) \
+	__print_flags(flags, "|", \
+		{ LOOKUP_FOLLOW,	"FOLLOW" }, \
+		{ LOOKUP_DIRECTORY,	"DIRECTORY" }, \
+		{ LOOKUP_AUTOMOUNT,	"AUTOMOUNT" }, \
+		{ LOOKUP_EMPTY,		"EMPTY" }, \
+		{ LOOKUP_DOWN,		"DOWN" }, \
+		{ LOOKUP_MOUNTPOINT,	"MOUNTPOINT" }, \
+		{ LOOKUP_REVAL,		"REVAL" }, \
+		{ LOOKUP_RCU,		"RCU" }, \
+		{ LOOKUP_OPEN,		"OPEN" }, \
+		{ LOOKUP_CREATE,	"CREATE" }, \
+		{ LOOKUP_EXCL,		"EXCL" }, \
+		{ LOOKUP_RENAME_TARGET,	"RENAME_TARGET" }, \
+		{ LOOKUP_PARENT,	"PARENT" }, \
+		{ LOOKUP_JUMPED,	"JUMPED" }, \
+		{ LOOKUP_ROOT,		"ROOT" }, \
+		{ LOOKUP_ROOT_GRABBED,	"ROOT_GRABBED" }, \
+		{ LOOKUP_NO_SYMLINKS,	"NO_SYMLINKS" }, \
+		{ LOOKUP_NO_MAGICLINKS,	"NO_MAGICLINKS" }, \
+		{ LOOKUP_NO_XDEV,	"NO_XDEV" }, \
+		{ LOOKUP_BENEATH,	"BENEATH" }, \
+		{ LOOKUP_IN_ROOT,	"IN_ROOT" })



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

* [PATCH v2 02/27] NFS: Move NFS protocol display macros to global header
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
  2020-09-21 18:10 ` [PATCH v2 01/27] NFS: Move generic FS show macros to global header Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 03/27] NFSD: Add SPDX header for fs/nfsd/trace.c Chuck Lever
                   ` (25 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Refactor: surface useful show_ macros so they can be shared between
the client and server trace code.

Additional clean up:
- Housekeeping: ensure the correct #include files are pulled in
  and add proper TRACE_DEFINE_ENUM where they are missing
- Use a consistent naming scheme for the helpers
- Store values to be displayed symbolically as unsigned long, as
  that is the type that the __print_yada() functions take

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfs/nfs4trace.h         |  387 ++++----------------------------------------
 fs/nfs/nfstrace.h          |  113 ++-----------
 fs/nfs/pnfs.h              |    4 
 fs/nfsd/trace.h            |    1 
 include/linux/nfs4.h       |    4 
 include/trace/events/nfs.h |  361 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 414 insertions(+), 456 deletions(-)
 create mode 100644 include/trace/events/nfs.h

diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h
index 502b13651c94..e5dfed490a1b 100644
--- a/fs/nfs/nfs4trace.h
+++ b/fs/nfs/nfs4trace.h
@@ -11,309 +11,7 @@
 #include <linux/tracepoint.h>
 
 #include <trace/events/fs.h>
-
-TRACE_DEFINE_ENUM(EPERM);
-TRACE_DEFINE_ENUM(ENOENT);
-TRACE_DEFINE_ENUM(EIO);
-TRACE_DEFINE_ENUM(ENXIO);
-TRACE_DEFINE_ENUM(EACCES);
-TRACE_DEFINE_ENUM(EEXIST);
-TRACE_DEFINE_ENUM(EXDEV);
-TRACE_DEFINE_ENUM(ENOTDIR);
-TRACE_DEFINE_ENUM(EISDIR);
-TRACE_DEFINE_ENUM(EFBIG);
-TRACE_DEFINE_ENUM(ENOSPC);
-TRACE_DEFINE_ENUM(EROFS);
-TRACE_DEFINE_ENUM(EMLINK);
-TRACE_DEFINE_ENUM(ENAMETOOLONG);
-TRACE_DEFINE_ENUM(ENOTEMPTY);
-TRACE_DEFINE_ENUM(EDQUOT);
-TRACE_DEFINE_ENUM(ESTALE);
-TRACE_DEFINE_ENUM(EBADHANDLE);
-TRACE_DEFINE_ENUM(EBADCOOKIE);
-TRACE_DEFINE_ENUM(ENOTSUPP);
-TRACE_DEFINE_ENUM(ETOOSMALL);
-TRACE_DEFINE_ENUM(EREMOTEIO);
-TRACE_DEFINE_ENUM(EBADTYPE);
-TRACE_DEFINE_ENUM(EAGAIN);
-TRACE_DEFINE_ENUM(ELOOP);
-TRACE_DEFINE_ENUM(EOPNOTSUPP);
-TRACE_DEFINE_ENUM(EDEADLK);
-TRACE_DEFINE_ENUM(ENOMEM);
-TRACE_DEFINE_ENUM(EKEYEXPIRED);
-TRACE_DEFINE_ENUM(ETIMEDOUT);
-TRACE_DEFINE_ENUM(ERESTARTSYS);
-TRACE_DEFINE_ENUM(ECONNREFUSED);
-TRACE_DEFINE_ENUM(ECONNRESET);
-TRACE_DEFINE_ENUM(ENETUNREACH);
-TRACE_DEFINE_ENUM(EHOSTUNREACH);
-TRACE_DEFINE_ENUM(EHOSTDOWN);
-TRACE_DEFINE_ENUM(EPIPE);
-TRACE_DEFINE_ENUM(EPFNOSUPPORT);
-TRACE_DEFINE_ENUM(EPROTONOSUPPORT);
-
-TRACE_DEFINE_ENUM(NFS4_OK);
-TRACE_DEFINE_ENUM(NFS4ERR_ACCESS);
-TRACE_DEFINE_ENUM(NFS4ERR_ATTRNOTSUPP);
-TRACE_DEFINE_ENUM(NFS4ERR_ADMIN_REVOKED);
-TRACE_DEFINE_ENUM(NFS4ERR_BACK_CHAN_BUSY);
-TRACE_DEFINE_ENUM(NFS4ERR_BADCHAR);
-TRACE_DEFINE_ENUM(NFS4ERR_BADHANDLE);
-TRACE_DEFINE_ENUM(NFS4ERR_BADIOMODE);
-TRACE_DEFINE_ENUM(NFS4ERR_BADLAYOUT);
-TRACE_DEFINE_ENUM(NFS4ERR_BADLABEL);
-TRACE_DEFINE_ENUM(NFS4ERR_BADNAME);
-TRACE_DEFINE_ENUM(NFS4ERR_BADOWNER);
-TRACE_DEFINE_ENUM(NFS4ERR_BADSESSION);
-TRACE_DEFINE_ENUM(NFS4ERR_BADSLOT);
-TRACE_DEFINE_ENUM(NFS4ERR_BADTYPE);
-TRACE_DEFINE_ENUM(NFS4ERR_BADXDR);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_COOKIE);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_HIGH_SLOT);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_RANGE);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_SEQID);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_SESSION_DIGEST);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_STATEID);
-TRACE_DEFINE_ENUM(NFS4ERR_CB_PATH_DOWN);
-TRACE_DEFINE_ENUM(NFS4ERR_CLID_INUSE);
-TRACE_DEFINE_ENUM(NFS4ERR_CLIENTID_BUSY);
-TRACE_DEFINE_ENUM(NFS4ERR_COMPLETE_ALREADY);
-TRACE_DEFINE_ENUM(NFS4ERR_CONN_NOT_BOUND_TO_SESSION);
-TRACE_DEFINE_ENUM(NFS4ERR_DEADLOCK);
-TRACE_DEFINE_ENUM(NFS4ERR_DEADSESSION);
-TRACE_DEFINE_ENUM(NFS4ERR_DELAY);
-TRACE_DEFINE_ENUM(NFS4ERR_DELEG_ALREADY_WANTED);
-TRACE_DEFINE_ENUM(NFS4ERR_DELEG_REVOKED);
-TRACE_DEFINE_ENUM(NFS4ERR_DENIED);
-TRACE_DEFINE_ENUM(NFS4ERR_DIRDELEG_UNAVAIL);
-TRACE_DEFINE_ENUM(NFS4ERR_DQUOT);
-TRACE_DEFINE_ENUM(NFS4ERR_ENCR_ALG_UNSUPP);
-TRACE_DEFINE_ENUM(NFS4ERR_EXIST);
-TRACE_DEFINE_ENUM(NFS4ERR_EXPIRED);
-TRACE_DEFINE_ENUM(NFS4ERR_FBIG);
-TRACE_DEFINE_ENUM(NFS4ERR_FHEXPIRED);
-TRACE_DEFINE_ENUM(NFS4ERR_FILE_OPEN);
-TRACE_DEFINE_ENUM(NFS4ERR_GRACE);
-TRACE_DEFINE_ENUM(NFS4ERR_HASH_ALG_UNSUPP);
-TRACE_DEFINE_ENUM(NFS4ERR_INVAL);
-TRACE_DEFINE_ENUM(NFS4ERR_IO);
-TRACE_DEFINE_ENUM(NFS4ERR_ISDIR);
-TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTTRYLATER);
-TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTUNAVAILABLE);
-TRACE_DEFINE_ENUM(NFS4ERR_LEASE_MOVED);
-TRACE_DEFINE_ENUM(NFS4ERR_LOCKED);
-TRACE_DEFINE_ENUM(NFS4ERR_LOCKS_HELD);
-TRACE_DEFINE_ENUM(NFS4ERR_LOCK_RANGE);
-TRACE_DEFINE_ENUM(NFS4ERR_MINOR_VERS_MISMATCH);
-TRACE_DEFINE_ENUM(NFS4ERR_MLINK);
-TRACE_DEFINE_ENUM(NFS4ERR_MOVED);
-TRACE_DEFINE_ENUM(NFS4ERR_NAMETOOLONG);
-TRACE_DEFINE_ENUM(NFS4ERR_NOENT);
-TRACE_DEFINE_ENUM(NFS4ERR_NOFILEHANDLE);
-TRACE_DEFINE_ENUM(NFS4ERR_NOMATCHING_LAYOUT);
-TRACE_DEFINE_ENUM(NFS4ERR_NOSPC);
-TRACE_DEFINE_ENUM(NFS4ERR_NOTDIR);
-TRACE_DEFINE_ENUM(NFS4ERR_NOTEMPTY);
-TRACE_DEFINE_ENUM(NFS4ERR_NOTSUPP);
-TRACE_DEFINE_ENUM(NFS4ERR_NOT_ONLY_OP);
-TRACE_DEFINE_ENUM(NFS4ERR_NOT_SAME);
-TRACE_DEFINE_ENUM(NFS4ERR_NO_GRACE);
-TRACE_DEFINE_ENUM(NFS4ERR_NXIO);
-TRACE_DEFINE_ENUM(NFS4ERR_OLD_STATEID);
-TRACE_DEFINE_ENUM(NFS4ERR_OPENMODE);
-TRACE_DEFINE_ENUM(NFS4ERR_OP_ILLEGAL);
-TRACE_DEFINE_ENUM(NFS4ERR_OP_NOT_IN_SESSION);
-TRACE_DEFINE_ENUM(NFS4ERR_PERM);
-TRACE_DEFINE_ENUM(NFS4ERR_PNFS_IO_HOLE);
-TRACE_DEFINE_ENUM(NFS4ERR_PNFS_NO_LAYOUT);
-TRACE_DEFINE_ENUM(NFS4ERR_RECALLCONFLICT);
-TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_BAD);
-TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_CONFLICT);
-TRACE_DEFINE_ENUM(NFS4ERR_REJECT_DELEG);
-TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG);
-TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG_TO_CACHE);
-TRACE_DEFINE_ENUM(NFS4ERR_REQ_TOO_BIG);
-TRACE_DEFINE_ENUM(NFS4ERR_RESOURCE);
-TRACE_DEFINE_ENUM(NFS4ERR_RESTOREFH);
-TRACE_DEFINE_ENUM(NFS4ERR_RETRY_UNCACHED_REP);
-TRACE_DEFINE_ENUM(NFS4ERR_RETURNCONFLICT);
-TRACE_DEFINE_ENUM(NFS4ERR_ROFS);
-TRACE_DEFINE_ENUM(NFS4ERR_SAME);
-TRACE_DEFINE_ENUM(NFS4ERR_SHARE_DENIED);
-TRACE_DEFINE_ENUM(NFS4ERR_SEQUENCE_POS);
-TRACE_DEFINE_ENUM(NFS4ERR_SEQ_FALSE_RETRY);
-TRACE_DEFINE_ENUM(NFS4ERR_SEQ_MISORDERED);
-TRACE_DEFINE_ENUM(NFS4ERR_SERVERFAULT);
-TRACE_DEFINE_ENUM(NFS4ERR_STALE);
-TRACE_DEFINE_ENUM(NFS4ERR_STALE_CLIENTID);
-TRACE_DEFINE_ENUM(NFS4ERR_STALE_STATEID);
-TRACE_DEFINE_ENUM(NFS4ERR_SYMLINK);
-TRACE_DEFINE_ENUM(NFS4ERR_TOOSMALL);
-TRACE_DEFINE_ENUM(NFS4ERR_TOO_MANY_OPS);
-TRACE_DEFINE_ENUM(NFS4ERR_UNKNOWN_LAYOUTTYPE);
-TRACE_DEFINE_ENUM(NFS4ERR_UNSAFE_COMPOUND);
-TRACE_DEFINE_ENUM(NFS4ERR_WRONGSEC);
-TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED);
-TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE);
-TRACE_DEFINE_ENUM(NFS4ERR_XDEV);
-
-TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS);
-TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS);
-
-#define show_nfsv4_errors(error) \
-	__print_symbolic(error, \
-		{ NFS4_OK, "OK" }, \
-		/* Mapped by nfs4_stat_to_errno() */ \
-		{ EPERM, "EPERM" }, \
-		{ ENOENT, "ENOENT" }, \
-		{ EIO, "EIO" }, \
-		{ ENXIO, "ENXIO" }, \
-		{ EACCES, "EACCES" }, \
-		{ EEXIST, "EEXIST" }, \
-		{ EXDEV, "EXDEV" }, \
-		{ ENOTDIR, "ENOTDIR" }, \
-		{ EISDIR, "EISDIR" }, \
-		{ EFBIG, "EFBIG" }, \
-		{ ENOSPC, "ENOSPC" }, \
-		{ EROFS, "EROFS" }, \
-		{ EMLINK, "EMLINK" }, \
-		{ ENAMETOOLONG, "ENAMETOOLONG" }, \
-		{ ENOTEMPTY, "ENOTEMPTY" }, \
-		{ EDQUOT, "EDQUOT" }, \
-		{ ESTALE, "ESTALE" }, \
-		{ EBADHANDLE, "EBADHANDLE" }, \
-		{ EBADCOOKIE, "EBADCOOKIE" }, \
-		{ ENOTSUPP, "ENOTSUPP" }, \
-		{ ETOOSMALL, "ETOOSMALL" }, \
-		{ EREMOTEIO, "EREMOTEIO" }, \
-		{ EBADTYPE, "EBADTYPE" }, \
-		{ EAGAIN, "EAGAIN" }, \
-		{ ELOOP, "ELOOP" }, \
-		{ EOPNOTSUPP, "EOPNOTSUPP" }, \
-		{ EDEADLK, "EDEADLK" }, \
-		/* RPC errors */ \
-		{ ENOMEM, "ENOMEM" }, \
-		{ EKEYEXPIRED, "EKEYEXPIRED" }, \
-		{ ETIMEDOUT, "ETIMEDOUT" }, \
-		{ ERESTARTSYS, "ERESTARTSYS" }, \
-		{ ECONNREFUSED, "ECONNREFUSED" }, \
-		{ ECONNRESET, "ECONNRESET" }, \
-		{ ENETUNREACH, "ENETUNREACH" }, \
-		{ EHOSTUNREACH, "EHOSTUNREACH" }, \
-		{ EHOSTDOWN, "EHOSTDOWN" }, \
-		{ EPIPE, "EPIPE" }, \
-		{ EPFNOSUPPORT, "EPFNOSUPPORT" }, \
-		{ EPROTONOSUPPORT, "EPROTONOSUPPORT" }, \
-		/* NFSv4 native errors */ \
-		{ NFS4ERR_ACCESS, "ACCESS" }, \
-		{ NFS4ERR_ATTRNOTSUPP, "ATTRNOTSUPP" }, \
-		{ NFS4ERR_ADMIN_REVOKED, "ADMIN_REVOKED" }, \
-		{ NFS4ERR_BACK_CHAN_BUSY, "BACK_CHAN_BUSY" }, \
-		{ NFS4ERR_BADCHAR, "BADCHAR" }, \
-		{ NFS4ERR_BADHANDLE, "BADHANDLE" }, \
-		{ NFS4ERR_BADIOMODE, "BADIOMODE" }, \
-		{ NFS4ERR_BADLAYOUT, "BADLAYOUT" }, \
-		{ NFS4ERR_BADLABEL, "BADLABEL" }, \
-		{ NFS4ERR_BADNAME, "BADNAME" }, \
-		{ NFS4ERR_BADOWNER, "BADOWNER" }, \
-		{ NFS4ERR_BADSESSION, "BADSESSION" }, \
-		{ NFS4ERR_BADSLOT, "BADSLOT" }, \
-		{ NFS4ERR_BADTYPE, "BADTYPE" }, \
-		{ NFS4ERR_BADXDR, "BADXDR" }, \
-		{ NFS4ERR_BAD_COOKIE, "BAD_COOKIE" }, \
-		{ NFS4ERR_BAD_HIGH_SLOT, "BAD_HIGH_SLOT" }, \
-		{ NFS4ERR_BAD_RANGE, "BAD_RANGE" }, \
-		{ NFS4ERR_BAD_SEQID, "BAD_SEQID" }, \
-		{ NFS4ERR_BAD_SESSION_DIGEST, "BAD_SESSION_DIGEST" }, \
-		{ NFS4ERR_BAD_STATEID, "BAD_STATEID" }, \
-		{ NFS4ERR_CB_PATH_DOWN, "CB_PATH_DOWN" }, \
-		{ NFS4ERR_CLID_INUSE, "CLID_INUSE" }, \
-		{ NFS4ERR_CLIENTID_BUSY, "CLIENTID_BUSY" }, \
-		{ NFS4ERR_COMPLETE_ALREADY, "COMPLETE_ALREADY" }, \
-		{ NFS4ERR_CONN_NOT_BOUND_TO_SESSION, \
-			"CONN_NOT_BOUND_TO_SESSION" }, \
-		{ NFS4ERR_DEADLOCK, "DEADLOCK" }, \
-		{ NFS4ERR_DEADSESSION, "DEAD_SESSION" }, \
-		{ NFS4ERR_DELAY, "DELAY" }, \
-		{ NFS4ERR_DELEG_ALREADY_WANTED, \
-			"DELEG_ALREADY_WANTED" }, \
-		{ NFS4ERR_DELEG_REVOKED, "DELEG_REVOKED" }, \
-		{ NFS4ERR_DENIED, "DENIED" }, \
-		{ NFS4ERR_DIRDELEG_UNAVAIL, "DIRDELEG_UNAVAIL" }, \
-		{ NFS4ERR_DQUOT, "DQUOT" }, \
-		{ NFS4ERR_ENCR_ALG_UNSUPP, "ENCR_ALG_UNSUPP" }, \
-		{ NFS4ERR_EXIST, "EXIST" }, \
-		{ NFS4ERR_EXPIRED, "EXPIRED" }, \
-		{ NFS4ERR_FBIG, "FBIG" }, \
-		{ NFS4ERR_FHEXPIRED, "FHEXPIRED" }, \
-		{ NFS4ERR_FILE_OPEN, "FILE_OPEN" }, \
-		{ NFS4ERR_GRACE, "GRACE" }, \
-		{ NFS4ERR_HASH_ALG_UNSUPP, "HASH_ALG_UNSUPP" }, \
-		{ NFS4ERR_INVAL, "INVAL" }, \
-		{ NFS4ERR_IO, "IO" }, \
-		{ NFS4ERR_ISDIR, "ISDIR" }, \
-		{ NFS4ERR_LAYOUTTRYLATER, "LAYOUTTRYLATER" }, \
-		{ NFS4ERR_LAYOUTUNAVAILABLE, "LAYOUTUNAVAILABLE" }, \
-		{ NFS4ERR_LEASE_MOVED, "LEASE_MOVED" }, \
-		{ NFS4ERR_LOCKED, "LOCKED" }, \
-		{ NFS4ERR_LOCKS_HELD, "LOCKS_HELD" }, \
-		{ NFS4ERR_LOCK_RANGE, "LOCK_RANGE" }, \
-		{ NFS4ERR_MINOR_VERS_MISMATCH, "MINOR_VERS_MISMATCH" }, \
-		{ NFS4ERR_MLINK, "MLINK" }, \
-		{ NFS4ERR_MOVED, "MOVED" }, \
-		{ NFS4ERR_NAMETOOLONG, "NAMETOOLONG" }, \
-		{ NFS4ERR_NOENT, "NOENT" }, \
-		{ NFS4ERR_NOFILEHANDLE, "NOFILEHANDLE" }, \
-		{ NFS4ERR_NOMATCHING_LAYOUT, "NOMATCHING_LAYOUT" }, \
-		{ NFS4ERR_NOSPC, "NOSPC" }, \
-		{ NFS4ERR_NOTDIR, "NOTDIR" }, \
-		{ NFS4ERR_NOTEMPTY, "NOTEMPTY" }, \
-		{ NFS4ERR_NOTSUPP, "NOTSUPP" }, \
-		{ NFS4ERR_NOT_ONLY_OP, "NOT_ONLY_OP" }, \
-		{ NFS4ERR_NOT_SAME, "NOT_SAME" }, \
-		{ NFS4ERR_NO_GRACE, "NO_GRACE" }, \
-		{ NFS4ERR_NXIO, "NXIO" }, \
-		{ NFS4ERR_OLD_STATEID, "OLD_STATEID" }, \
-		{ NFS4ERR_OPENMODE, "OPENMODE" }, \
-		{ NFS4ERR_OP_ILLEGAL, "OP_ILLEGAL" }, \
-		{ NFS4ERR_OP_NOT_IN_SESSION, "OP_NOT_IN_SESSION" }, \
-		{ NFS4ERR_PERM, "PERM" }, \
-		{ NFS4ERR_PNFS_IO_HOLE, "PNFS_IO_HOLE" }, \
-		{ NFS4ERR_PNFS_NO_LAYOUT, "PNFS_NO_LAYOUT" }, \
-		{ NFS4ERR_RECALLCONFLICT, "RECALLCONFLICT" }, \
-		{ NFS4ERR_RECLAIM_BAD, "RECLAIM_BAD" }, \
-		{ NFS4ERR_RECLAIM_CONFLICT, "RECLAIM_CONFLICT" }, \
-		{ NFS4ERR_REJECT_DELEG, "REJECT_DELEG" }, \
-		{ NFS4ERR_REP_TOO_BIG, "REP_TOO_BIG" }, \
-		{ NFS4ERR_REP_TOO_BIG_TO_CACHE, \
-			"REP_TOO_BIG_TO_CACHE" }, \
-		{ NFS4ERR_REQ_TOO_BIG, "REQ_TOO_BIG" }, \
-		{ NFS4ERR_RESOURCE, "RESOURCE" }, \
-		{ NFS4ERR_RESTOREFH, "RESTOREFH" }, \
-		{ NFS4ERR_RETRY_UNCACHED_REP, "RETRY_UNCACHED_REP" }, \
-		{ NFS4ERR_RETURNCONFLICT, "RETURNCONFLICT" }, \
-		{ NFS4ERR_ROFS, "ROFS" }, \
-		{ NFS4ERR_SAME, "SAME" }, \
-		{ NFS4ERR_SHARE_DENIED, "SHARE_DENIED" }, \
-		{ NFS4ERR_SEQUENCE_POS, "SEQUENCE_POS" }, \
-		{ NFS4ERR_SEQ_FALSE_RETRY, "SEQ_FALSE_RETRY" }, \
-		{ NFS4ERR_SEQ_MISORDERED, "SEQ_MISORDERED" }, \
-		{ NFS4ERR_SERVERFAULT, "SERVERFAULT" }, \
-		{ NFS4ERR_STALE, "STALE" }, \
-		{ NFS4ERR_STALE_CLIENTID, "STALE_CLIENTID" }, \
-		{ NFS4ERR_STALE_STATEID, "STALE_STATEID" }, \
-		{ NFS4ERR_SYMLINK, "SYMLINK" }, \
-		{ NFS4ERR_TOOSMALL, "TOOSMALL" }, \
-		{ NFS4ERR_TOO_MANY_OPS, "TOO_MANY_OPS" }, \
-		{ NFS4ERR_UNKNOWN_LAYOUTTYPE, "UNKNOWN_LAYOUTTYPE" }, \
-		{ NFS4ERR_UNSAFE_COMPOUND, "UNSAFE_COMPOUND" }, \
-		{ NFS4ERR_WRONGSEC, "WRONGSEC" }, \
-		{ NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \
-		{ NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \
-		{ NFS4ERR_XDEV, "XDEV" }, \
-		/* ***** Internal to Linux NFS client ***** */ \
-		{ NFS4ERR_RESET_TO_MDS, "RESET_TO_MDS" }, \
-		{ NFS4ERR_RESET_TO_PNFS, "RESET_TO_PNFS" })
+#include <trace/events/nfs.h>
 
 #define show_nfs_fattr_flags(valid) \
 	__print_flags((unsigned long)valid, "|", \
@@ -354,7 +52,7 @@ DECLARE_EVENT_CLASS(nfs4_clientid_event,
 		TP_printk(
 			"error=%ld (%s) dstaddr=%s",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			__get_str(dstaddr)
 		)
 );
@@ -378,29 +76,6 @@ DEFINE_NFS4_CLIENTID_EVENT(nfs4_bind_conn_to_session);
 DEFINE_NFS4_CLIENTID_EVENT(nfs4_sequence);
 DEFINE_NFS4_CLIENTID_EVENT(nfs4_reclaim_complete);
 
-#define show_nfs4_sequence_status_flags(status) \
-	__print_flags((unsigned long)status, "|", \
-		{ SEQ4_STATUS_CB_PATH_DOWN, "CB_PATH_DOWN" }, \
-		{ SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING, \
-			"CB_GSS_CONTEXTS_EXPIRING" }, \
-		{ SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED, \
-			"CB_GSS_CONTEXTS_EXPIRED" }, \
-		{ SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, \
-			"EXPIRED_ALL_STATE_REVOKED" }, \
-		{ SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, \
-			"EXPIRED_SOME_STATE_REVOKED" }, \
-		{ SEQ4_STATUS_ADMIN_STATE_REVOKED, \
-			"ADMIN_STATE_REVOKED" }, \
-		{ SEQ4_STATUS_RECALLABLE_STATE_REVOKED,	 \
-			"RECALLABLE_STATE_REVOKED" }, \
-		{ SEQ4_STATUS_LEASE_MOVED, "LEASE_MOVED" }, \
-		{ SEQ4_STATUS_RESTART_RECLAIM_NEEDED, \
-			"RESTART_RECLAIM_NEEDED" }, \
-		{ SEQ4_STATUS_CB_PATH_DOWN_SESSION, \
-			"CB_PATH_DOWN_SESSION" }, \
-		{ SEQ4_STATUS_BACKCHANNEL_FAULT, \
-			"BACKCHANNEL_FAULT" })
-
 TRACE_EVENT(nfs4_sequence_done,
 		TP_PROTO(
 			const struct nfs4_session *session,
@@ -414,7 +89,7 @@ TRACE_EVENT(nfs4_sequence_done,
 			__field(unsigned int, seq_nr)
 			__field(unsigned int, highest_slotid)
 			__field(unsigned int, target_highest_slotid)
-			__field(unsigned int, status_flags)
+			__field(unsigned long, status_flags)
 			__field(unsigned long, error)
 		),
 
@@ -433,16 +108,16 @@ TRACE_EVENT(nfs4_sequence_done,
 		TP_printk(
 			"error=%ld (%s) session=0x%08x slot_nr=%u seq_nr=%u "
 			"highest_slotid=%u target_highest_slotid=%u "
-			"status_flags=%u (%s)",
+			"status_flags=0x%lx (%s)",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			__entry->session,
 			__entry->slot_nr,
 			__entry->seq_nr,
 			__entry->highest_slotid,
 			__entry->target_highest_slotid,
 			__entry->status_flags,
-			show_nfs4_sequence_status_flags(__entry->status_flags)
+			show_nfs4_seq4_status(__entry->status_flags)
 		)
 );
 
@@ -479,7 +154,7 @@ TRACE_EVENT(nfs4_cb_sequence,
 			"error=%ld (%s) session=0x%08x slot_nr=%u seq_nr=%u "
 			"highest_slotid=%u",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			__entry->session,
 			__entry->slot_nr,
 			__entry->seq_nr,
@@ -516,7 +191,7 @@ TRACE_EVENT(nfs4_cb_seqid_err,
 			"error=%ld (%s) session=0x%08x slot_nr=%u seq_nr=%u "
 			"highest_slotid=%u",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			__entry->session,
 			__entry->slot_nr,
 			__entry->seq_nr,
@@ -650,7 +325,7 @@ TRACE_EVENT(nfs4_state_mgr_failed,
 			"hostname=%s clp state=%s error=%ld (%s) section=%s",
 			__get_str(hostname),
 			show_nfs4_clp_state(__entry->state), -__entry->error,
-			show_nfsv4_errors(__entry->error), __get_str(section)
+			show_nfs4_status(__entry->error), __get_str(section)
 
 		)
 )
@@ -686,7 +361,7 @@ TRACE_EVENT(nfs4_xdr_status,
 		TP_printk(
 			"task:%u@%d xid=0x%08x error=%ld (%s) operation=%u",
 			__entry->task_id, __entry->client_id, __entry->xid,
-			-__entry->error, show_nfsv4_errors(__entry->error),
+			-__entry->error, show_nfs4_status(__entry->error),
 			__entry->op
 		)
 );
@@ -791,7 +466,7 @@ DECLARE_EVENT_CLASS(nfs4_open_event,
 			"name=%02x:%02x:%llu/%s stateid=%d:0x%08x "
 			"openstateid=%d:0x%08x",
 			 -__entry->error,
-			 show_nfsv4_errors(__entry->error),
+			 show_nfs4_status(__entry->error),
 			 __entry->flags,
 			 show_fcntl_open_flags(__entry->flags),
 			 show_fmode_flags(__entry->fmode),
@@ -895,7 +570,7 @@ TRACE_EVENT(nfs4_close,
 			"error=%ld (%s) fmode=%s fileid=%02x:%02x:%llu "
 			"fhandle=0x%08x openstateid=%d:0x%08x",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			__entry->fmode ?  show_fmode_flags(__entry->fmode) :
 					  "closed",
 			MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -950,7 +625,7 @@ DECLARE_EVENT_CLASS(nfs4_lock_event,
 			"fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"stateid=%d:0x%08x",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			show_fcntl_cmd(__entry->cmd),
 			show_fcntl_lock_type(__entry->type),
 			(long long)__entry->start,
@@ -1026,7 +701,7 @@ TRACE_EVENT(nfs4_set_lock,
 			"fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"stateid=%d:0x%08x lockstateid=%d:0x%08x",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			show_fcntl_cmd(__entry->cmd),
 			show_fcntl_lock_type(__entry->type),
 			(long long)__entry->start,
@@ -1192,7 +867,7 @@ TRACE_EVENT(nfs4_delegreturn_exit,
 			"error=%ld (%s) dev=%02x:%02x fhandle=0x%08x "
 			"stateid=%d:0x%08x",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			__entry->fhandle,
 			__entry->stateid_seq, __entry->stateid_hash
@@ -1235,7 +910,7 @@ DECLARE_EVENT_CLASS(nfs4_test_stateid_event,
 			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"stateid=%d:0x%08x",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -1282,7 +957,7 @@ DECLARE_EVENT_CLASS(nfs4_lookup_event,
 		TP_printk(
 			"error=%ld (%s) name=%02x:%02x:%llu/%s",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->dir,
 			__get_str(name)
@@ -1329,7 +1004,7 @@ TRACE_EVENT(nfs4_lookupp,
 		TP_printk(
 			"error=%ld (%s) inode=%02x:%02x:%llu",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->ino
 		)
@@ -1368,7 +1043,7 @@ TRACE_EVENT(nfs4_rename,
 			"error=%ld (%s) oldname=%02x:%02x:%llu/%s "
 			"newname=%02x:%02x:%llu/%s",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->olddir,
 			__get_str(oldname),
@@ -1403,7 +1078,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_event,
 		TP_printk(
 			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle
@@ -1461,7 +1136,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_stateid_event,
 			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"stateid=%d:0x%08x",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -1513,7 +1188,7 @@ DECLARE_EVENT_CLASS(nfs4_getattr_event,
 			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"valid=%s",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -1569,7 +1244,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_callback_event,
 			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"dstaddr=%s",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -1630,7 +1305,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_stateid_callback_event,
 			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"stateid=%d:0x%08x dstaddr=%s",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -1679,7 +1354,7 @@ DECLARE_EVENT_CLASS(nfs4_idmap_event,
 
 		TP_printk(
 			"error=%ld (%s) id=%u name=%s",
-			-__entry->error, show_nfsv4_errors(__entry->error),
+			-__entry->error, show_nfs4_status(__entry->error),
 			__entry->id,
 			__get_str(name)
 		)
@@ -1757,7 +1432,7 @@ DECLARE_EVENT_CLASS(nfs4_read_event,
 			"offset=%lld count=%u res=%u stateid=%d:0x%08x "
 			"layoutstateid=%d:0x%08x",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -1831,7 +1506,7 @@ DECLARE_EVENT_CLASS(nfs4_write_event,
 			"offset=%lld count=%u res=%u stateid=%d:0x%08x "
 			"layoutstateid=%d:0x%08x",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -1895,7 +1570,7 @@ DECLARE_EVENT_CLASS(nfs4_commit_event,
 			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"offset=%lld count=%u layoutstateid=%d:0x%08x",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -1980,7 +1655,7 @@ TRACE_EVENT(nfs4_layoutget,
 			"iomode=%s offset=%llu count=%llu stateid=%d:0x%08x "
 			"layoutstateid=%d:0x%08x",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -2202,7 +1877,7 @@ DECLARE_EVENT_CLASS(nfs4_flexfiles_io_event,
 			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"offset=%llu count=%u stateid=%d:0x%08x dstaddr=%s",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -2258,7 +1933,7 @@ TRACE_EVENT(ff_layout_commit_error,
 			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"offset=%llu count=%u dstaddr=%s",
 			-__entry->error,
-			show_nfsv4_errors(__entry->error),
+			show_nfs4_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h
index 91677dea7e3d..99b8cb359c0f 100644
--- a/fs/nfs/nfstrace.h
+++ b/fs/nfs/nfstrace.h
@@ -12,6 +12,7 @@
 #include <linux/iversion.h>
 
 #include <trace/events/fs.h>
+#include <trace/events/nfs.h>
 
 TRACE_DEFINE_ENUM(NFS_INO_INVALID_DATA);
 TRACE_DEFINE_ENUM(NFS_INO_INVALID_ATIME);
@@ -134,7 +135,7 @@ DECLARE_EVENT_CLASS(nfs_inode_event_done,
 			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
 			"type=%u (%s) version=%llu size=%lld "
 			"cache_validity=0x%lx (%s) nfs_flags=0x%lx (%s)",
-			-__entry->error, nfs_show_status(__entry->error),
+			-__entry->error, show_nfs_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -225,7 +226,7 @@ TRACE_EVENT(nfs_access_exit,
 			"type=%u (%s) version=%llu size=%lld "
 			"cache_validity=0x%lx (%s) nfs_flags=0x%lx (%s) "
 			"mask=0x%x permitted=0x%x",
-			-__entry->error, nfs_show_status(__entry->error),
+			-__entry->error, show_nfs_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
@@ -311,7 +312,7 @@ DECLARE_EVENT_CLASS(nfs_lookup_event_done,
 
 		TP_printk(
 			"error=%ld (%s) flags=0x%lx (%s) name=%02x:%02x:%llu/%s",
-			-__entry->error, nfs_show_status(__entry->error),
+			-__entry->error, show_nfs_status(__entry->error),
 			__entry->flags,
 			show_vfs_lookup_flags(__entry->flags),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -402,7 +403,7 @@ TRACE_EVENT(nfs_atomic_open_exit,
 		TP_printk(
 			"error=%ld (%s) flags=0x%lx (%s) fmode=%s "
 			"name=%02x:%02x:%llu/%s",
-			-__entry->error, nfs_show_status(__entry->error),
+			-__entry->error, show_nfs_status(__entry->error),
 			__entry->flags,
 			show_fcntl_open_flags(__entry->flags),
 			show_fmode_flags(__entry->fmode),
@@ -473,7 +474,7 @@ TRACE_EVENT(nfs_create_exit,
 
 		TP_printk(
 			"error=%ld (%s) flags=0x%lx (%s) name=%02x:%02x:%llu/%s",
-			-__entry->error, nfs_show_status(__entry->error),
+			-__entry->error, show_nfs_status(__entry->error),
 			__entry->flags,
 			show_fcntl_open_flags(__entry->flags),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -543,7 +544,7 @@ DECLARE_EVENT_CLASS(nfs_directory_event_done,
 
 		TP_printk(
 			"error=%ld (%s) name=%02x:%02x:%llu/%s",
-			-__entry->error, nfs_show_status(__entry->error),
+			-__entry->error, show_nfs_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->dir,
 			__get_str(name)
@@ -633,7 +634,7 @@ TRACE_EVENT(nfs_link_exit,
 
 		TP_printk(
 			"error=%ld (%s) fileid=%02x:%02x:%llu name=%02x:%02x:%llu/%s",
-			-__entry->error, nfs_show_status(__entry->error),
+			-__entry->error, show_nfs_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			__entry->fileid,
 			MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -720,7 +721,7 @@ DECLARE_EVENT_CLASS(nfs_rename_event_done,
 		TP_printk(
 			"error=%ld (%s) old_name=%02x:%02x:%llu/%s "
 			"new_name=%02x:%02x:%llu/%s",
-			-__entry->error, nfs_show_status(__entry->error),
+			-__entry->error, show_nfs_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->old_dir,
 			__get_str(old_name),
@@ -774,7 +775,7 @@ TRACE_EVENT(nfs_sillyrename_unlink,
 
 		TP_printk(
 			"error=%ld (%s) name=%02x:%02x:%llu/%s",
-			-__entry->error, nfs_show_status(__entry->error),
+			-__entry->error, show_nfs_status(__entry->error),
 			MAJOR(__entry->dev), MINOR(__entry->dev),
 			(unsigned long long)__entry->dir,
 			__get_str(name)
@@ -957,16 +958,6 @@ TRACE_EVENT(nfs_pgio_error,
 	)
 );
 
-TRACE_DEFINE_ENUM(NFS_UNSTABLE);
-TRACE_DEFINE_ENUM(NFS_DATA_SYNC);
-TRACE_DEFINE_ENUM(NFS_FILE_SYNC);
-
-#define nfs_show_stable(stable) \
-	__print_symbolic(stable, \
-			{ NFS_UNSTABLE, "UNSTABLE" }, \
-			{ NFS_DATA_SYNC, "DATA_SYNC" }, \
-			{ NFS_FILE_SYNC, "FILE_SYNC" })
-
 TRACE_EVENT(nfs_initiate_write,
 		TP_PROTO(
 			const struct nfs_pgio_header *hdr
@@ -980,7 +971,7 @@ TRACE_EVENT(nfs_initiate_write,
 			__field(u64, fileid)
 			__field(loff_t, offset)
 			__field(u32, count)
-			__field(enum nfs3_stable_how, stable)
+			__field(unsigned long, stable)
 		),
 
 		TP_fast_assign(
@@ -1004,7 +995,7 @@ TRACE_EVENT(nfs_initiate_write,
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
 			(long long)__entry->offset, __entry->count,
-			nfs_show_stable(__entry->stable)
+			show_nfs_stable_how(__entry->stable)
 		)
 );
 
@@ -1024,7 +1015,7 @@ TRACE_EVENT(nfs_writeback_done,
 			__field(u32, arg_count)
 			__field(u32, res_count)
 			__field(int, status)
-			__field(enum nfs3_stable_how, stable)
+			__field(unsigned long, stable)
 			__array(char, verifier, NFS4_VERIFIER_SIZE)
 		),
 
@@ -1057,7 +1048,7 @@ TRACE_EVENT(nfs_writeback_done,
 			__entry->fhandle,
 			(long long)__entry->offset, __entry->arg_count,
 			__entry->res_count, __entry->status,
-			nfs_show_stable(__entry->stable),
+			show_nfs_stable_how(__entry->stable),
 			__print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE)
 		)
 );
@@ -1159,7 +1150,7 @@ TRACE_EVENT(nfs_commit_done,
 			__field(u64, fileid)
 			__field(loff_t, offset)
 			__field(int, status)
-			__field(enum nfs3_stable_how, stable)
+			__field(unsigned long, stable)
 			__array(char, verifier, NFS4_VERIFIER_SIZE)
 		),
 
@@ -1188,7 +1179,7 @@ TRACE_EVENT(nfs_commit_done,
 			(unsigned long long)__entry->fileid,
 			__entry->fhandle,
 			(long long)__entry->offset, __entry->status,
-			nfs_show_stable(__entry->stable),
+			show_nfs_stable_how(__entry->stable),
 			__print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE)
 		)
 );
@@ -1226,76 +1217,6 @@ TRACE_EVENT(nfs_fh_to_dentry,
 		)
 );
 
-TRACE_DEFINE_ENUM(NFS_OK);
-TRACE_DEFINE_ENUM(NFSERR_PERM);
-TRACE_DEFINE_ENUM(NFSERR_NOENT);
-TRACE_DEFINE_ENUM(NFSERR_IO);
-TRACE_DEFINE_ENUM(NFSERR_NXIO);
-TRACE_DEFINE_ENUM(ECHILD);
-TRACE_DEFINE_ENUM(NFSERR_EAGAIN);
-TRACE_DEFINE_ENUM(NFSERR_ACCES);
-TRACE_DEFINE_ENUM(NFSERR_EXIST);
-TRACE_DEFINE_ENUM(NFSERR_XDEV);
-TRACE_DEFINE_ENUM(NFSERR_NODEV);
-TRACE_DEFINE_ENUM(NFSERR_NOTDIR);
-TRACE_DEFINE_ENUM(NFSERR_ISDIR);
-TRACE_DEFINE_ENUM(NFSERR_INVAL);
-TRACE_DEFINE_ENUM(NFSERR_FBIG);
-TRACE_DEFINE_ENUM(NFSERR_NOSPC);
-TRACE_DEFINE_ENUM(NFSERR_ROFS);
-TRACE_DEFINE_ENUM(NFSERR_MLINK);
-TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP);
-TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG);
-TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY);
-TRACE_DEFINE_ENUM(NFSERR_DQUOT);
-TRACE_DEFINE_ENUM(NFSERR_STALE);
-TRACE_DEFINE_ENUM(NFSERR_REMOTE);
-TRACE_DEFINE_ENUM(NFSERR_WFLUSH);
-TRACE_DEFINE_ENUM(NFSERR_BADHANDLE);
-TRACE_DEFINE_ENUM(NFSERR_NOT_SYNC);
-TRACE_DEFINE_ENUM(NFSERR_BAD_COOKIE);
-TRACE_DEFINE_ENUM(NFSERR_NOTSUPP);
-TRACE_DEFINE_ENUM(NFSERR_TOOSMALL);
-TRACE_DEFINE_ENUM(NFSERR_SERVERFAULT);
-TRACE_DEFINE_ENUM(NFSERR_BADTYPE);
-TRACE_DEFINE_ENUM(NFSERR_JUKEBOX);
-
-#define nfs_show_status(x) \
-	__print_symbolic(x, \
-			{ NFS_OK, "OK" }, \
-			{ NFSERR_PERM, "PERM" }, \
-			{ NFSERR_NOENT, "NOENT" }, \
-			{ NFSERR_IO, "IO" }, \
-			{ NFSERR_NXIO, "NXIO" }, \
-			{ ECHILD, "CHILD" }, \
-			{ NFSERR_EAGAIN, "AGAIN" }, \
-			{ NFSERR_ACCES, "ACCES" }, \
-			{ NFSERR_EXIST, "EXIST" }, \
-			{ NFSERR_XDEV, "XDEV" }, \
-			{ NFSERR_NODEV, "NODEV" }, \
-			{ NFSERR_NOTDIR, "NOTDIR" }, \
-			{ NFSERR_ISDIR, "ISDIR" }, \
-			{ NFSERR_INVAL, "INVAL" }, \
-			{ NFSERR_FBIG, "FBIG" }, \
-			{ NFSERR_NOSPC, "NOSPC" }, \
-			{ NFSERR_ROFS, "ROFS" }, \
-			{ NFSERR_MLINK, "MLINK" }, \
-			{ NFSERR_OPNOTSUPP, "OPNOTSUPP" }, \
-			{ NFSERR_NAMETOOLONG, "NAMETOOLONG" }, \
-			{ NFSERR_NOTEMPTY, "NOTEMPTY" }, \
-			{ NFSERR_DQUOT, "DQUOT" }, \
-			{ NFSERR_STALE, "STALE" }, \
-			{ NFSERR_REMOTE, "REMOTE" }, \
-			{ NFSERR_WFLUSH, "WFLUSH" }, \
-			{ NFSERR_BADHANDLE, "BADHANDLE" }, \
-			{ NFSERR_NOT_SYNC, "NOTSYNC" }, \
-			{ NFSERR_BAD_COOKIE, "BADCOOKIE" }, \
-			{ NFSERR_NOTSUPP, "NOTSUPP" }, \
-			{ NFSERR_TOOSMALL, "TOOSMALL" }, \
-			{ NFSERR_SERVERFAULT, "REMOTEIO" }, \
-			{ NFSERR_BADTYPE, "BADTYPE" }, \
-			{ NFSERR_JUKEBOX, "JUKEBOX" })
-
 TRACE_EVENT(nfs_xdr_status,
 		TP_PROTO(
 			const struct xdr_stream *xdr,
@@ -1335,7 +1256,7 @@ TRACE_EVENT(nfs_xdr_status,
 			__entry->task_id, __entry->client_id, __entry->xid,
 			__get_str(program), __entry->version,
 			__get_str(procedure), -__entry->error,
-			nfs_show_status(__entry->error)
+			show_nfs_status(__entry->error)
 		)
 );
 
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 2661c44c62db..bd4b397b98d3 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -80,10 +80,6 @@ enum pnfs_try_status {
 	PNFS_TRY_AGAIN     = 2,
 };
 
-/* error codes for internal use */
-#define NFS4ERR_RESET_TO_MDS   12001
-#define NFS4ERR_RESET_TO_PNFS  12002
-
 #ifdef CONFIG_NFS_V4_1
 
 #define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4"
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 1861db1bdc67..1909fc57435f 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -9,6 +9,7 @@
 #define _NFSD_TRACE_H
 
 #include <linux/tracepoint.h>
+
 #include "export.h"
 #include "nfsfh.h"
 
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index b8360be141da..985fb3def3df 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -292,6 +292,10 @@ enum nfsstat4 {
 	NFS4ERR_XATTR2BIG      = 10096,
 };
 
+/* error codes for internal client use */
+#define NFS4ERR_RESET_TO_MDS   12001
+#define NFS4ERR_RESET_TO_PNFS  12002
+
 static inline bool seqid_mutating_err(u32 err)
 {
 	/* See RFC 7530, section 9.1.7 */
diff --git a/include/trace/events/nfs.h b/include/trace/events/nfs.h
new file mode 100644
index 000000000000..8e3de3b421f4
--- /dev/null
+++ b/include/trace/events/nfs.h
@@ -0,0 +1,361 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Display helpers for NFS protocol elements
+ *
+ * Author: Chuck Lever <chuck.lever@oracle.com>
+ *
+ * Copyright (c) 2020, Oracle and/or its affiliates.
+ */
+
+#include <linux/nfs4.h>
+#include <uapi/linux/nfs.h>
+
+TRACE_DEFINE_ENUM(NFS_OK);
+TRACE_DEFINE_ENUM(NFSERR_PERM);
+TRACE_DEFINE_ENUM(NFSERR_NOENT);
+TRACE_DEFINE_ENUM(NFSERR_IO);
+TRACE_DEFINE_ENUM(NFSERR_NXIO);
+TRACE_DEFINE_ENUM(NFSERR_EAGAIN);
+TRACE_DEFINE_ENUM(NFSERR_ACCES);
+TRACE_DEFINE_ENUM(NFSERR_EXIST);
+TRACE_DEFINE_ENUM(NFSERR_XDEV);
+TRACE_DEFINE_ENUM(NFSERR_NODEV);
+TRACE_DEFINE_ENUM(NFSERR_NOTDIR);
+TRACE_DEFINE_ENUM(NFSERR_ISDIR);
+TRACE_DEFINE_ENUM(NFSERR_INVAL);
+TRACE_DEFINE_ENUM(NFSERR_FBIG);
+TRACE_DEFINE_ENUM(NFSERR_NOSPC);
+TRACE_DEFINE_ENUM(NFSERR_ROFS);
+TRACE_DEFINE_ENUM(NFSERR_MLINK);
+TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP);
+TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG);
+TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY);
+TRACE_DEFINE_ENUM(NFSERR_DQUOT);
+TRACE_DEFINE_ENUM(NFSERR_STALE);
+TRACE_DEFINE_ENUM(NFSERR_REMOTE);
+TRACE_DEFINE_ENUM(NFSERR_WFLUSH);
+TRACE_DEFINE_ENUM(NFSERR_BADHANDLE);
+TRACE_DEFINE_ENUM(NFSERR_NOT_SYNC);
+TRACE_DEFINE_ENUM(NFSERR_BAD_COOKIE);
+TRACE_DEFINE_ENUM(NFSERR_NOTSUPP);
+TRACE_DEFINE_ENUM(NFSERR_TOOSMALL);
+TRACE_DEFINE_ENUM(NFSERR_SERVERFAULT);
+TRACE_DEFINE_ENUM(NFSERR_BADTYPE);
+TRACE_DEFINE_ENUM(NFSERR_JUKEBOX);
+
+#define show_nfs_status(x) \
+	__print_symbolic(x, \
+		{ NFS_OK,			"OK" }, \
+		{ NFSERR_PERM,			"PERM" }, \
+		{ NFSERR_NOENT,			"NOENT" }, \
+		{ NFSERR_IO,			"IO" }, \
+		{ NFSERR_NXIO,			"NXIO" }, \
+		{ ECHILD,			"CHILD" }, \
+		{ NFSERR_EAGAIN,		"AGAIN" }, \
+		{ NFSERR_ACCES,			"ACCES" }, \
+		{ NFSERR_EXIST,			"EXIST" }, \
+		{ NFSERR_XDEV,			"XDEV" }, \
+		{ NFSERR_NODEV,			"NODEV" }, \
+		{ NFSERR_NOTDIR,		"NOTDIR" }, \
+		{ NFSERR_ISDIR,			"ISDIR" }, \
+		{ NFSERR_INVAL,			"INVAL" }, \
+		{ NFSERR_FBIG,			"FBIG" }, \
+		{ NFSERR_NOSPC,			"NOSPC" }, \
+		{ NFSERR_ROFS,			"ROFS" }, \
+		{ NFSERR_MLINK,			"MLINK" }, \
+		{ NFSERR_OPNOTSUPP,		"OPNOTSUPP" }, \
+		{ NFSERR_NAMETOOLONG,		"NAMETOOLONG" }, \
+		{ NFSERR_NOTEMPTY,		"NOTEMPTY" }, \
+		{ NFSERR_DQUOT,			"DQUOT" }, \
+		{ NFSERR_STALE,			"STALE" }, \
+		{ NFSERR_REMOTE,		"REMOTE" }, \
+		{ NFSERR_WFLUSH,		"WFLUSH" }, \
+		{ NFSERR_BADHANDLE,		"BADHANDLE" }, \
+		{ NFSERR_NOT_SYNC,		"NOTSYNC" }, \
+		{ NFSERR_BAD_COOKIE,		"BADCOOKIE" }, \
+		{ NFSERR_NOTSUPP,		"NOTSUPP" }, \
+		{ NFSERR_TOOSMALL,		"TOOSMALL" }, \
+		{ NFSERR_SERVERFAULT,		"REMOTEIO" }, \
+		{ NFSERR_BADTYPE,		"BADTYPE" }, \
+		{ NFSERR_JUKEBOX,		"JUKEBOX" })
+
+TRACE_DEFINE_ENUM(NFS4_OK);
+TRACE_DEFINE_ENUM(NFS4ERR_ACCESS);
+TRACE_DEFINE_ENUM(NFS4ERR_ATTRNOTSUPP);
+TRACE_DEFINE_ENUM(NFS4ERR_ADMIN_REVOKED);
+TRACE_DEFINE_ENUM(NFS4ERR_BACK_CHAN_BUSY);
+TRACE_DEFINE_ENUM(NFS4ERR_BADCHAR);
+TRACE_DEFINE_ENUM(NFS4ERR_BADHANDLE);
+TRACE_DEFINE_ENUM(NFS4ERR_BADIOMODE);
+TRACE_DEFINE_ENUM(NFS4ERR_BADLAYOUT);
+TRACE_DEFINE_ENUM(NFS4ERR_BADLABEL);
+TRACE_DEFINE_ENUM(NFS4ERR_BADNAME);
+TRACE_DEFINE_ENUM(NFS4ERR_BADOWNER);
+TRACE_DEFINE_ENUM(NFS4ERR_BADSESSION);
+TRACE_DEFINE_ENUM(NFS4ERR_BADSLOT);
+TRACE_DEFINE_ENUM(NFS4ERR_BADTYPE);
+TRACE_DEFINE_ENUM(NFS4ERR_BADXDR);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_COOKIE);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_HIGH_SLOT);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_RANGE);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_SEQID);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_SESSION_DIGEST);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_STATEID);
+TRACE_DEFINE_ENUM(NFS4ERR_CB_PATH_DOWN);
+TRACE_DEFINE_ENUM(NFS4ERR_CLID_INUSE);
+TRACE_DEFINE_ENUM(NFS4ERR_CLIENTID_BUSY);
+TRACE_DEFINE_ENUM(NFS4ERR_COMPLETE_ALREADY);
+TRACE_DEFINE_ENUM(NFS4ERR_CONN_NOT_BOUND_TO_SESSION);
+TRACE_DEFINE_ENUM(NFS4ERR_DEADLOCK);
+TRACE_DEFINE_ENUM(NFS4ERR_DEADSESSION);
+TRACE_DEFINE_ENUM(NFS4ERR_DELAY);
+TRACE_DEFINE_ENUM(NFS4ERR_DELEG_ALREADY_WANTED);
+TRACE_DEFINE_ENUM(NFS4ERR_DELEG_REVOKED);
+TRACE_DEFINE_ENUM(NFS4ERR_DENIED);
+TRACE_DEFINE_ENUM(NFS4ERR_DIRDELEG_UNAVAIL);
+TRACE_DEFINE_ENUM(NFS4ERR_DQUOT);
+TRACE_DEFINE_ENUM(NFS4ERR_ENCR_ALG_UNSUPP);
+TRACE_DEFINE_ENUM(NFS4ERR_EXIST);
+TRACE_DEFINE_ENUM(NFS4ERR_EXPIRED);
+TRACE_DEFINE_ENUM(NFS4ERR_FBIG);
+TRACE_DEFINE_ENUM(NFS4ERR_FHEXPIRED);
+TRACE_DEFINE_ENUM(NFS4ERR_FILE_OPEN);
+TRACE_DEFINE_ENUM(NFS4ERR_GRACE);
+TRACE_DEFINE_ENUM(NFS4ERR_HASH_ALG_UNSUPP);
+TRACE_DEFINE_ENUM(NFS4ERR_INVAL);
+TRACE_DEFINE_ENUM(NFS4ERR_IO);
+TRACE_DEFINE_ENUM(NFS4ERR_ISDIR);
+TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTTRYLATER);
+TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTUNAVAILABLE);
+TRACE_DEFINE_ENUM(NFS4ERR_LEASE_MOVED);
+TRACE_DEFINE_ENUM(NFS4ERR_LOCKED);
+TRACE_DEFINE_ENUM(NFS4ERR_LOCKS_HELD);
+TRACE_DEFINE_ENUM(NFS4ERR_LOCK_RANGE);
+TRACE_DEFINE_ENUM(NFS4ERR_MINOR_VERS_MISMATCH);
+TRACE_DEFINE_ENUM(NFS4ERR_MLINK);
+TRACE_DEFINE_ENUM(NFS4ERR_MOVED);
+TRACE_DEFINE_ENUM(NFS4ERR_NAMETOOLONG);
+TRACE_DEFINE_ENUM(NFS4ERR_NOENT);
+TRACE_DEFINE_ENUM(NFS4ERR_NOFILEHANDLE);
+TRACE_DEFINE_ENUM(NFS4ERR_NOMATCHING_LAYOUT);
+TRACE_DEFINE_ENUM(NFS4ERR_NOSPC);
+TRACE_DEFINE_ENUM(NFS4ERR_NOTDIR);
+TRACE_DEFINE_ENUM(NFS4ERR_NOTEMPTY);
+TRACE_DEFINE_ENUM(NFS4ERR_NOTSUPP);
+TRACE_DEFINE_ENUM(NFS4ERR_NOT_ONLY_OP);
+TRACE_DEFINE_ENUM(NFS4ERR_NOT_SAME);
+TRACE_DEFINE_ENUM(NFS4ERR_NO_GRACE);
+TRACE_DEFINE_ENUM(NFS4ERR_NXIO);
+TRACE_DEFINE_ENUM(NFS4ERR_OLD_STATEID);
+TRACE_DEFINE_ENUM(NFS4ERR_OPENMODE);
+TRACE_DEFINE_ENUM(NFS4ERR_OP_ILLEGAL);
+TRACE_DEFINE_ENUM(NFS4ERR_OP_NOT_IN_SESSION);
+TRACE_DEFINE_ENUM(NFS4ERR_PERM);
+TRACE_DEFINE_ENUM(NFS4ERR_PNFS_IO_HOLE);
+TRACE_DEFINE_ENUM(NFS4ERR_PNFS_NO_LAYOUT);
+TRACE_DEFINE_ENUM(NFS4ERR_RECALLCONFLICT);
+TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_BAD);
+TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_CONFLICT);
+TRACE_DEFINE_ENUM(NFS4ERR_REJECT_DELEG);
+TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG);
+TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG_TO_CACHE);
+TRACE_DEFINE_ENUM(NFS4ERR_REQ_TOO_BIG);
+TRACE_DEFINE_ENUM(NFS4ERR_RESOURCE);
+TRACE_DEFINE_ENUM(NFS4ERR_RESTOREFH);
+TRACE_DEFINE_ENUM(NFS4ERR_RETRY_UNCACHED_REP);
+TRACE_DEFINE_ENUM(NFS4ERR_RETURNCONFLICT);
+TRACE_DEFINE_ENUM(NFS4ERR_ROFS);
+TRACE_DEFINE_ENUM(NFS4ERR_SAME);
+TRACE_DEFINE_ENUM(NFS4ERR_SHARE_DENIED);
+TRACE_DEFINE_ENUM(NFS4ERR_SEQUENCE_POS);
+TRACE_DEFINE_ENUM(NFS4ERR_SEQ_FALSE_RETRY);
+TRACE_DEFINE_ENUM(NFS4ERR_SEQ_MISORDERED);
+TRACE_DEFINE_ENUM(NFS4ERR_SERVERFAULT);
+TRACE_DEFINE_ENUM(NFS4ERR_STALE);
+TRACE_DEFINE_ENUM(NFS4ERR_STALE_CLIENTID);
+TRACE_DEFINE_ENUM(NFS4ERR_STALE_STATEID);
+TRACE_DEFINE_ENUM(NFS4ERR_SYMLINK);
+TRACE_DEFINE_ENUM(NFS4ERR_TOOSMALL);
+TRACE_DEFINE_ENUM(NFS4ERR_TOO_MANY_OPS);
+TRACE_DEFINE_ENUM(NFS4ERR_UNKNOWN_LAYOUTTYPE);
+TRACE_DEFINE_ENUM(NFS4ERR_UNSAFE_COMPOUND);
+TRACE_DEFINE_ENUM(NFS4ERR_WRONGSEC);
+TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED);
+TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE);
+TRACE_DEFINE_ENUM(NFS4ERR_XDEV);
+
+TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS);
+TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS);
+
+#define show_nfs4_status(x) \
+	__print_symbolic(x, \
+		{ NFS4_OK,			"OK" }, \
+		{ EPERM,			"EPERM" }, \
+		{ ENOENT,			"ENOENT" }, \
+		{ EIO,				"EIO" }, \
+		{ ENXIO,			"ENXIO" }, \
+		{ EACCES,			"EACCES" }, \
+		{ EEXIST,			"EEXIST" }, \
+		{ EXDEV,			"EXDEV" }, \
+		{ ENOTDIR,			"ENOTDIR" }, \
+		{ EISDIR,			"EISDIR" }, \
+		{ EFBIG,			"EFBIG" }, \
+		{ ENOSPC,			"ENOSPC" }, \
+		{ EROFS,			"EROFS" }, \
+		{ EMLINK,			"EMLINK" }, \
+		{ ENAMETOOLONG,			"ENAMETOOLONG" }, \
+		{ ENOTEMPTY,			"ENOTEMPTY" }, \
+		{ EDQUOT,			"EDQUOT" }, \
+		{ ESTALE,			"ESTALE" }, \
+		{ EBADHANDLE,			"EBADHANDLE" }, \
+		{ EBADCOOKIE,			"EBADCOOKIE" }, \
+		{ ENOTSUPP,			"ENOTSUPP" }, \
+		{ ETOOSMALL,			"ETOOSMALL" }, \
+		{ EREMOTEIO,			"EREMOTEIO" }, \
+		{ EBADTYPE,			"EBADTYPE" }, \
+		{ EAGAIN,			"EAGAIN" }, \
+		{ ELOOP,			"ELOOP" }, \
+		{ EOPNOTSUPP,			"EOPNOTSUPP" }, \
+		{ EDEADLK,			"EDEADLK" }, \
+		{ ENOMEM,			"ENOMEM" }, \
+		{ EKEYEXPIRED,			"EKEYEXPIRED" }, \
+		{ ETIMEDOUT,			"ETIMEDOUT" }, \
+		{ ERESTARTSYS,			"ERESTARTSYS" }, \
+		{ ECONNREFUSED,			"ECONNREFUSED" }, \
+		{ ECONNRESET,			"ECONNRESET" }, \
+		{ ENETUNREACH,			"ENETUNREACH" }, \
+		{ EHOSTUNREACH,			"EHOSTUNREACH" }, \
+		{ EHOSTDOWN,			"EHOSTDOWN" }, \
+		{ EPIPE,			"EPIPE" }, \
+		{ EPFNOSUPPORT,			"EPFNOSUPPORT" }, \
+		{ EPROTONOSUPPORT,		"EPROTONOSUPPORT" }, \
+		{ NFS4ERR_ACCESS,		"ACCESS" }, \
+		{ NFS4ERR_ATTRNOTSUPP,		"ATTRNOTSUPP" }, \
+		{ NFS4ERR_ADMIN_REVOKED,	"ADMIN_REVOKED" }, \
+		{ NFS4ERR_BACK_CHAN_BUSY,	"BACK_CHAN_BUSY" }, \
+		{ NFS4ERR_BADCHAR,		"BADCHAR" }, \
+		{ NFS4ERR_BADHANDLE,		"BADHANDLE" }, \
+		{ NFS4ERR_BADIOMODE,		"BADIOMODE" }, \
+		{ NFS4ERR_BADLAYOUT,		"BADLAYOUT" }, \
+		{ NFS4ERR_BADLABEL,		"BADLABEL" }, \
+		{ NFS4ERR_BADNAME,		"BADNAME" }, \
+		{ NFS4ERR_BADOWNER,		"BADOWNER" }, \
+		{ NFS4ERR_BADSESSION,		"BADSESSION" }, \
+		{ NFS4ERR_BADSLOT,		"BADSLOT" }, \
+		{ NFS4ERR_BADTYPE,		"BADTYPE" }, \
+		{ NFS4ERR_BADXDR,		"BADXDR" }, \
+		{ NFS4ERR_BAD_COOKIE,		"BAD_COOKIE" }, \
+		{ NFS4ERR_BAD_HIGH_SLOT,	"BAD_HIGH_SLOT" }, \
+		{ NFS4ERR_BAD_RANGE,		"BAD_RANGE" }, \
+		{ NFS4ERR_BAD_SEQID,		"BAD_SEQID" }, \
+		{ NFS4ERR_BAD_SESSION_DIGEST,	"BAD_SESSION_DIGEST" }, \
+		{ NFS4ERR_BAD_STATEID,		"BAD_STATEID" }, \
+		{ NFS4ERR_CB_PATH_DOWN,		"CB_PATH_DOWN" }, \
+		{ NFS4ERR_CLID_INUSE,		"CLID_INUSE" }, \
+		{ NFS4ERR_CLIENTID_BUSY,	"CLIENTID_BUSY" }, \
+		{ NFS4ERR_COMPLETE_ALREADY,	"COMPLETE_ALREADY" }, \
+		{ NFS4ERR_CONN_NOT_BOUND_TO_SESSION, "CONN_NOT_BOUND_TO_SESSION" }, \
+		{ NFS4ERR_DEADLOCK,		"DEADLOCK" }, \
+		{ NFS4ERR_DEADSESSION,		"DEAD_SESSION" }, \
+		{ NFS4ERR_DELAY,		"DELAY" }, \
+		{ NFS4ERR_DELEG_ALREADY_WANTED,	"DELEG_ALREADY_WANTED" }, \
+		{ NFS4ERR_DELEG_REVOKED,	"DELEG_REVOKED" }, \
+		{ NFS4ERR_DENIED,		"DENIED" }, \
+		{ NFS4ERR_DIRDELEG_UNAVAIL,	"DIRDELEG_UNAVAIL" }, \
+		{ NFS4ERR_DQUOT,		"DQUOT" }, \
+		{ NFS4ERR_ENCR_ALG_UNSUPP,	"ENCR_ALG_UNSUPP" }, \
+		{ NFS4ERR_EXIST,		"EXIST" }, \
+		{ NFS4ERR_EXPIRED,		"EXPIRED" }, \
+		{ NFS4ERR_FBIG,			"FBIG" }, \
+		{ NFS4ERR_FHEXPIRED,		"FHEXPIRED" }, \
+		{ NFS4ERR_FILE_OPEN,		"FILE_OPEN" }, \
+		{ NFS4ERR_GRACE,		"GRACE" }, \
+		{ NFS4ERR_HASH_ALG_UNSUPP,	"HASH_ALG_UNSUPP" }, \
+		{ NFS4ERR_INVAL,		"INVAL" }, \
+		{ NFS4ERR_IO,			"IO" }, \
+		{ NFS4ERR_ISDIR,		"ISDIR" }, \
+		{ NFS4ERR_LAYOUTTRYLATER,	"LAYOUTTRYLATER" }, \
+		{ NFS4ERR_LAYOUTUNAVAILABLE,	"LAYOUTUNAVAILABLE" }, \
+		{ NFS4ERR_LEASE_MOVED,		"LEASE_MOVED" }, \
+		{ NFS4ERR_LOCKED,		"LOCKED" }, \
+		{ NFS4ERR_LOCKS_HELD,		"LOCKS_HELD" }, \
+		{ NFS4ERR_LOCK_RANGE,		"LOCK_RANGE" }, \
+		{ NFS4ERR_MINOR_VERS_MISMATCH,	"MINOR_VERS_MISMATCH" }, \
+		{ NFS4ERR_MLINK,		"MLINK" }, \
+		{ NFS4ERR_MOVED,		"MOVED" }, \
+		{ NFS4ERR_NAMETOOLONG,		"NAMETOOLONG" }, \
+		{ NFS4ERR_NOENT,		"NOENT" }, \
+		{ NFS4ERR_NOFILEHANDLE,		"NOFILEHANDLE" }, \
+		{ NFS4ERR_NOMATCHING_LAYOUT,	"NOMATCHING_LAYOUT" }, \
+		{ NFS4ERR_NOSPC,		"NOSPC" }, \
+		{ NFS4ERR_NOTDIR,		"NOTDIR" }, \
+		{ NFS4ERR_NOTEMPTY,		"NOTEMPTY" }, \
+		{ NFS4ERR_NOTSUPP,		"NOTSUPP" }, \
+		{ NFS4ERR_NOT_ONLY_OP,		"NOT_ONLY_OP" }, \
+		{ NFS4ERR_NOT_SAME,		"NOT_SAME" }, \
+		{ NFS4ERR_NO_GRACE,		"NO_GRACE" }, \
+		{ NFS4ERR_NXIO,			"NXIO" }, \
+		{ NFS4ERR_OLD_STATEID,		"OLD_STATEID" }, \
+		{ NFS4ERR_OPENMODE,		"OPENMODE" }, \
+		{ NFS4ERR_OP_ILLEGAL,		"OP_ILLEGAL" }, \
+		{ NFS4ERR_OP_NOT_IN_SESSION,	"OP_NOT_IN_SESSION" }, \
+		{ NFS4ERR_PERM,			"PERM" }, \
+		{ NFS4ERR_PNFS_IO_HOLE,		"PNFS_IO_HOLE" }, \
+		{ NFS4ERR_PNFS_NO_LAYOUT,	"PNFS_NO_LAYOUT" }, \
+		{ NFS4ERR_RECALLCONFLICT,	"RECALLCONFLICT" }, \
+		{ NFS4ERR_RECLAIM_BAD,		"RECLAIM_BAD" }, \
+		{ NFS4ERR_RECLAIM_CONFLICT,	"RECLAIM_CONFLICT" }, \
+		{ NFS4ERR_REJECT_DELEG,		"REJECT_DELEG" }, \
+		{ NFS4ERR_REP_TOO_BIG,		"REP_TOO_BIG" }, \
+		{ NFS4ERR_REP_TOO_BIG_TO_CACHE,	"REP_TOO_BIG_TO_CACHE" }, \
+		{ NFS4ERR_REQ_TOO_BIG,		"REQ_TOO_BIG" }, \
+		{ NFS4ERR_RESOURCE,		"RESOURCE" }, \
+		{ NFS4ERR_RESTOREFH,		"RESTOREFH" }, \
+		{ NFS4ERR_RETRY_UNCACHED_REP,	"RETRY_UNCACHED_REP" }, \
+		{ NFS4ERR_RETURNCONFLICT,	"RETURNCONFLICT" }, \
+		{ NFS4ERR_ROFS,			"ROFS" }, \
+		{ NFS4ERR_SAME,			"SAME" }, \
+		{ NFS4ERR_SHARE_DENIED,		"SHARE_DENIED" }, \
+		{ NFS4ERR_SEQUENCE_POS,		"SEQUENCE_POS" }, \
+		{ NFS4ERR_SEQ_FALSE_RETRY,	"SEQ_FALSE_RETRY" }, \
+		{ NFS4ERR_SEQ_MISORDERED,	"SEQ_MISORDERED" }, \
+		{ NFS4ERR_SERVERFAULT,		"SERVERFAULT" }, \
+		{ NFS4ERR_STALE,		"STALE" }, \
+		{ NFS4ERR_STALE_CLIENTID,	"STALE_CLIENTID" }, \
+		{ NFS4ERR_STALE_STATEID,	"STALE_STATEID" }, \
+		{ NFS4ERR_SYMLINK,		"SYMLINK" }, \
+		{ NFS4ERR_TOOSMALL,		"TOOSMALL" }, \
+		{ NFS4ERR_TOO_MANY_OPS,		"TOO_MANY_OPS" }, \
+		{ NFS4ERR_UNKNOWN_LAYOUTTYPE,	"UNKNOWN_LAYOUTTYPE" }, \
+		{ NFS4ERR_UNSAFE_COMPOUND,	"UNSAFE_COMPOUND" }, \
+		{ NFS4ERR_WRONGSEC,		"WRONGSEC" }, \
+		{ NFS4ERR_WRONG_CRED,		"WRONG_CRED" }, \
+		{ NFS4ERR_WRONG_TYPE,		"WRONG_TYPE" }, \
+		{ NFS4ERR_XDEV,			"XDEV" }, \
+		/* ***** Internal to Linux NFS client ***** */ \
+		{ NFS4ERR_RESET_TO_MDS,		"RESET_TO_MDS" }, \
+		{ NFS4ERR_RESET_TO_PNFS,	"RESET_TO_PNFS" })
+
+TRACE_DEFINE_ENUM(NFS_UNSTABLE);
+TRACE_DEFINE_ENUM(NFS_DATA_SYNC);
+TRACE_DEFINE_ENUM(NFS_FILE_SYNC);
+
+#define show_nfs_stable_how(x) \
+	__print_symbolic(x, \
+			{ NFS_UNSTABLE, "UNSTABLE" }, \
+			{ NFS_DATA_SYNC, "DATA_SYNC" }, \
+			{ NFS_FILE_SYNC, "FILE_SYNC" })
+
+#define show_nfs4_seq4_status(x) \
+	__print_flags(x, "|", \
+		{ SEQ4_STATUS_CB_PATH_DOWN,		"CB_PATH_DOWN" }, \
+		{ SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING,	"CB_GSS_CONTEXTS_EXPIRING" }, \
+		{ SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED,	"CB_GSS_CONTEXTS_EXPIRED" }, \
+		{ SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, "EXPIRED_ALL_STATE_REVOKED" }, \
+		{ SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, "EXPIRED_SOME_STATE_REVOKED" }, \
+		{ SEQ4_STATUS_ADMIN_STATE_REVOKED,	"ADMIN_STATE_REVOKED" }, \
+		{ SEQ4_STATUS_RECALLABLE_STATE_REVOKED,	"RECALLABLE_STATE_REVOKED" }, \
+		{ SEQ4_STATUS_LEASE_MOVED,		"LEASE_MOVED" }, \
+		{ SEQ4_STATUS_RESTART_RECLAIM_NEEDED,	"RESTART_RECLAIM_NEEDED" }, \
+		{ SEQ4_STATUS_CB_PATH_DOWN_SESSION,	"CB_PATH_DOWN_SESSION" }, \
+		{ SEQ4_STATUS_BACKCHANNEL_FAULT,	"BACKCHANNEL_FAULT" })



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

* [PATCH v2 03/27] NFSD: Add SPDX header for fs/nfsd/trace.c
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
  2020-09-21 18:10 ` [PATCH v2 01/27] NFS: Move generic FS show macros to global header Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 02/27] NFS: Move NFS protocol display " Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 04/27] SUNRPC: Move the svc_xdr_recvfrom() tracepoint Chuck Lever
                   ` (24 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Clean up.

The file was contributed in 2014 by Christoph Hellwig in commit
31ef83dc0538 ("nfsd: add trace events").

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/trace.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/nfsd/trace.c b/fs/nfsd/trace.c
index 90967466a1e5..f008b95ceec2 100644
--- a/fs/nfsd/trace.c
+++ b/fs/nfsd/trace.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"



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

* [PATCH v2 04/27] SUNRPC: Move the svc_xdr_recvfrom() tracepoint
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (2 preceding siblings ...)
  2020-09-21 18:11 ` [PATCH v2 03/27] NFSD: Add SPDX header for fs/nfsd/trace.c Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 05/27] SUNRPC: Add svc_xdr_authenticate tracepoint Chuck Lever
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Commit c509f15a5801 ("SUNRPC: Split the xdr_buf event class") added
display of the rqst's XID to the svc_xdr_buf_class. However, when
the recvfrom tracepoint fires, rq_xid has yet to be filled in with
the current XID. So it ends up recording the last XID that was
handled by that svc_rqst.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 include/trace/events/sunrpc.h |   24 ------------------------
 net/sunrpc/svc_xprt.c         |    4 +---
 2 files changed, 1 insertion(+), 27 deletions(-)

diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
index 65d7dfbbc9cd..6afd39572dcd 100644
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -1279,30 +1279,6 @@ SVC_RQST_FLAG_LIST
 #define show_rqstp_flags(flags)						\
 		__print_flags(flags, "|", SVC_RQST_FLAG_LIST)
 
-TRACE_EVENT(svc_recv,
-	TP_PROTO(struct svc_rqst *rqst, int len),
-
-	TP_ARGS(rqst, len),
-
-	TP_STRUCT__entry(
-		__field(u32, xid)
-		__field(int, len)
-		__field(unsigned long, flags)
-		__string(addr, rqst->rq_xprt->xpt_remotebuf)
-	),
-
-	TP_fast_assign(
-		__entry->xid = be32_to_cpu(rqst->rq_xid);
-		__entry->len = len;
-		__entry->flags = rqst->rq_flags;
-		__assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
-	),
-
-	TP_printk("addr=%s xid=0x%08x len=%d flags=%s",
-			__get_str(addr), __entry->xid, __entry->len,
-			show_rqstp_flags(__entry->flags))
-);
-
 TRACE_DEFINE_ENUM(SVC_GARBAGE);
 TRACE_DEFINE_ENUM(SVC_SYSERR);
 TRACE_DEFINE_ENUM(SVC_VALID);
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 43cf8dbde898..5fb9164aa690 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -813,8 +813,6 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt)
 			len = svc_deferred_recv(rqstp);
 		else
 			len = xprt->xpt_ops->xpo_recvfrom(rqstp);
-		if (len > 0)
-			trace_svc_xdr_recvfrom(rqstp, &rqstp->rq_arg);
 		rqstp->rq_stime = ktime_get();
 		rqstp->rq_reserved = serv->sv_max_mesg;
 		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
@@ -868,7 +866,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
 
 	if (serv->sv_stats)
 		serv->sv_stats->netcnt++;
-	trace_svc_recv(rqstp, len);
+	trace_svc_xdr_recvfrom(rqstp, &rqstp->rq_arg);
 	return len;
 out_release:
 	rqstp->rq_res.len = 0;



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

* [PATCH v2 05/27] SUNRPC: Add svc_xdr_authenticate tracepoint
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (3 preceding siblings ...)
  2020-09-21 18:11 ` [PATCH v2 04/27] SUNRPC: Move the svc_xdr_recvfrom() tracepoint Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 06/27] lockd: Replace PROC() macro with open code Chuck Lever
                   ` (22 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Enable examination of the incoming RPC Call buffer _after_ it has
been unwrapped to help troubleshoot problems with the GSS unwrap
functions.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 include/trace/events/sunrpc.h |    1 +
 net/sunrpc/svcauth.c          |    5 ++++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
index 6afd39572dcd..aac12f45bfb0 100644
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -1249,6 +1249,7 @@ DECLARE_EVENT_CLASS(svc_xdr_buf_class,
 
 DEFINE_SVCXDRBUF_EVENT(recvfrom);
 DEFINE_SVCXDRBUF_EVENT(sendto);
+DEFINE_SVCXDRBUF_EVENT(authenticate);
 
 /*
  * from include/linux/sunrpc/svc.h
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index 998b196b6176..593df315b111 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -63,6 +63,7 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
 {
 	rpc_authflavor_t	flavor;
 	struct auth_ops		*aops;
+	int			ret;
 
 	*authp = rpc_auth_ok;
 
@@ -80,7 +81,9 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
 	init_svc_cred(&rqstp->rq_cred);
 
 	rqstp->rq_authop = aops;
-	return aops->accept(rqstp, authp);
+	ret = aops->accept(rqstp, authp);
+	trace_svc_xdr_authenticate(rqstp, &rqstp->rq_arg);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(svc_authenticate);
 



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

* [PATCH v2 06/27] lockd: Replace PROC() macro with open code
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (4 preceding siblings ...)
  2020-09-21 18:11 ` [PATCH v2 05/27] SUNRPC: Add svc_xdr_authenticate tracepoint Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 07/27] NFSACL: " Chuck Lever
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Clean up: Follow-up on ten-year-old commit b9081d90f5b9 ("NFS: kill
off complicated macro 'PROC'") by performing the same conversion in
the lockd code. To reduce the chance of error, I copied the original
C preprocessor output and then made some minor edits.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/lockd/svc4proc.c |  242 ++++++++++++++++++++++++++++++++++++++++-----------
 fs/lockd/svcproc.c  |  244 ++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 386 insertions(+), 100 deletions(-)

diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index e4d3f783e06a..77a00c105b03 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -491,60 +491,204 @@ nlm4svc_proc_granted_res(struct svc_rqst *rqstp)
  * NLM Server procedures.
  */
 
-#define nlm4svc_encode_norep	nlm4svc_encode_void
-#define nlm4svc_decode_norep	nlm4svc_decode_void
-#define nlm4svc_decode_testres	nlm4svc_decode_void
-#define nlm4svc_decode_lockres	nlm4svc_decode_void
-#define nlm4svc_decode_unlockres	nlm4svc_decode_void
-#define nlm4svc_decode_cancelres	nlm4svc_decode_void
-#define nlm4svc_decode_grantedres	nlm4svc_decode_void
-
-#define nlm4svc_proc_none	nlm4svc_proc_null
-#define nlm4svc_proc_test_res	nlm4svc_proc_null
-#define nlm4svc_proc_lock_res	nlm4svc_proc_null
-#define nlm4svc_proc_cancel_res	nlm4svc_proc_null
-#define nlm4svc_proc_unlock_res	nlm4svc_proc_null
-
 struct nlm_void			{ int dummy; };
 
-#define PROC(name, xargt, xrest, argt, rest, respsize)	\
- { .pc_func	= nlm4svc_proc_##name,	\
-   .pc_decode	= nlm4svc_decode_##xargt,	\
-   .pc_encode	= nlm4svc_encode_##xrest,	\
-   .pc_release	= NULL,					\
-   .pc_argsize	= sizeof(struct nlm_##argt),		\
-   .pc_ressize	= sizeof(struct nlm_##rest),		\
-   .pc_xdrressize = respsize,				\
- }
 #define	Ck	(1+XDR_QUADLEN(NLM_MAXCOOKIELEN))	/* cookie */
 #define	No	(1+1024/4)				/* netobj */
 #define	St	1					/* status */
 #define	Rg	4					/* range (offset + length) */
-const struct svc_procedure nlmsvc_procedures4[] = {
-  PROC(null,		void,		void,		void,	void, 1),
-  PROC(test,		testargs,	testres,	args,	res, Ck+St+2+No+Rg),
-  PROC(lock,		lockargs,	res,		args,	res, Ck+St),
-  PROC(cancel,		cancargs,	res,		args,	res, Ck+St),
-  PROC(unlock,		unlockargs,	res,		args,	res, Ck+St),
-  PROC(granted,		testargs,	res,		args,	res, Ck+St),
-  PROC(test_msg,	testargs,	norep,		args,	void, 1),
-  PROC(lock_msg,	lockargs,	norep,		args,	void, 1),
-  PROC(cancel_msg,	cancargs,	norep,		args,	void, 1),
-  PROC(unlock_msg,	unlockargs,	norep,		args,	void, 1),
-  PROC(granted_msg,	testargs,	norep,		args,	void, 1),
-  PROC(test_res,	testres,	norep,		res,	void, 1),
-  PROC(lock_res,	lockres,	norep,		res,	void, 1),
-  PROC(cancel_res,	cancelres,	norep,		res,	void, 1),
-  PROC(unlock_res,	unlockres,	norep,		res,	void, 1),
-  PROC(granted_res,	res,		norep,		res,	void, 1),
-  /* statd callback */
-  PROC(sm_notify,	reboot,		void,		reboot,	void, 1),
-  PROC(none,		void,		void,		void,	void, 0),
-  PROC(none,		void,		void,		void,	void, 0),
-  PROC(none,		void,		void,		void,	void, 0),
-  PROC(share,		shareargs,	shareres,	args,	res, Ck+St+1),
-  PROC(unshare,		shareargs,	shareres,	args,	res, Ck+St+1),
-  PROC(nm_lock,		lockargs,	res,		args,	res, Ck+St),
-  PROC(free_all,	notify,		void,		args,	void, 1),
 
+const struct svc_procedure nlmsvc_procedures4[24] = {
+	[NLMPROC_NULL] = {
+		.pc_func = nlm4svc_proc_null,
+		.pc_decode = nlm4svc_decode_void,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_void),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_TEST] = {
+		.pc_func = nlm4svc_proc_test,
+		.pc_decode = nlm4svc_decode_testargs,
+		.pc_encode = nlm4svc_encode_testres,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St+2+No+Rg,
+	},
+	[NLMPROC_LOCK] = {
+		.pc_func = nlm4svc_proc_lock,
+		.pc_decode = nlm4svc_decode_lockargs,
+		.pc_encode = nlm4svc_encode_res,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St,
+	},
+	[NLMPROC_CANCEL] = {
+		.pc_func = nlm4svc_proc_cancel,
+		.pc_decode = nlm4svc_decode_cancargs,
+		.pc_encode = nlm4svc_encode_res,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St,
+	},
+	[NLMPROC_UNLOCK] = {
+		.pc_func = nlm4svc_proc_unlock,
+		.pc_decode = nlm4svc_decode_unlockargs,
+		.pc_encode = nlm4svc_encode_res,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St,
+	},
+	[NLMPROC_GRANTED] = {
+		.pc_func = nlm4svc_proc_granted,
+		.pc_decode = nlm4svc_decode_testargs,
+		.pc_encode = nlm4svc_encode_res,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St,
+	},
+	[NLMPROC_TEST_MSG] = {
+		.pc_func = nlm4svc_proc_test_msg,
+		.pc_decode = nlm4svc_decode_testargs,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_LOCK_MSG] = {
+		.pc_func = nlm4svc_proc_lock_msg,
+		.pc_decode = nlm4svc_decode_lockargs,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_CANCEL_MSG] = {
+		.pc_func = nlm4svc_proc_cancel_msg,
+		.pc_decode = nlm4svc_decode_cancargs,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_UNLOCK_MSG] = {
+		.pc_func = nlm4svc_proc_unlock_msg,
+		.pc_decode = nlm4svc_decode_unlockargs,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_GRANTED_MSG] = {
+		.pc_func = nlm4svc_proc_granted_msg,
+		.pc_decode = nlm4svc_decode_testargs,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_TEST_RES] = {
+		.pc_func = nlm4svc_proc_null,
+		.pc_decode = nlm4svc_decode_void,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_res),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_LOCK_RES] = {
+		.pc_func = nlm4svc_proc_null,
+		.pc_decode = nlm4svc_decode_void,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_res),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_CANCEL_RES] = {
+		.pc_func = nlm4svc_proc_null,
+		.pc_decode = nlm4svc_decode_void,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_res),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_UNLOCK_RES] = {
+		.pc_func = nlm4svc_proc_null,
+		.pc_decode = nlm4svc_decode_void,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_res),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_GRANTED_RES] = {
+		.pc_func = nlm4svc_proc_granted_res,
+		.pc_decode = nlm4svc_decode_res,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_res),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_NSM_NOTIFY] = {
+		.pc_func = nlm4svc_proc_sm_notify,
+		.pc_decode = nlm4svc_decode_reboot,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_reboot),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[ 17 /* unused procedure */ ] = {
+		.pc_func = nlm4svc_proc_null,
+		.pc_decode = nlm4svc_decode_void,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_void),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = 0,
+	},
+	[ 18 /* unused procedure */ ] = {
+		.pc_func = nlm4svc_proc_null,
+		.pc_decode = nlm4svc_decode_void,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_void),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = 0,
+	},
+	[ 19 /* unused procedure */ ] = {
+		.pc_func = nlm4svc_proc_null,
+		.pc_decode = nlm4svc_decode_void,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_void),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = 0,
+	},
+	[NLMPROC_SHARE] = {
+		.pc_func = nlm4svc_proc_share,
+		.pc_decode = nlm4svc_decode_shareargs,
+		.pc_encode = nlm4svc_encode_shareres,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St+1,
+	},
+	[NLMPROC_UNSHARE] = {
+		.pc_func = nlm4svc_proc_unshare,
+		.pc_decode = nlm4svc_decode_shareargs,
+		.pc_encode = nlm4svc_encode_shareres,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St+1,
+	},
+	[NLMPROC_NM_LOCK] = {
+		.pc_func = nlm4svc_proc_nm_lock,
+		.pc_decode = nlm4svc_decode_lockargs,
+		.pc_encode = nlm4svc_encode_res,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St,
+	},
+	[NLMPROC_FREE_ALL] = {
+		.pc_func = nlm4svc_proc_free_all,
+		.pc_decode = nlm4svc_decode_notify,
+		.pc_encode = nlm4svc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
 };
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index d0bb7a6bf005..9b369e377f40 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -533,62 +533,204 @@ nlmsvc_proc_granted_res(struct svc_rqst *rqstp)
  * NLM Server procedures.
  */
 
-#define nlmsvc_encode_norep	nlmsvc_encode_void
-#define nlmsvc_decode_norep	nlmsvc_decode_void
-#define nlmsvc_decode_testres	nlmsvc_decode_void
-#define nlmsvc_decode_lockres	nlmsvc_decode_void
-#define nlmsvc_decode_unlockres	nlmsvc_decode_void
-#define nlmsvc_decode_cancelres	nlmsvc_decode_void
-#define nlmsvc_decode_grantedres	nlmsvc_decode_void
-
-#define nlmsvc_proc_none	nlmsvc_proc_null
-#define nlmsvc_proc_test_res	nlmsvc_proc_null
-#define nlmsvc_proc_lock_res	nlmsvc_proc_null
-#define nlmsvc_proc_cancel_res	nlmsvc_proc_null
-#define nlmsvc_proc_unlock_res	nlmsvc_proc_null
-
 struct nlm_void			{ int dummy; };
 
-#define PROC(name, xargt, xrest, argt, rest, respsize)	\
- { .pc_func	= nlmsvc_proc_##name,			\
-   .pc_decode	= nlmsvc_decode_##xargt,		\
-   .pc_encode	= nlmsvc_encode_##xrest,		\
-   .pc_release	= NULL,					\
-   .pc_argsize	= sizeof(struct nlm_##argt),		\
-   .pc_ressize	= sizeof(struct nlm_##rest),		\
-   .pc_xdrressize = respsize,				\
- }
-
 #define	Ck	(1+XDR_QUADLEN(NLM_MAXCOOKIELEN))	/* cookie */
 #define	St	1				/* status */
 #define	No	(1+1024/4)			/* Net Obj */
 #define	Rg	2				/* range - offset + size */
 
-const struct svc_procedure nlmsvc_procedures[] = {
-  PROC(null,		void,		void,		void,	void, 1),
-  PROC(test,		testargs,	testres,	args,	res, Ck+St+2+No+Rg),
-  PROC(lock,		lockargs,	res,		args,	res, Ck+St),
-  PROC(cancel,		cancargs,	res,		args,	res, Ck+St),
-  PROC(unlock,		unlockargs,	res,		args,	res, Ck+St),
-  PROC(granted,		testargs,	res,		args,	res, Ck+St),
-  PROC(test_msg,	testargs,	norep,		args,	void, 1),
-  PROC(lock_msg,	lockargs,	norep,		args,	void, 1),
-  PROC(cancel_msg,	cancargs,	norep,		args,	void, 1),
-  PROC(unlock_msg,	unlockargs,	norep,		args,	void, 1),
-  PROC(granted_msg,	testargs,	norep,		args,	void, 1),
-  PROC(test_res,	testres,	norep,		res,	void, 1),
-  PROC(lock_res,	lockres,	norep,		res,	void, 1),
-  PROC(cancel_res,	cancelres,	norep,		res,	void, 1),
-  PROC(unlock_res,	unlockres,	norep,		res,	void, 1),
-  PROC(granted_res,	res,		norep,		res,	void, 1),
-  /* statd callback */
-  PROC(sm_notify,	reboot,		void,		reboot,	void, 1),
-  PROC(none,		void,		void,		void,	void, 1),
-  PROC(none,		void,		void,		void,	void, 1),
-  PROC(none,		void,		void,		void,	void, 1),
-  PROC(share,		shareargs,	shareres,	args,	res, Ck+St+1),
-  PROC(unshare,		shareargs,	shareres,	args,	res, Ck+St+1),
-  PROC(nm_lock,		lockargs,	res,		args,	res, Ck+St),
-  PROC(free_all,	notify,		void,		args,	void, 0),
-
+const struct svc_procedure nlmsvc_procedures[24] = {
+	[NLMPROC_NULL] = {
+		.pc_func = nlmsvc_proc_null,
+		.pc_decode = nlmsvc_decode_void,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_void),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_TEST] = {
+		.pc_func = nlmsvc_proc_test,
+		.pc_decode = nlmsvc_decode_testargs,
+		.pc_encode = nlmsvc_encode_testres,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St+2+No+Rg,
+	},
+	[NLMPROC_LOCK] = {
+		.pc_func = nlmsvc_proc_lock,
+		.pc_decode = nlmsvc_decode_lockargs,
+		.pc_encode = nlmsvc_encode_res,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St,
+	},
+	[NLMPROC_CANCEL] = {
+		.pc_func = nlmsvc_proc_cancel,
+		.pc_decode = nlmsvc_decode_cancargs,
+		.pc_encode = nlmsvc_encode_res,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St,
+	},
+	[NLMPROC_UNLOCK] = {
+		.pc_func = nlmsvc_proc_unlock,
+		.pc_decode = nlmsvc_decode_unlockargs,
+		.pc_encode = nlmsvc_encode_res,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St,
+	},
+	[NLMPROC_GRANTED] = {
+		.pc_func = nlmsvc_proc_granted,
+		.pc_decode = nlmsvc_decode_testargs,
+		.pc_encode = nlmsvc_encode_res,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St,
+	},
+	[NLMPROC_TEST_MSG] = {
+		.pc_func = nlmsvc_proc_test_msg,
+		.pc_decode = nlmsvc_decode_testargs,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_LOCK_MSG] = {
+		.pc_func = nlmsvc_proc_lock_msg,
+		.pc_decode = nlmsvc_decode_lockargs,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_CANCEL_MSG] = {
+		.pc_func = nlmsvc_proc_cancel_msg,
+		.pc_decode = nlmsvc_decode_cancargs,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_UNLOCK_MSG] = {
+		.pc_func = nlmsvc_proc_unlock_msg,
+		.pc_decode = nlmsvc_decode_unlockargs,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_GRANTED_MSG] = {
+		.pc_func = nlmsvc_proc_granted_msg,
+		.pc_decode = nlmsvc_decode_testargs,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_TEST_RES] = {
+		.pc_func = nlmsvc_proc_null,
+		.pc_decode = nlmsvc_decode_void,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_res),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_LOCK_RES] = {
+		.pc_func = nlmsvc_proc_null,
+		.pc_decode = nlmsvc_decode_void,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_res),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_CANCEL_RES] = {
+		.pc_func = nlmsvc_proc_null,
+		.pc_decode = nlmsvc_decode_void,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_res),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_UNLOCK_RES] = {
+		.pc_func = nlmsvc_proc_null,
+		.pc_decode = nlmsvc_decode_void,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_res),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_GRANTED_RES] = {
+		.pc_func = nlmsvc_proc_granted_res,
+		.pc_decode = nlmsvc_decode_res,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_res),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_NSM_NOTIFY] = {
+		.pc_func = nlmsvc_proc_sm_notify,
+		.pc_decode = nlmsvc_decode_reboot,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_reboot),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[ 17 /* unused procedure */ ] = {
+		.pc_func = nlmsvc_proc_null,
+		.pc_decode = nlmsvc_decode_void,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_void),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[ 18 /* unused procedure */ ] = {
+		.pc_func = nlmsvc_proc_null,
+		.pc_decode = nlmsvc_decode_void,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_void),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[ 19 /* unused procedure */ ] = {
+		.pc_func = nlmsvc_proc_null,
+		.pc_decode = nlmsvc_decode_void,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_void),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = St,
+	},
+	[NLMPROC_SHARE] = {
+		.pc_func = nlmsvc_proc_share,
+		.pc_decode = nlmsvc_decode_shareargs,
+		.pc_encode = nlmsvc_encode_shareres,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St+1,
+	},
+	[NLMPROC_UNSHARE] = {
+		.pc_func = nlmsvc_proc_unshare,
+		.pc_decode = nlmsvc_decode_shareargs,
+		.pc_encode = nlmsvc_encode_shareres,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St+1,
+	},
+	[NLMPROC_NM_LOCK] = {
+		.pc_func = nlmsvc_proc_nm_lock,
+		.pc_decode = nlmsvc_decode_lockargs,
+		.pc_encode = nlmsvc_encode_res,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_res),
+		.pc_xdrressize = Ck+St,
+	},
+	[NLMPROC_FREE_ALL] = {
+		.pc_func = nlmsvc_proc_free_all,
+		.pc_decode = nlmsvc_decode_notify,
+		.pc_encode = nlmsvc_encode_void,
+		.pc_argsize = sizeof(struct nlm_args),
+		.pc_ressize = sizeof(struct nlm_void),
+		.pc_xdrressize = 0,
+	},
 };



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

* [PATCH v2 07/27] NFSACL: Replace PROC() macro with open code
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (5 preceding siblings ...)
  2020-09-21 18:11 ` [PATCH v2 06/27] lockd: Replace PROC() macro with open code Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 08/27] SUNRPC: Make trace_svc_process() display the RPC procedure symbolically Chuck Lever
                   ` (20 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Clean up: Follow-up on ten-year-old commit b9081d90f5b9 ("NFS: kill
off complicated macro 'PROC'") by performing the same conversion in
the NFSACL code. To reduce the chance of error, I copied the original
C preprocessor output and then made some minor edits.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs2acl.c           |   72 +++++++++++++++++++++++++++++--------------
 fs/nfsd/nfs3acl.c           |   49 +++++++++++++++++------------
 include/uapi/linux/nfsacl.h |    2 +
 3 files changed, 80 insertions(+), 43 deletions(-)

diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index cbab1d2d8a75..8d20e0d74417 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -347,36 +347,62 @@ static void nfsaclsvc_release_access(struct svc_rqst *rqstp)
 	fh_put(&resp->fh);
 }
 
-#define nfsaclsvc_decode_voidargs	NULL
-#define nfsaclsvc_release_void		NULL
-#define nfsd3_fhandleargs	nfsd_fhandle
-#define nfsd3_attrstatres	nfsd_attrstat
-#define nfsd3_voidres		nfsd3_voidargs
 struct nfsd3_voidargs { int dummy; };
 
-#define PROC(name, argt, rest, relt, cache, respsize)			\
-{									\
-	.pc_func	= nfsacld_proc_##name,				\
-	.pc_decode	= nfsaclsvc_decode_##argt##args,		\
-	.pc_encode	= nfsaclsvc_encode_##rest##res,			\
-	.pc_release	= nfsaclsvc_release_##relt,	\
-	.pc_argsize	= sizeof(struct nfsd3_##argt##args),		\
-	.pc_ressize	= sizeof(struct nfsd3_##rest##res),		\
-	.pc_cachetype	= cache,					\
-	.pc_xdrressize	= respsize,					\
-}
-
 #define ST 1		/* status*/
 #define AT 21		/* attributes */
 #define pAT (1+AT)	/* post attributes - conditional */
 #define ACL (1+NFS_ACL_MAX_ENTRIES*3)  /* Access Control List */
 
-static const struct svc_procedure nfsd_acl_procedures2[] = {
-  PROC(null,	void,		void,		void,	  RC_NOCACHE, ST),
-  PROC(getacl,	getacl,		getacl,		getacl,	  RC_NOCACHE, ST+1+2*(1+ACL)),
-  PROC(setacl,	setacl,		attrstat,	attrstat, RC_NOCACHE, ST+AT),
-  PROC(getattr, fhandle,	attrstat,	attrstat, RC_NOCACHE, ST+AT),
-  PROC(access,	access,		access,		access,   RC_NOCACHE, ST+AT+1),
+static const struct svc_procedure nfsd_acl_procedures2[5] = {
+	[ACLPROC2_NULL] = {
+		.pc_func = nfsacld_proc_null,
+		.pc_encode = nfsaclsvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd3_voidargs),
+		.pc_ressize = sizeof(struct nfsd3_voidargs),
+		.pc_cachetype = RC_NOCACHE,
+		.pc_xdrressize = ST,
+	},
+	[ACLPROC2_GETACL] = {
+		.pc_func = nfsacld_proc_getacl,
+		.pc_decode = nfsaclsvc_decode_getaclargs,
+		.pc_encode = nfsaclsvc_encode_getaclres,
+		.pc_release = nfsaclsvc_release_getacl,
+		.pc_argsize = sizeof(struct nfsd3_getaclargs),
+		.pc_ressize = sizeof(struct nfsd3_getaclres),
+		.pc_cachetype = RC_NOCACHE,
+		.pc_xdrressize = ST+1+2*(1+ACL),
+	},
+	[ACLPROC2_SETACL] = {
+		.pc_func = nfsacld_proc_setacl,
+		.pc_decode = nfsaclsvc_decode_setaclargs,
+		.pc_encode = nfsaclsvc_encode_attrstatres,
+		.pc_release = nfsaclsvc_release_attrstat,
+		.pc_argsize = sizeof(struct nfsd3_setaclargs),
+		.pc_ressize = sizeof(struct nfsd_attrstat),
+		.pc_cachetype = RC_NOCACHE,
+		.pc_xdrressize = ST+AT,
+	},
+	[ACLPROC2_GETATTR] = {
+		.pc_func = nfsacld_proc_getattr,
+		.pc_decode = nfsaclsvc_decode_fhandleargs,
+		.pc_encode = nfsaclsvc_encode_attrstatres,
+		.pc_release = nfsaclsvc_release_attrstat,
+		.pc_argsize = sizeof(struct nfsd_fhandle),
+		.pc_ressize = sizeof(struct nfsd_attrstat),
+		.pc_cachetype = RC_NOCACHE,
+		.pc_xdrressize = ST+AT,
+	},
+	[ACLPROC2_ACCESS] = {
+		.pc_func = nfsacld_proc_access,
+		.pc_decode = nfsaclsvc_decode_accessargs,
+		.pc_encode = nfsaclsvc_encode_accessres,
+		.pc_release = nfsaclsvc_release_access,
+		.pc_argsize = sizeof(struct nfsd3_accessargs),
+		.pc_ressize = sizeof(struct nfsd3_accessres),
+		.pc_cachetype = RC_NOCACHE,
+		.pc_xdrressize = ST+AT+1,
+	},
 };
 
 static unsigned int nfsd_acl_count2[ARRAY_SIZE(nfsd_acl_procedures2)];
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index 13bca4a2f89d..292acb2e529c 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -235,33 +235,42 @@ static void nfs3svc_release_getacl(struct svc_rqst *rqstp)
 	posix_acl_release(resp->acl_default);
 }
 
-#define nfs3svc_decode_voidargs		NULL
-#define nfs3svc_release_void		NULL
-#define nfsd3_setaclres			nfsd3_attrstat
-#define nfsd3_voidres			nfsd3_voidargs
 struct nfsd3_voidargs { int dummy; };
 
-#define PROC(name, argt, rest, relt, cache, respsize)			\
-{									\
-	.pc_func	= nfsd3_proc_##name,				\
-	.pc_decode	= nfs3svc_decode_##argt##args,			\
-	.pc_encode	= nfs3svc_encode_##rest##res,			\
-	.pc_release	= nfs3svc_release_##relt,			\
-	.pc_argsize	= sizeof(struct nfsd3_##argt##args),		\
-	.pc_ressize	= sizeof(struct nfsd3_##rest##res),		\
-	.pc_cachetype	= cache,					\
-	.pc_xdrressize	= respsize,					\
-}
-
 #define ST 1		/* status*/
 #define AT 21		/* attributes */
 #define pAT (1+AT)	/* post attributes - conditional */
 #define ACL (1+NFS_ACL_MAX_ENTRIES*3)  /* Access Control List */
 
-static const struct svc_procedure nfsd_acl_procedures3[] = {
-  PROC(null,	void,		void,		void,	  RC_NOCACHE, ST),
-  PROC(getacl,	getacl,		getacl,		getacl,	  RC_NOCACHE, ST+1+2*(1+ACL)),
-  PROC(setacl,	setacl,		setacl,		fhandle,  RC_NOCACHE, ST+pAT),
+static const struct svc_procedure nfsd_acl_procedures3[3] = {
+	[ACLPROC3_NULL] = {
+		.pc_func = nfsd3_proc_null,
+		.pc_encode = nfs3svc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd3_voidargs),
+		.pc_ressize = sizeof(struct nfsd3_voidargs),
+		.pc_cachetype = RC_NOCACHE,
+		.pc_xdrressize = ST,
+	},
+	[ACLPROC3_GETACL] = {
+		.pc_func = nfsd3_proc_getacl,
+		.pc_decode = nfs3svc_decode_getaclargs,
+		.pc_encode = nfs3svc_encode_getaclres,
+		.pc_release = nfs3svc_release_getacl,
+		.pc_argsize = sizeof(struct nfsd3_getaclargs),
+		.pc_ressize = sizeof(struct nfsd3_getaclres),
+		.pc_cachetype = RC_NOCACHE,
+		.pc_xdrressize = ST+1+2*(1+ACL),
+	},
+	[ACLPROC3_SETACL] = {
+		.pc_func = nfsd3_proc_setacl,
+		.pc_decode = nfs3svc_decode_setaclargs,
+		.pc_encode = nfs3svc_encode_setaclres,
+		.pc_release = nfs3svc_release_fhandle,
+		.pc_argsize = sizeof(struct nfsd3_setaclargs),
+		.pc_ressize = sizeof(struct nfsd3_attrstat),
+		.pc_cachetype = RC_NOCACHE,
+		.pc_xdrressize = ST+pAT,
+	},
 };
 
 static unsigned int nfsd_acl_count3[ARRAY_SIZE(nfsd_acl_procedures3)];
diff --git a/include/uapi/linux/nfsacl.h b/include/uapi/linux/nfsacl.h
index ca9a8501ff30..2c2ad204d3b0 100644
--- a/include/uapi/linux/nfsacl.h
+++ b/include/uapi/linux/nfsacl.h
@@ -9,11 +9,13 @@
 
 #define NFS_ACL_PROGRAM	100227
 
+#define ACLPROC2_NULL		0
 #define ACLPROC2_GETACL		1
 #define ACLPROC2_SETACL		2
 #define ACLPROC2_GETATTR	3
 #define ACLPROC2_ACCESS		4
 
+#define ACLPROC3_NULL		0
 #define ACLPROC3_GETACL		1
 #define ACLPROC3_SETACL		2
 



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

* [PATCH v2 08/27] SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (6 preceding siblings ...)
  2020-09-21 18:11 ` [PATCH v2 07/27] NFSACL: " Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 09/27] NFSD: Clean up the show_nf_may macro Chuck Lever
                   ` (19 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

A long-requested feature to help make RPC trace logs more human-
readable.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/lockd/svc4proc.c           |   21 +++++++++++++++++++++
 fs/lockd/svcproc.c            |   21 +++++++++++++++++++++
 fs/nfs/callback_xdr.c         |    2 ++
 fs/nfsd/nfs2acl.c             |    5 +++++
 fs/nfsd/nfs3acl.c             |    3 +++
 fs/nfsd/nfs3proc.c            |   22 ++++++++++++++++++++++
 fs/nfsd/nfs4proc.c            |    2 ++
 fs/nfsd/nfsproc.c             |   18 ++++++++++++++++++
 include/linux/sunrpc/svc.h    |    1 +
 include/trace/events/sunrpc.h |    8 ++++++--
 10 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 77a00c105b03..ea761a8a0844 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -506,6 +506,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_void),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "NULL",
 	},
 	[NLMPROC_TEST] = {
 		.pc_func = nlm4svc_proc_test,
@@ -514,6 +515,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+2+No+Rg,
+		.pc_name = "TEST",
 	},
 	[NLMPROC_LOCK] = {
 		.pc_func = nlm4svc_proc_lock,
@@ -522,6 +524,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "LOCK",
 	},
 	[NLMPROC_CANCEL] = {
 		.pc_func = nlm4svc_proc_cancel,
@@ -530,6 +533,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "CANCEL",
 	},
 	[NLMPROC_UNLOCK] = {
 		.pc_func = nlm4svc_proc_unlock,
@@ -538,6 +542,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "UNLOCK",
 	},
 	[NLMPROC_GRANTED] = {
 		.pc_func = nlm4svc_proc_granted,
@@ -546,6 +551,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "GRANTED",
 	},
 	[NLMPROC_TEST_MSG] = {
 		.pc_func = nlm4svc_proc_test_msg,
@@ -554,6 +560,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "TEST_MSG",
 	},
 	[NLMPROC_LOCK_MSG] = {
 		.pc_func = nlm4svc_proc_lock_msg,
@@ -562,6 +569,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "LOCK_MSG",
 	},
 	[NLMPROC_CANCEL_MSG] = {
 		.pc_func = nlm4svc_proc_cancel_msg,
@@ -570,6 +578,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "CANCEL_MSG",
 	},
 	[NLMPROC_UNLOCK_MSG] = {
 		.pc_func = nlm4svc_proc_unlock_msg,
@@ -578,6 +587,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "UNLOCK_MSG",
 	},
 	[NLMPROC_GRANTED_MSG] = {
 		.pc_func = nlm4svc_proc_granted_msg,
@@ -586,6 +596,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "GRANTED_MSG",
 	},
 	[NLMPROC_TEST_RES] = {
 		.pc_func = nlm4svc_proc_null,
@@ -594,6 +605,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "TEST_RES",
 	},
 	[NLMPROC_LOCK_RES] = {
 		.pc_func = nlm4svc_proc_null,
@@ -602,6 +614,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "LOCK_RES",
 	},
 	[NLMPROC_CANCEL_RES] = {
 		.pc_func = nlm4svc_proc_null,
@@ -610,6 +623,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "CANCEL_RES",
 	},
 	[NLMPROC_UNLOCK_RES] = {
 		.pc_func = nlm4svc_proc_null,
@@ -618,6 +632,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "UNLOCK_RES",
 	},
 	[NLMPROC_GRANTED_RES] = {
 		.pc_func = nlm4svc_proc_granted_res,
@@ -626,6 +641,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "GRANTED_RES",
 	},
 	[NLMPROC_NSM_NOTIFY] = {
 		.pc_func = nlm4svc_proc_sm_notify,
@@ -634,6 +650,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_reboot),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "SM_NOTIFY",
 	},
 	[ 17 /* unused procedure */ ] = {
 		.pc_func = nlm4svc_proc_null,
@@ -666,6 +683,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+1,
+		.pc_name = "SHARE",
 	},
 	[NLMPROC_UNSHARE] = {
 		.pc_func = nlm4svc_proc_unshare,
@@ -674,6 +692,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+1,
+		.pc_name = "UNSHARE",
 	},
 	[NLMPROC_NM_LOCK] = {
 		.pc_func = nlm4svc_proc_nm_lock,
@@ -682,6 +701,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "NM_LOCK",
 	},
 	[NLMPROC_FREE_ALL] = {
 		.pc_func = nlm4svc_proc_free_all,
@@ -690,5 +710,6 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "FREE_ALL",
 	},
 };
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 9b369e377f40..c9c83aeb831c 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -548,6 +548,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_void),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "NULL",
 	},
 	[NLMPROC_TEST] = {
 		.pc_func = nlmsvc_proc_test,
@@ -556,6 +557,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+2+No+Rg,
+		.pc_name = "TEST",
 	},
 	[NLMPROC_LOCK] = {
 		.pc_func = nlmsvc_proc_lock,
@@ -564,6 +566,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "LOCK",
 	},
 	[NLMPROC_CANCEL] = {
 		.pc_func = nlmsvc_proc_cancel,
@@ -572,6 +575,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "CANCEL",
 	},
 	[NLMPROC_UNLOCK] = {
 		.pc_func = nlmsvc_proc_unlock,
@@ -580,6 +584,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "UNLOCK",
 	},
 	[NLMPROC_GRANTED] = {
 		.pc_func = nlmsvc_proc_granted,
@@ -588,6 +593,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "GRANTED",
 	},
 	[NLMPROC_TEST_MSG] = {
 		.pc_func = nlmsvc_proc_test_msg,
@@ -596,6 +602,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "TEST_MSG",
 	},
 	[NLMPROC_LOCK_MSG] = {
 		.pc_func = nlmsvc_proc_lock_msg,
@@ -604,6 +611,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "LOCK_MSG",
 	},
 	[NLMPROC_CANCEL_MSG] = {
 		.pc_func = nlmsvc_proc_cancel_msg,
@@ -612,6 +620,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "CANCEL_MSG",
 	},
 	[NLMPROC_UNLOCK_MSG] = {
 		.pc_func = nlmsvc_proc_unlock_msg,
@@ -620,6 +629,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "UNLOCK_MSG",
 	},
 	[NLMPROC_GRANTED_MSG] = {
 		.pc_func = nlmsvc_proc_granted_msg,
@@ -628,6 +638,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "GRANTED_MSG",
 	},
 	[NLMPROC_TEST_RES] = {
 		.pc_func = nlmsvc_proc_null,
@@ -636,6 +647,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "TEST_RES",
 	},
 	[NLMPROC_LOCK_RES] = {
 		.pc_func = nlmsvc_proc_null,
@@ -644,6 +656,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "LOCK_RES",
 	},
 	[NLMPROC_CANCEL_RES] = {
 		.pc_func = nlmsvc_proc_null,
@@ -652,6 +665,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "CANCEL_RES",
 	},
 	[NLMPROC_UNLOCK_RES] = {
 		.pc_func = nlmsvc_proc_null,
@@ -660,6 +674,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "UNLOCK_RES",
 	},
 	[NLMPROC_GRANTED_RES] = {
 		.pc_func = nlmsvc_proc_granted_res,
@@ -668,6 +683,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "GRANTED_RES",
 	},
 	[NLMPROC_NSM_NOTIFY] = {
 		.pc_func = nlmsvc_proc_sm_notify,
@@ -676,6 +692,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_reboot),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "SM_NOTIFY",
 	},
 	[ 17 /* unused procedure */ ] = {
 		.pc_func = nlmsvc_proc_null,
@@ -708,6 +725,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+1,
+		.pc_name = "SHARE",
 	},
 	[NLMPROC_UNSHARE] = {
 		.pc_func = nlmsvc_proc_unshare,
@@ -716,6 +734,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+1,
+		.pc_name = "UNSHARE",
 	},
 	[NLMPROC_NM_LOCK] = {
 		.pc_func = nlmsvc_proc_nm_lock,
@@ -724,6 +743,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "NM_LOCK",
 	},
 	[NLMPROC_FREE_ALL] = {
 		.pc_func = nlmsvc_proc_free_all,
@@ -732,5 +752,6 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = 0,
+		.pc_name = "FREE_ALL",
 	},
 };
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 79ff172eb1c8..c5348ba81129 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -1060,6 +1060,7 @@ static const struct svc_procedure nfs4_callback_procedures1[] = {
 		.pc_decode = nfs4_decode_void,
 		.pc_encode = nfs4_encode_void,
 		.pc_xdrressize = 1,
+		.pc_name = "NULL",
 	},
 	[CB_COMPOUND] = {
 		.pc_func = nfs4_callback_compound,
@@ -1067,6 +1068,7 @@ static const struct svc_procedure nfs4_callback_procedures1[] = {
 		.pc_argsize = 256,
 		.pc_ressize = 256,
 		.pc_xdrressize = NFS4_CALLBACK_BUFSIZE,
+		.pc_name = "COMPOUND",
 	}
 };
 
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 8d20e0d74417..54e597918822 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -362,6 +362,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 		.pc_ressize = sizeof(struct nfsd3_voidargs),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
+		.pc_name = "NULL",
 	},
 	[ACLPROC2_GETACL] = {
 		.pc_func = nfsacld_proc_getacl,
@@ -372,6 +373,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 		.pc_ressize = sizeof(struct nfsd3_getaclres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+1+2*(1+ACL),
+		.pc_name = "GETACL",
 	},
 	[ACLPROC2_SETACL] = {
 		.pc_func = nfsacld_proc_setacl,
@@ -382,6 +384,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 		.pc_ressize = sizeof(struct nfsd_attrstat),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "SETACL",
 	},
 	[ACLPROC2_GETATTR] = {
 		.pc_func = nfsacld_proc_getattr,
@@ -392,6 +395,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 		.pc_ressize = sizeof(struct nfsd_attrstat),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "GETATTR",
 	},
 	[ACLPROC2_ACCESS] = {
 		.pc_func = nfsacld_proc_access,
@@ -402,6 +406,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 		.pc_ressize = sizeof(struct nfsd3_accessres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT+1,
+		.pc_name = "SETATTR",
 	},
 };
 
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index 292acb2e529c..7f512dec7460 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -250,6 +250,7 @@ static const struct svc_procedure nfsd_acl_procedures3[3] = {
 		.pc_ressize = sizeof(struct nfsd3_voidargs),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
+		.pc_name = "NULL",
 	},
 	[ACLPROC3_GETACL] = {
 		.pc_func = nfsd3_proc_getacl,
@@ -260,6 +261,7 @@ static const struct svc_procedure nfsd_acl_procedures3[3] = {
 		.pc_ressize = sizeof(struct nfsd3_getaclres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+1+2*(1+ACL),
+		.pc_name = "GETACL",
 	},
 	[ACLPROC3_SETACL] = {
 		.pc_func = nfsd3_proc_setacl,
@@ -270,6 +272,7 @@ static const struct svc_procedure nfsd_acl_procedures3[3] = {
 		.pc_ressize = sizeof(struct nfsd3_attrstat),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT,
+		.pc_name = "SETACL",
 	},
 };
 
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 288bc76b4574..02f6bb6d749e 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -721,6 +721,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
+		.pc_name = "NULL",
 	},
 	[NFS3PROC_GETATTR] = {
 		.pc_func = nfsd3_proc_getattr,
@@ -731,6 +732,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_attrstatres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "GETATTR",
 	},
 	[NFS3PROC_SETATTR] = {
 		.pc_func = nfsd3_proc_setattr,
@@ -741,6 +743,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_wccstatres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+WC,
+		.pc_name = "SETATTR",
 	},
 	[NFS3PROC_LOOKUP] = {
 		.pc_func = nfsd3_proc_lookup,
@@ -751,6 +754,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_diropres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+FH+pAT+pAT,
+		.pc_name = "LOOKUP",
 	},
 	[NFS3PROC_ACCESS] = {
 		.pc_func = nfsd3_proc_access,
@@ -761,6 +765,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_accessres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+1,
+		.pc_name = "ACCESS",
 	},
 	[NFS3PROC_READLINK] = {
 		.pc_func = nfsd3_proc_readlink,
@@ -771,6 +776,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_readlinkres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+1+NFS3_MAXPATHLEN/4,
+		.pc_name = "READLINK",
 	},
 	[NFS3PROC_READ] = {
 		.pc_func = nfsd3_proc_read,
@@ -781,6 +787,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_readres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+4+NFSSVC_MAXBLKSIZE/4,
+		.pc_name = "READ",
 	},
 	[NFS3PROC_WRITE] = {
 		.pc_func = nfsd3_proc_write,
@@ -791,6 +798,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_writeres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+WC+4,
+		.pc_name = "WRITE",
 	},
 	[NFS3PROC_CREATE] = {
 		.pc_func = nfsd3_proc_create,
@@ -801,6 +809,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_createres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+(1+FH+pAT)+WC,
+		.pc_name = "CREATE",
 	},
 	[NFS3PROC_MKDIR] = {
 		.pc_func = nfsd3_proc_mkdir,
@@ -811,6 +820,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_createres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+(1+FH+pAT)+WC,
+		.pc_name = "MKDIR",
 	},
 	[NFS3PROC_SYMLINK] = {
 		.pc_func = nfsd3_proc_symlink,
@@ -821,6 +831,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_createres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+(1+FH+pAT)+WC,
+		.pc_name = "SYMLINK",
 	},
 	[NFS3PROC_MKNOD] = {
 		.pc_func = nfsd3_proc_mknod,
@@ -831,6 +842,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_createres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+(1+FH+pAT)+WC,
+		.pc_name = "MKNOD",
 	},
 	[NFS3PROC_REMOVE] = {
 		.pc_func = nfsd3_proc_remove,
@@ -841,6 +853,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_wccstatres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+WC,
+		.pc_name = "REMOVE",
 	},
 	[NFS3PROC_RMDIR] = {
 		.pc_func = nfsd3_proc_rmdir,
@@ -851,6 +864,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_wccstatres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+WC,
+		.pc_name = "RMDIR",
 	},
 	[NFS3PROC_RENAME] = {
 		.pc_func = nfsd3_proc_rename,
@@ -861,6 +875,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_renameres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+WC+WC,
+		.pc_name = "RENAME",
 	},
 	[NFS3PROC_LINK] = {
 		.pc_func = nfsd3_proc_link,
@@ -871,6 +886,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_linkres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+pAT+WC,
+		.pc_name = "LINK",
 	},
 	[NFS3PROC_READDIR] = {
 		.pc_func = nfsd3_proc_readdir,
@@ -880,6 +896,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_argsize = sizeof(struct nfsd3_readdirargs),
 		.pc_ressize = sizeof(struct nfsd3_readdirres),
 		.pc_cachetype = RC_NOCACHE,
+		.pc_name = "READDIR",
 	},
 	[NFS3PROC_READDIRPLUS] = {
 		.pc_func = nfsd3_proc_readdirplus,
@@ -889,6 +906,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_argsize = sizeof(struct nfsd3_readdirplusargs),
 		.pc_ressize = sizeof(struct nfsd3_readdirres),
 		.pc_cachetype = RC_NOCACHE,
+		.pc_name = "READDIRPLUS",
 	},
 	[NFS3PROC_FSSTAT] = {
 		.pc_func = nfsd3_proc_fsstat,
@@ -898,6 +916,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_fsstatres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+2*6+1,
+		.pc_name = "FSSTAT",
 	},
 	[NFS3PROC_FSINFO] = {
 		.pc_func = nfsd3_proc_fsinfo,
@@ -907,6 +926,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_fsinfores),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+12,
+		.pc_name = "FSINFO",
 	},
 	[NFS3PROC_PATHCONF] = {
 		.pc_func = nfsd3_proc_pathconf,
@@ -916,6 +936,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_pathconfres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+6,
+		.pc_name = "PATHCONF",
 	},
 	[NFS3PROC_COMMIT] = {
 		.pc_func = nfsd3_proc_commit,
@@ -926,6 +947,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_commitres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+WC+2,
+		.pc_name = "COMMIT",
 	},
 };
 
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index eaf50eafa935..e89a51ed2bbf 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -3284,6 +3284,7 @@ static const struct svc_procedure nfsd_procedures4[2] = {
 		.pc_ressize = sizeof(struct nfsd4_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 1,
+		.pc_name = "NULL",
 	},
 	[NFSPROC4_COMPOUND] = {
 		.pc_func = nfsd4_proc_compound,
@@ -3294,6 +3295,7 @@ static const struct svc_procedure nfsd_procedures4[2] = {
 		.pc_release = nfsd4_release_compoundargs,
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = NFSD_BUFSIZE/4,
+		.pc_name = "COMPOUND",
 	},
 };
 
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 6e0b066480c5..fd78651bd21d 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -595,6 +595,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_void),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
+		.pc_name = "NULL",
 	},
 	[NFSPROC_GETATTR] = {
 		.pc_func = nfsd_proc_getattr,
@@ -605,6 +606,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_attrstat),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "GETATTR",
 	},
 	[NFSPROC_SETATTR] = {
 		.pc_func = nfsd_proc_setattr,
@@ -615,6 +617,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_attrstat),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "SETATTR",
 	},
 	[NFSPROC_ROOT] = {
 		.pc_decode = nfssvc_decode_void,
@@ -623,6 +626,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_void),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
+		.pc_name = "ROOT",
 	},
 	[NFSPROC_LOOKUP] = {
 		.pc_func = nfsd_proc_lookup,
@@ -633,6 +637,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_diropres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+FH+AT,
+		.pc_name = "LOOKUP",
 	},
 	[NFSPROC_READLINK] = {
 		.pc_func = nfsd_proc_readlink,
@@ -642,6 +647,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_readlinkres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+1+NFS_MAXPATHLEN/4,
+		.pc_name = "READLINK",
 	},
 	[NFSPROC_READ] = {
 		.pc_func = nfsd_proc_read,
@@ -652,6 +658,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_readres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT+1+NFSSVC_MAXBLKSIZE_V2/4,
+		.pc_name = "READ",
 	},
 	[NFSPROC_WRITECACHE] = {
 		.pc_decode = nfssvc_decode_void,
@@ -660,6 +667,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_void),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
+		.pc_name = "WRITECACHE",
 	},
 	[NFSPROC_WRITE] = {
 		.pc_func = nfsd_proc_write,
@@ -670,6 +678,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_attrstat),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "WRITE",
 	},
 	[NFSPROC_CREATE] = {
 		.pc_func = nfsd_proc_create,
@@ -680,6 +689,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_diropres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+FH+AT,
+		.pc_name = "CREATE",
 	},
 	[NFSPROC_REMOVE] = {
 		.pc_func = nfsd_proc_remove,
@@ -689,6 +699,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_void),
 		.pc_cachetype = RC_REPLSTAT,
 		.pc_xdrressize = ST,
+		.pc_name = "REMOVE",
 	},
 	[NFSPROC_RENAME] = {
 		.pc_func = nfsd_proc_rename,
@@ -698,6 +709,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_void),
 		.pc_cachetype = RC_REPLSTAT,
 		.pc_xdrressize = ST,
+		.pc_name = "RENAME",
 	},
 	[NFSPROC_LINK] = {
 		.pc_func = nfsd_proc_link,
@@ -707,6 +719,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_void),
 		.pc_cachetype = RC_REPLSTAT,
 		.pc_xdrressize = ST,
+		.pc_name = "LINK",
 	},
 	[NFSPROC_SYMLINK] = {
 		.pc_func = nfsd_proc_symlink,
@@ -716,6 +729,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_void),
 		.pc_cachetype = RC_REPLSTAT,
 		.pc_xdrressize = ST,
+		.pc_name = "SYMLINK",
 	},
 	[NFSPROC_MKDIR] = {
 		.pc_func = nfsd_proc_mkdir,
@@ -726,6 +740,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_diropres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+FH+AT,
+		.pc_name = "MKDIR",
 	},
 	[NFSPROC_RMDIR] = {
 		.pc_func = nfsd_proc_rmdir,
@@ -735,6 +750,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_void),
 		.pc_cachetype = RC_REPLSTAT,
 		.pc_xdrressize = ST,
+		.pc_name = "RMDIR",
 	},
 	[NFSPROC_READDIR] = {
 		.pc_func = nfsd_proc_readdir,
@@ -743,6 +759,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_argsize = sizeof(struct nfsd_readdirargs),
 		.pc_ressize = sizeof(struct nfsd_readdirres),
 		.pc_cachetype = RC_NOCACHE,
+		.pc_name = "READDIR",
 	},
 	[NFSPROC_STATFS] = {
 		.pc_func = nfsd_proc_statfs,
@@ -752,6 +769,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_statfsres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+5,
+		.pc_name = "STATFS",
 	},
 };
 
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 386628b36bc7..56409c39c4a0 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -461,6 +461,7 @@ struct svc_procedure {
 	unsigned int		pc_ressize;	/* result struct size */
 	unsigned int		pc_cachetype;	/* cache info (NFS) */
 	unsigned int		pc_xdrressize;	/* maximum size of XDR reply */
+	const char *		pc_name;	/* for display */
 };
 
 /*
diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
index aac12f45bfb0..afe0ef534d7e 100644
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -1336,6 +1336,7 @@ TRACE_EVENT(svc_process,
 		__field(u32, vers)
 		__field(u32, proc)
 		__string(service, name)
+		__string(procedure, rqst->rq_procinfo->pc_name)
 		__string(addr, rqst->rq_xprt ?
 			 rqst->rq_xprt->xpt_remotebuf : "(null)")
 	),
@@ -1345,13 +1346,16 @@ TRACE_EVENT(svc_process,
 		__entry->vers = rqst->rq_vers;
 		__entry->proc = rqst->rq_proc;
 		__assign_str(service, name);
+		__assign_str(procedure, rqst->rq_procinfo->pc_name);
 		__assign_str(addr, rqst->rq_xprt ?
 			     rqst->rq_xprt->xpt_remotebuf : "(null)");
 	),
 
-	TP_printk("addr=%s xid=0x%08x service=%s vers=%u proc=%u",
+	TP_printk("addr=%s xid=0x%08x service=%s vers=%u proc=%s",
 			__get_str(addr), __entry->xid,
-			__get_str(service), __entry->vers, __entry->proc)
+			__get_str(service), __entry->vers,
+			__get_str(procedure)
+	)
 );
 
 DECLARE_EVENT_CLASS(svc_rqst_event,



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

* [PATCH v2 09/27] NFSD: Clean up the show_nf_may macro
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (7 preceding siblings ...)
  2020-09-21 18:11 ` [PATCH v2 08/27] SUNRPC: Make trace_svc_process() display the RPC procedure symbolically Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 10/27] NFSD: Remove extra "0x" in tracepoint format specifier Chuck Lever
                   ` (18 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Display all currently possible NFSD_MAY permission flags.

Move and rename show_nf_may with a more generic name because the
NFSD_MAY permission flags are used in other places besides the file
cache.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/trace.h |   40 ++++++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 1909fc57435f..8d72829f15ac 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -13,6 +13,22 @@
 #include "export.h"
 #include "nfsfh.h"
 
+#define show_nfsd_may_flags(x)						\
+	__print_flags(x, "|",						\
+		{ NFSD_MAY_EXEC,		"EXEC" },		\
+		{ NFSD_MAY_WRITE,		"WRITE" },		\
+		{ NFSD_MAY_READ,		"READ" },		\
+		{ NFSD_MAY_SATTR,		"SATTR" },		\
+		{ NFSD_MAY_TRUNC,		"TRUNC" },		\
+		{ NFSD_MAY_LOCK,		"LOCK" },		\
+		{ NFSD_MAY_OWNER_OVERRIDE,	"OWNER_OVERRIDE" },	\
+		{ NFSD_MAY_LOCAL_ACCESS,	"LOCAL_ACCESS" },	\
+		{ NFSD_MAY_BYPASS_GSS_ON_ROOT,	"BYPASS_GSS_ON_ROOT" },	\
+		{ NFSD_MAY_NOT_BREAK_LEASE,	"NOT_BREAD_LEASE" },	\
+		{ NFSD_MAY_BYPASS_GSS,		"BYPASS_GSS" },		\
+		{ NFSD_MAY_READ_IF_EXEC,	"READ_IF_EXEC" },	\
+		{ NFSD_MAY_64BIT_COOKIE,	"64BIT_COOKIE" })
+
 TRACE_EVENT(nfsd_compound,
 	TP_PROTO(const struct svc_rqst *rqst,
 		 u32 args_opcnt),
@@ -422,6 +438,9 @@ TRACE_EVENT(nfsd_clid_inuse_err,
 		__entry->cl_boot, __entry->cl_id)
 )
 
+/*
+ * from fs/nfsd/filecache.h
+ */
 TRACE_DEFINE_ENUM(NFSD_FILE_HASHED);
 TRACE_DEFINE_ENUM(NFSD_FILE_PENDING);
 TRACE_DEFINE_ENUM(NFSD_FILE_BREAK_READ);
@@ -436,13 +455,6 @@ TRACE_DEFINE_ENUM(NFSD_FILE_REFERENCED);
 		{ 1 << NFSD_FILE_BREAK_WRITE,	"BREAK_WRITE" },	\
 		{ 1 << NFSD_FILE_REFERENCED,	"REFERENCED"})
 
-/* FIXME: This should probably be fleshed out in the future. */
-#define show_nf_may(val)						\
-	__print_flags(val, "|",						\
-		{ NFSD_MAY_READ,		"READ" },		\
-		{ NFSD_MAY_WRITE,		"WRITE" },		\
-		{ NFSD_MAY_NOT_BREAK_LEASE,	"NOT_BREAK_LEASE" })
-
 DECLARE_EVENT_CLASS(nfsd_file_class,
 	TP_PROTO(struct nfsd_file *nf),
 	TP_ARGS(nf),
@@ -467,7 +479,7 @@ DECLARE_EVENT_CLASS(nfsd_file_class,
 		__entry->nf_inode,
 		__entry->nf_ref,
 		show_nf_flags(__entry->nf_flags),
-		show_nf_may(__entry->nf_may),
+		show_nfsd_may_flags(__entry->nf_may),
 		__entry->nf_file)
 )
 
@@ -493,10 +505,10 @@ TRACE_EVENT(nfsd_file_acquire,
 		__field(u32, xid)
 		__field(unsigned int, hash)
 		__field(void *, inode)
-		__field(unsigned int, may_flags)
+		__field(unsigned long, may_flags)
 		__field(int, nf_ref)
 		__field(unsigned long, nf_flags)
-		__field(unsigned char, nf_may)
+		__field(unsigned long, nf_may)
 		__field(struct file *, nf_file)
 		__field(u32, status)
 	),
@@ -515,10 +527,10 @@ TRACE_EVENT(nfsd_file_acquire,
 
 	TP_printk("xid=0x%x hash=0x%x inode=0x%p may_flags=%s ref=%d nf_flags=%s nf_may=%s nf_file=0x%p status=%u",
 			__entry->xid, __entry->hash, __entry->inode,
-			show_nf_may(__entry->may_flags), __entry->nf_ref,
-			show_nf_flags(__entry->nf_flags),
-			show_nf_may(__entry->nf_may), __entry->nf_file,
-			__entry->status)
+			show_nfsd_may_flags(__entry->may_flags),
+			__entry->nf_ref, show_nf_flags(__entry->nf_flags),
+			show_nfsd_may_flags(__entry->nf_may),
+			__entry->nf_file, __entry->status)
 );
 
 DECLARE_EVENT_CLASS(nfsd_file_search_class,



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

* [PATCH v2 10/27] NFSD: Remove extra "0x" in tracepoint format specifier
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (8 preceding siblings ...)
  2020-09-21 18:11 ` [PATCH v2 09/27] NFSD: Clean up the show_nf_may macro Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 11/27] NFSD: Constify @fh argument of knfsd_fh_hash() Chuck Lever
                   ` (17 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Clean up: %p adds its own 0x already.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/trace.h |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 8d72829f15ac..62bf57a8d03c 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -474,7 +474,7 @@ DECLARE_EVENT_CLASS(nfsd_file_class,
 		__entry->nf_may = nf->nf_may;
 		__entry->nf_file = nf->nf_file;
 	),
-	TP_printk("hash=0x%x inode=0x%p ref=%d flags=%s may=%s file=%p",
+	TP_printk("hash=0x%x inode=%p ref=%d flags=%s may=%s file=%p",
 		__entry->nf_hashval,
 		__entry->nf_inode,
 		__entry->nf_ref,
@@ -525,7 +525,7 @@ TRACE_EVENT(nfsd_file_acquire,
 		__entry->status = be32_to_cpu(status);
 	),
 
-	TP_printk("xid=0x%x hash=0x%x inode=0x%p may_flags=%s ref=%d nf_flags=%s nf_may=%s nf_file=0x%p status=%u",
+	TP_printk("xid=0x%x hash=0x%x inode=%p may_flags=%s ref=%d nf_flags=%s nf_may=%s nf_file=%p status=%u",
 			__entry->xid, __entry->hash, __entry->inode,
 			show_nfsd_may_flags(__entry->may_flags),
 			__entry->nf_ref, show_nf_flags(__entry->nf_flags),
@@ -546,7 +546,7 @@ DECLARE_EVENT_CLASS(nfsd_file_search_class,
 		__entry->hash = hash;
 		__entry->found = found;
 	),
-	TP_printk("hash=0x%x inode=0x%p found=%d", __entry->hash,
+	TP_printk("hash=0x%x inode=%p found=%d", __entry->hash,
 			__entry->inode, __entry->found)
 );
 
@@ -574,7 +574,7 @@ TRACE_EVENT(nfsd_file_fsnotify_handle_event,
 		__entry->mode = inode->i_mode;
 		__entry->mask = mask;
 	),
-	TP_printk("inode=0x%p nlink=%u mode=0%ho mask=0x%x", __entry->inode,
+	TP_printk("inode=%p nlink=%u mode=0%ho mask=0x%x", __entry->inode,
 			__entry->nlink, __entry->mode, __entry->mask)
 );
 



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

* [PATCH v2 11/27] NFSD: Constify @fh argument of knfsd_fh_hash()
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (9 preceding siblings ...)
  2020-09-21 18:11 ` [PATCH v2 10/27] NFSD: Remove extra "0x" in tracepoint format specifier Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 12/27] NFSD: Add tracepoint in nfsd_setattr() Chuck Lever
                   ` (16 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Refactor: Enable knfsd_fh_hash() to be invoked in functions where
the FH is const.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsfh.h |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h
index 56cfbc361561..1a2e28369d04 100644
--- a/fs/nfsd/nfsfh.h
+++ b/fs/nfsd/nfsfh.h
@@ -219,15 +219,12 @@ static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
  * returns a crc32 hash for the filehandle that is compatible with
  * the one displayed by "wireshark".
  */
-
-static inline u32
-knfsd_fh_hash(struct knfsd_fh *fh)
+static inline u32 knfsd_fh_hash(const struct knfsd_fh *fh)
 {
 	return ~crc32_le(0xFFFFFFFF, (unsigned char *)&fh->fh_base, fh->fh_size);
 }
 #else
-static inline u32
-knfsd_fh_hash(struct knfsd_fh *fh)
+static inline u32 knfsd_fh_hash(const struct knfsd_fh *fh)
 {
 	return 0;
 }



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

* [PATCH v2 12/27] NFSD: Add tracepoint in nfsd_setattr()
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (10 preceding siblings ...)
  2020-09-21 18:11 ` [PATCH v2 11/27] NFSD: Constify @fh argument of knfsd_fh_hash() Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:11 ` [PATCH v2 13/27] NFSD: Add tracepoint for nfsd_access() Chuck Lever
                   ` (15 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Capture especially the XID, file handle, and attr mask for
troubleshooting. So for example:

nfsd-1025  [002]   256.807363: nfsd_setattr:         xid=0x12147d7a fh_hash=0x6085d6fb valid=MODE|ATIME|MTIME

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/trace.h           |   24 ++++++++++++++++++++++++
 fs/nfsd/vfs.c             |    2 ++
 include/trace/events/fs.h |   20 ++++++++++++++++++++
 3 files changed, 46 insertions(+)

diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 62bf57a8d03c..b4c773530aa8 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -9,6 +9,7 @@
 #define _NFSD_TRACE_H
 
 #include <linux/tracepoint.h>
+#include <trace/events/fs.h>
 
 #include "export.h"
 #include "nfsfh.h"
@@ -29,6 +30,29 @@
 		{ NFSD_MAY_READ_IF_EXEC,	"READ_IF_EXEC" },	\
 		{ NFSD_MAY_64BIT_COOKIE,	"64BIT_COOKIE" })
 
+TRACE_EVENT(nfsd_setattr_args,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct svc_fh *fhp,
+		unsigned int valid
+	),
+	TP_ARGS(rqstp, fhp, valid),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, fh_hash)
+		__field(unsigned long, valid)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->fh_hash = knfsd_fh_hash(&fhp->fh_handle);
+		__entry->valid = valid;
+	),
+	TP_printk("xid=0x%08x fh_hash=0x%08x valid=%s",
+		__entry->xid, __entry->fh_hash,
+		show_attr_valid_flags(__entry->valid)
+	)
+);
+
 TRACE_EVENT(nfsd_compound,
 	TP_PROTO(const struct svc_rqst *rqst,
 		 u32 args_opcnt),
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 1ecaceebee13..a311593ac976 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -375,6 +375,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
 	bool		get_write_count;
 	bool		size_change = (iap->ia_valid & ATTR_SIZE);
 
+	trace_nfsd_setattr_args(rqstp, fhp, iap->ia_valid);
+
 	if (iap->ia_valid & ATTR_SIZE) {
 		accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE;
 		ftype = S_IFREG;
diff --git a/include/trace/events/fs.h b/include/trace/events/fs.h
index 8ea0e84e425a..2b185d81d9a5 100644
--- a/include/trace/events/fs.h
+++ b/include/trace/events/fs.h
@@ -145,3 +145,23 @@
 		{ LOOKUP_NO_XDEV,	"NO_XDEV" }, \
 		{ LOOKUP_BENEATH,	"BENEATH" }, \
 		{ LOOKUP_IN_ROOT,	"IN_ROOT" })
+
+#define show_attr_valid_flags(x) \
+	__print_flags(x, "|", \
+		{ ATTR_MODE,		"MODE" }, \
+		{ ATTR_UID,		"UID" }, \
+		{ ATTR_GID,		"GID" }, \
+		{ ATTR_SIZE,		"SIZE" }, \
+		{ ATTR_ATIME,		"ATIME" }, \
+		{ ATTR_MTIME,		"MTIME" }, \
+		{ ATTR_CTIME,		"CTIME" }, \
+		{ ATTR_ATIME_SET,	"ATIME_SET" }, \
+		{ ATTR_MTIME_SET,	"MTIME_SET" }, \
+		{ ATTR_FORCE,		"FORCE" }, \
+		{ ATTR_KILL_SUID,	"KILL_SUID" }, \
+		{ ATTR_KILL_SGID,	"KILL_SGID" }, \
+		{ ATTR_FILE,		"FILE" }, \
+		{ ATTR_KILL_PRIV,	"KILL_PRIV" }, \
+		{ ATTR_OPEN,		"OPEN" }, \
+		{ ATTR_TIMES_SET,	"TIMES_SET" }, \
+		{ ATTR_TOUCH,		"TOUCH" })



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

* [PATCH v2 13/27] NFSD: Add tracepoint for nfsd_access()
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (11 preceding siblings ...)
  2020-09-21 18:11 ` [PATCH v2 12/27] NFSD: Add tracepoint in nfsd_setattr() Chuck Lever
@ 2020-09-21 18:11 ` Chuck Lever
  2020-09-21 18:12 ` [PATCH v2 14/27] NFSD: nfsd_compound_status tracepoint should record XID Chuck Lever
                   ` (14 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:11 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

It is possible to use this tracepoint for several purposes,
including troubleshooting export permission problems and auditing
accesses to files.

nfsd-1025  [002]   256.807403: nfsd_permission:      xid=0x12147d7a \
	type=REG access=WRITE|SATTR|OWNER_OVERRIDE owner=1046/100 \
	user=1046/100 name=.clang-format status=OK

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/trace.h           |   45 +++++++++++++++++++++++++++++++++++++++++++++
 fs/nfsd/vfs.c             |    1 +
 include/trace/events/fs.h |   10 ++++++++++
 3 files changed, 56 insertions(+)

diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index b4c773530aa8..15b97275b3b4 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -10,6 +10,7 @@
 
 #include <linux/tracepoint.h>
 #include <trace/events/fs.h>
+#include <trace/events/nfs.h>
 
 #include "export.h"
 #include "nfsfh.h"
@@ -30,6 +31,50 @@
 		{ NFSD_MAY_READ_IF_EXEC,	"READ_IF_EXEC" },	\
 		{ NFSD_MAY_64BIT_COOKIE,	"64BIT_COOKIE" })
 
+TRACE_EVENT(nfsd_access,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct dentry *dentry,
+		int access,
+		__be32 status
+	),
+	TP_ARGS(rqstp, dentry, access, status),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(unsigned long, type)
+		__field(unsigned long, access)
+		__field(uid_t, owner)
+		__field(gid_t, owner_group)
+		__field(uid_t, user)
+		__field(gid_t, user_group)
+		__field(int, status)
+		__dynamic_array(unsigned char, name, dentry->d_name.len + 1)
+	),
+	TP_fast_assign(
+		const struct inode *inode = d_inode(dentry);
+
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->type = inode->i_mode & S_IFMT;
+		__entry->access = access;
+		__entry->owner = __kuid_val(inode->i_uid);
+		__entry->owner_group = __kgid_val(inode->i_gid);
+		__entry->user = __kuid_val(current_fsuid());
+		__entry->user_group = __kgid_val(current_fsgid());
+		__entry->status = be32_to_cpu(status);
+		memcpy(__get_str(name), dentry->d_name.name,
+		       dentry->d_name.len);
+		__get_str(name)[dentry->d_name.len] = '\0';
+	),
+	TP_printk("xid=0x%08x type=%s access=%s owner=%u/%u user=%u/%u name=%s status=%s",
+		__entry->xid,
+		show_inode_type(__entry->type),
+		show_nfsd_may_flags(__entry->access),
+		__entry->owner, __entry->owner_group,
+		__entry->user, __entry->user_group,
+		__get_str(name), show_nfs_status(__entry->status)
+	)
+);
+
 TRACE_EVENT(nfsd_setattr_args,
 	TP_PROTO(
 		const struct svc_rqst *rqstp,
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index a311593ac976..0d354531ed19 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -687,6 +687,7 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor
 			sresult |= map->access;
 
 			err2 = nfsd_permission(rqstp, export, dentry, map->how);
+			trace_nfsd_access(rqstp, dentry, map->how, err2);
 			switch (err2) {
 			case nfs_ok:
 				result |= map->access;
diff --git a/include/trace/events/fs.h b/include/trace/events/fs.h
index 2b185d81d9a5..49d3dde471ad 100644
--- a/include/trace/events/fs.h
+++ b/include/trace/events/fs.h
@@ -165,3 +165,13 @@
 		{ ATTR_OPEN,		"OPEN" }, \
 		{ ATTR_TIMES_SET,	"TIMES_SET" }, \
 		{ ATTR_TOUCH,		"TOUCH" })
+
+#define show_inode_type(x) \
+	__print_symbolic(x, \
+		{ S_IFIFO,		"FIFO" }, \
+		{ S_IFCHR,		"CHR" }, \
+		{ S_IFDIR,		"DIR" }, \
+		{ S_IFBLK,		"BLK" }, \
+		{ S_IFREG,		"REG" }, \
+		{ S_IFLNK,		"LNK" }, \
+		{ S_IFSOCK,		"SOCK" })



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

* [PATCH v2 14/27] NFSD: nfsd_compound_status tracepoint should record XID
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (12 preceding siblings ...)
  2020-09-21 18:11 ` [PATCH v2 13/27] NFSD: Add tracepoint for nfsd_access() Chuck Lever
@ 2020-09-21 18:12 ` Chuck Lever
  2020-09-21 18:12 ` [PATCH v2 15/27] NFSD: Add client ID lifetime tracepoints Chuck Lever
                   ` (13 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:12 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

The two tracepoints, nfsd_compound and nfsd_compound_status, should
provide matching information, to enable the records to be bracketed
correctly. So, for example:

nfsd-1034  [000]   165.191371: nfsd4_compound:       xid=0xe62d9610 opcnt=4
nfsd-1034  [000]   165.191516: nfsd4_compound_status: xid=0xe62d9610 op=1/4 OP_PUTFH status=OK
nfsd-1034  [000]   165.191637: nfsd4_compound_status: xid=0xe62d9610 op=2/4 OP_CREATE status=OK
nfsd-1034  [000]   165.191639: nfsd4_compound_status: xid=0xe62d9610 op=3/4 OP_GETFH status=OK
nfsd-1034  [000]   165.191680: nfsd4_compound_status: xid=0xe62d9610 op=4/4 OP_GETATTR status=OK

Also, report the status code symbolically instead of numerically for
faster readability.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4proc.c |    6 ++--
 fs/nfsd/trace.h    |   86 ++++++++++++++++++++++++++++------------------------
 2 files changed, 50 insertions(+), 42 deletions(-)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index e89a51ed2bbf..17a627f97766 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -2371,7 +2371,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
 
 	rqstp->rq_lease_breaker = (void **)&cstate->clp;
 
-	trace_nfsd_compound(rqstp, args->opcnt);
+	trace_nfsd4_compound(rqstp, args->opcnt);
 	while (!status && resp->opcnt < args->opcnt) {
 		op = &args->ops[resp->opcnt++];
 
@@ -2450,8 +2450,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
 			status = op->status;
 		}
 
-		trace_nfsd_compound_status(args->opcnt, resp->opcnt, status,
-					   nfsd4_op_name(op->opnum));
+		trace_nfsd4_compoundstatus(rqstp, args->opcnt, resp->opcnt,
+					   status, nfsd4_op_name(op->opnum));
 
 		nfsd4_cstate_clear_replay(cstate);
 		nfsd4_increment_op_stats(op->opnum);
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 15b97275b3b4..afcb3bcf13f2 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -98,45 +98,6 @@ TRACE_EVENT(nfsd_setattr_args,
 	)
 );
 
-TRACE_EVENT(nfsd_compound,
-	TP_PROTO(const struct svc_rqst *rqst,
-		 u32 args_opcnt),
-	TP_ARGS(rqst, args_opcnt),
-	TP_STRUCT__entry(
-		__field(u32, xid)
-		__field(u32, args_opcnt)
-	),
-	TP_fast_assign(
-		__entry->xid = be32_to_cpu(rqst->rq_xid);
-		__entry->args_opcnt = args_opcnt;
-	),
-	TP_printk("xid=0x%08x opcnt=%u",
-		__entry->xid, __entry->args_opcnt)
-)
-
-TRACE_EVENT(nfsd_compound_status,
-	TP_PROTO(u32 args_opcnt,
-		 u32 resp_opcnt,
-		 __be32 status,
-		 const char *name),
-	TP_ARGS(args_opcnt, resp_opcnt, status, name),
-	TP_STRUCT__entry(
-		__field(u32, args_opcnt)
-		__field(u32, resp_opcnt)
-		__field(int, status)
-		__string(name, name)
-	),
-	TP_fast_assign(
-		__entry->args_opcnt = args_opcnt;
-		__entry->resp_opcnt = resp_opcnt;
-		__entry->status = be32_to_cpu(status);
-		__assign_str(name, name);
-	),
-	TP_printk("op=%u/%u %s status=%d",
-		__entry->resp_opcnt, __entry->args_opcnt,
-		__get_str(name), __entry->status)
-)
-
 DECLARE_EVENT_CLASS(nfsd_fh_err_class,
 	TP_PROTO(struct svc_rqst *rqstp,
 		 struct svc_fh	*fhp,
@@ -333,6 +294,53 @@ DEFINE_EVENT(nfsd_err_class, nfsd_##name,	\
 DEFINE_NFSD_ERR_EVENT(read_err);
 DEFINE_NFSD_ERR_EVENT(write_err);
 
+TRACE_EVENT(nfsd4_compound,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		 u32 args_opcnt
+	),
+	TP_ARGS(rqstp, args_opcnt),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, args_opcnt)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->args_opcnt = args_opcnt;
+	),
+	TP_printk("xid=0x%08x opcnt=%u",
+		__entry->xid, __entry->args_opcnt)
+)
+
+TRACE_EVENT(nfsd4_compoundstatus,
+	TP_PROTO(
+		 const struct svc_rqst *rqstp,
+		 u32 args_opcnt,
+		 u32 resp_opcnt,
+		 __be32 status,
+		 const char *name
+	),
+	TP_ARGS(rqstp, args_opcnt, resp_opcnt, status, name),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, args_opcnt)
+		__field(u32, resp_opcnt)
+		__field(int, status)
+		__string(name, name)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->args_opcnt = args_opcnt;
+		__entry->resp_opcnt = resp_opcnt;
+		__entry->status = be32_to_cpu(status);
+		__assign_str(name, name);
+	),
+	TP_printk("xid=0x%08x op=%u/%u %s status=%s",
+		__entry->xid, __entry->resp_opcnt, __entry->args_opcnt,
+		__get_str(name), show_nfs4_status(__entry->status)
+	)
+)
+
 #include "state.h"
 #include "filecache.h"
 #include "vfs.h"



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

* [PATCH v2 15/27] NFSD: Add client ID lifetime tracepoints
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (13 preceding siblings ...)
  2020-09-21 18:12 ` [PATCH v2 14/27] NFSD: nfsd_compound_status tracepoint should record XID Chuck Lever
@ 2020-09-21 18:12 ` Chuck Lever
  2020-09-21 18:12 ` [PATCH v2 16/27] NFSD: Add tracepoints to report NFSv4 session state Chuck Lever
                   ` (12 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:12 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

These tracepoints enable troubleshooting of duplicate clientid strings
and they bracket NFSv4 state recovery. Examples:

NFSv4.0:

nfsd-1037  [000]  1282.828363: nfsd4_compound:       xid=0xef35f61d opcnt=1
nfsd-1037  [000]  1282.828488: nfsd_cb_args:         client 5f60f8c2:36e7ec84 callback addr=192.168.2.51:38549 prog=1073741824 ident=1
nfsd-1037  [000]  1282.828492: nfsd4_setclientid:    xid=0xef35f61d addr=192.168.2.51:0 \
	nfs4_clientid=Linux NFSv4.0 manet.1015granger.net/2d9f29bfc60e4c97b19dc38ae1bbed35/192.168.2.55 \
	verifier=1631b10 2717d415f client 5f60f8c2:36e7ec84
nfsd-1037  [000]  1282.828496: nfsd4_compoundstatus: xid=0xef35f61d op=1/1 OP_SETCLIENTID status=OK

 ...

kworker/u8:2-1276  [001]  1802.149078: nfsd4_clid_purged:    client 5f60f8c2:36e7ec84
kworker/u8:2-1276  [002]  1802.152047: nfsd4_clid_destroy:   client 5f60f8c2:36e7ec84


NFSv4.1:

nfsd-1036  [003]   239.777632: nfsd4_compound:       xid=0x746ca73c opcnt=1
nfsd-1036  [003]   239.777776: nfsd4_exchange_id:    xid=0x746ca73c addr=192.168.2.51:0 \
	nfs4_clientid=Linux NFSv4.1 2d9f29bfc60e4c97b19dc38ae1bbed35/manet.1015granger.net \
	verifier=1631b102717d415f flags=SUPP_MOVED_REFER|USE_PNFS_MDS spa_how=SP4_MACH_CRED \
	seqid=0 client 5f610879:b615c40a
kworker/u8:4-144   [002]   239.777795: nfsd4_cb_work:        addr= client 5f610879:b615c409 procedure=CB_NULL
nfsd-1036  [003]   239.777887: nfsd4_compoundstatus: xid=0x746ca73c op=1/1 OP_EXCHANGE_ID status=OK
nfsd-1036  [003]   239.779793: nfsd4_compound:       xid=0x756ca73c opcnt=1
nfsd-1036  [003]   239.780052: nfsd4_cb_state:       addr=192.168.2.51:0 client 5f610879:b615c40a state=UNKNOWN
kworker/u8:4-144   [002]   239.780063: nfsd4_cb_work:        addr=192.168.2.51:0 client 5f610879:b615c40a procedure=CB_NULL
kworker/u8:4-144   [002]   239.780416: nfsd4_cb_setup:       addr=192.168.2.51:0 client 5f610879:b615c40a state=UNKNOWN
nfsd-1036  [000]   239.780433: nfsd4_compoundstatus: xid=0x756ca73c op=1/1 OP_CREATE_SESSION status=OK
nfsd-1036  [000]   239.782856: nfsd4_compound:       xid=0x766ca73c opcnt=2
nfsd-1036  [000]   239.782874: nfsd4_compoundstatus: xid=0x766ca73c op=1/2 OP_SEQUENCE status=OK
nfsd-1036  [000]   239.782876: nfsd4_clid_reclaim_complete: client 5f610879:b615c40a
nfsd-1036  [000]   239.785385: nfsd4_compoundstatus: xid=0x766ca73c op=2/2 OP_RECLAIM_COMPLETE status=OK

 ...

nfsd-1036  [003]   649.644616: nfsd4_compound:       xid=0x88d1a73c opcnt=1
nfsd-1036  [003]   649.647841: nfsd4_clid_destroy:   client 5f610879:b615c40a
kworker/u8:6-158   [002]   649.647854: nfsd4_cb_work:        addr=192.168.2.51:0 client 5f610879:b615c40a procedure=CB_NULL
nfsd-1036  [003]   649.647946: nfsd4_compoundstatus: xid=0x88d1a73c op=1/1 OP_DESTROY_CLIENTID status=OK

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4state.c        |   37 ++++++---------
 fs/nfsd/trace.h            |  107 ++++++++++++++++++++++++++++++++------------
 fs/nfsd/xdr4.h             |    3 +
 include/trace/events/nfs.h |   22 +++++++++
 4 files changed, 116 insertions(+), 53 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 0b3059b8b36c..974b3303d2fc 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1935,7 +1935,7 @@ STALE_CLIENTID(clientid_t *clid, struct nfsd_net *nn)
 	 */
 	if (clid->cl_boot == (u32)nn->boot_time)
 		return 0;
-	trace_nfsd_clid_stale(clid);
+	trace_nfsd4_clid_stale(clid);
 	return 1;
 }
 
@@ -2077,6 +2077,8 @@ __destroy_client(struct nfs4_client *clp)
 	struct nfs4_delegation *dp;
 	struct list_head reaplist;
 
+	trace_nfsd4_clid_destroy(&clp->cl_clientid);
+
 	INIT_LIST_HEAD(&reaplist);
 	spin_lock(&state_lock);
 	while (!list_empty(&clp->cl_delegations)) {
@@ -3062,18 +3064,10 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	struct nfs4_client *conf, *new;
 	struct nfs4_client *unconf = NULL;
 	__be32 status;
-	char			addr_str[INET6_ADDRSTRLEN];
 	nfs4_verifier		verf = exid->verifier;
-	struct sockaddr		*sa = svc_addr(rqstp);
 	bool	update = exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A;
 	struct nfsd_net		*nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 
-	rpc_ntop(sa, addr_str, sizeof(addr_str));
-	dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p "
-		"ip_addr=%s flags %x, spa_how %d\n",
-		__func__, rqstp, exid, exid->clname.len, exid->clname.data,
-		addr_str, exid->flags, exid->spa_how);
-
 	if (exid->flags & ~EXCHGID4_FLAG_MASK_A)
 		return nfserr_inval;
 
@@ -3200,8 +3194,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	exid->seqid = conf->cl_cs_slot.sl_seqid + 1;
 	nfsd4_set_ex_flags(conf, exid);
 
-	dprintk("nfsd4_exchange_id seqid %d flags %x\n",
-		conf->cl_cs_slot.sl_seqid, conf->cl_exchange_flags);
+	trace_nfsd4_exchange_id(rqstp, exid);
 	status = nfs_ok;
 
 out:
@@ -3894,8 +3887,11 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp,
 		struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
 {
 	struct nfsd4_reclaim_complete *rc = &u->reclaim_complete;
+	struct nfs4_client *clp = cstate->session->se_client;
 	__be32 status = 0;
 
+	trace_nfsd4_clid_reclaim_complete(&clp->cl_clientid);
+
 	if (rc->rca_one_fs) {
 		if (!cstate->current_fh.fh_dentry)
 			return nfserr_nofilehandle;
@@ -3907,12 +3903,11 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp,
 	}
 
 	status = nfserr_complete_already;
-	if (test_and_set_bit(NFSD4_CLIENT_RECLAIM_COMPLETE,
-			     &cstate->session->se_client->cl_flags))
+	if (test_and_set_bit(NFSD4_CLIENT_RECLAIM_COMPLETE, &clp->cl_flags))
 		goto out;
 
 	status = nfserr_stale_clientid;
-	if (is_client_expired(cstate->session->se_client))
+	if (is_client_expired(clp))
 		/*
 		 * The following error isn't really legal.
 		 * But we only get here if the client just explicitly
@@ -3923,8 +3918,8 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp,
 		goto out;
 
 	status = nfs_ok;
-	nfsd4_client_record_create(cstate->session->se_client);
-	inc_reclaim_complete(cstate->session->se_client);
+	nfsd4_client_record_create(clp);
+	inc_reclaim_complete(clp);
 out:
 	return status;
 }
@@ -3972,6 +3967,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
 	memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
 	new = NULL;
+	trace_nfsd4_setclientid(rqstp, setclid);
 	status = nfs_ok;
 out:
 	spin_unlock(&nn->client_lock);
@@ -5314,7 +5310,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	__be32 status;
 	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 
-	trace_nfsd_clid_renew(clid);
+	trace_nfsd4_clid_renew(clid);
 	status = lookup_clientid(clid, cstate, nn, false);
 	if (status)
 		goto out;
@@ -5426,7 +5422,7 @@ nfs4_laundromat(struct nfsd_net *nn)
 			break;
 		}
 		if (mark_client_expired_locked(clp)) {
-			trace_nfsd_clid_expired(&clp->cl_clientid);
+			trace_nfsd4_clid_expired(&clp->cl_clientid);
 			continue;
 		}
 		list_add(&clp->cl_lru, &reaplist);
@@ -5434,7 +5430,7 @@ nfs4_laundromat(struct nfsd_net *nn)
 	spin_unlock(&nn->client_lock);
 	list_for_each_safe(pos, next, &reaplist) {
 		clp = list_entry(pos, struct nfs4_client, cl_lru);
-		trace_nfsd_clid_purged(&clp->cl_clientid);
+		trace_nfsd4_clid_purged(&clp->cl_clientid);
 		list_del_init(&clp->cl_lru);
 		expire_client(clp);
 	}
@@ -7185,7 +7181,6 @@ nfs4_client_to_reclaim(struct xdr_netobj name, struct xdr_netobj princhash,
 	unsigned int strhashval;
 	struct nfs4_client_reclaim *crp;
 
-	trace_nfsd_clid_reclaim(nn, name.len, name.data);
 	crp = alloc_reclaim();
 	if (crp) {
 		strhashval = clientstr_hashval(name);
@@ -7235,8 +7230,6 @@ nfsd4_find_reclaim_client(struct xdr_netobj name, struct nfsd_net *nn)
 	unsigned int strhashval;
 	struct nfs4_client_reclaim *crp = NULL;
 
-	trace_nfsd_clid_find(nn, name.len, name.data);
-
 	strhashval = clientstr_hashval(name);
 	list_for_each_entry(crp, &nn->reclaim_str_hashtbl[strhashval], cr_strhash) {
 		if (compare_blob(&crp->cr_name, &name) == 0) {
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index afcb3bcf13f2..192d039da0ec 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -14,6 +14,7 @@
 
 #include "export.h"
 #include "nfsfh.h"
+#include "xdr4.h"
 
 #define show_nfsd_may_flags(x)						\
 	__print_flags(x, "|",						\
@@ -294,6 +295,79 @@ DEFINE_EVENT(nfsd_err_class, nfsd_##name,	\
 DEFINE_NFSD_ERR_EVENT(read_err);
 DEFINE_NFSD_ERR_EVENT(write_err);
 
+TRACE_EVENT(nfsd4_setclientid,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct nfsd4_setclientid *setclid
+	),
+	TP_ARGS(rqstp, setclid),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, cl_boot)
+		__field(u32, cl_id)
+		__array(unsigned char, addr, sizeof(struct sockaddr_in6))
+		__array(char, verifier, NFS4_VERIFIER_SIZE)
+		__field(int, len)
+		__dynamic_array(unsigned char, clientid, setclid->se_name.len)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->cl_boot = setclid->se_clientid.cl_boot;
+		__entry->cl_id = setclid->se_clientid.cl_id;
+		memcpy(__entry->addr, svc_addr(rqstp), sizeof(struct sockaddr_in6));
+		memcpy(__entry->verifier, &setclid->se_verf, NFS4_VERIFIER_SIZE);
+		__entry->len = setclid->se_name.len;
+		memcpy(__get_dynamic_array(clientid),
+		       setclid->se_name.data, setclid->se_name.len);
+	),
+	TP_printk("xid=0x%08x addr=%pISpc nfs4_clientid=%.*s verifier=%s client=%08x:%08x",
+		__entry->xid, __entry->addr,
+		__entry->len, __get_str(clientid),
+		__print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE),
+		__entry->cl_boot, __entry->cl_id
+	)
+);
+
+TRACE_EVENT(nfsd4_exchange_id,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct nfsd4_exchange_id *exid
+	),
+	TP_ARGS(rqstp, exid),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, seqid)
+		__field(u32, cl_boot)
+		__field(u32, cl_id)
+		__field(unsigned long, flags)
+		__field(unsigned long, spa_how)
+		__array(unsigned char, addr, sizeof(struct sockaddr_in6))
+		__array(char, verifier, NFS4_VERIFIER_SIZE)
+		__field(int, len)
+		__dynamic_array(unsigned char, clientid, exid->clname.len)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->seqid = exid->seqid - 1;
+		__entry->cl_boot = exid->clientid.cl_boot;
+		__entry->cl_id = exid->clientid.cl_id;
+		__entry->flags = exid->flags;
+		__entry->spa_how = exid->spa_how;
+		memcpy(__entry->addr, svc_addr(rqstp), sizeof(struct sockaddr_in6));
+		memcpy(__entry->verifier, &exid->verifier, NFS4_VERIFIER_SIZE);
+		__entry->len = exid->clname.len;
+		memcpy(__get_dynamic_array(clientid), exid->clname.data, exid->clname.len);
+	),
+	TP_printk("xid=0x%08x addr=%pISpc nfs4_clientid=%.*s verifier=%s flags=%s spa_how=%s seqid=%u client=%08x:%08x",
+		__entry->xid, __entry->addr,
+		__entry->len, __get_str(clientid),
+		__print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE),
+		show_nfs4_exchgid4_flags(__entry->flags),
+		show_nfs4_exchid4_spa_how(__entry->spa_how),
+		__entry->seqid, __entry->cl_boot, __entry->cl_id
+	)
+);
+
 TRACE_EVENT(nfsd4_compound,
 	TP_PROTO(
 		const struct svc_rqst *rqstp,
@@ -433,10 +507,12 @@ DECLARE_EVENT_CLASS(nfsd_clientid_class,
 )
 
 #define DEFINE_CLIENTID_EVENT(name) \
-DEFINE_EVENT(nfsd_clientid_class, nfsd_clid_##name, \
+DEFINE_EVENT(nfsd_clientid_class, nfsd4_clid_##name, \
 	TP_PROTO(const clientid_t *clid), \
 	TP_ARGS(clid))
 
+DEFINE_CLIENTID_EVENT(reclaim_complete);
+DEFINE_CLIENTID_EVENT(destroy);
 DEFINE_CLIENTID_EVENT(expired);
 DEFINE_CLIENTID_EVENT(purged);
 DEFINE_CLIENTID_EVENT(renew);
@@ -462,35 +538,6 @@ DEFINE_EVENT(nfsd_net_class, nfsd_##name, \
 DEFINE_NET_EVENT(grace_start);
 DEFINE_NET_EVENT(grace_complete);
 
-DECLARE_EVENT_CLASS(nfsd_clid_class,
-	TP_PROTO(const struct nfsd_net *nn,
-		 unsigned int namelen,
-		 const unsigned char *namedata),
-	TP_ARGS(nn, namelen, namedata),
-	TP_STRUCT__entry(
-		__field(unsigned long long, boot_time)
-		__field(unsigned int, namelen)
-		__dynamic_array(unsigned char,  name, namelen)
-	),
-	TP_fast_assign(
-		__entry->boot_time = nn->boot_time;
-		__entry->namelen = namelen;
-		memcpy(__get_dynamic_array(name), namedata, namelen);
-	),
-	TP_printk("boot_time=%16llx nfs4_clientid=%.*s",
-		__entry->boot_time, __entry->namelen, __get_str(name))
-)
-
-#define DEFINE_CLID_EVENT(name) \
-DEFINE_EVENT(nfsd_clid_class, nfsd_clid_##name, \
-	TP_PROTO(const struct nfsd_net *nn, \
-		 unsigned int namelen, \
-		 const unsigned char *namedata), \
-	TP_ARGS(nn, namelen, namedata))
-
-DEFINE_CLID_EVENT(find);
-DEFINE_CLID_EVENT(reclaim);
-
 TRACE_EVENT(nfsd_clid_inuse_err,
 	TP_PROTO(const struct nfs4_client *clp),
 	TP_ARGS(clp),
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 66499fb6b567..9267a4775263 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -763,6 +763,7 @@ void warn_on_nonidempotent_op(struct nfsd4_op *op);
 
 #define NFS4_SVC_XDRSIZE		sizeof(struct nfsd4_compoundargs)
 
+#ifdef CONFIG_NFSD_V3
 static inline void
 set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 {
@@ -778,7 +779,7 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 	cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
 
 }
-
+#endif /* CONFIG_NFSD_V3 */
 
 bool nfsd4_mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp);
 int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *);
diff --git a/include/trace/events/nfs.h b/include/trace/events/nfs.h
index 8e3de3b421f4..76f661e8cdf4 100644
--- a/include/trace/events/nfs.h
+++ b/include/trace/events/nfs.h
@@ -359,3 +359,25 @@ TRACE_DEFINE_ENUM(NFS_FILE_SYNC);
 		{ SEQ4_STATUS_RESTART_RECLAIM_NEEDED,	"RESTART_RECLAIM_NEEDED" }, \
 		{ SEQ4_STATUS_CB_PATH_DOWN_SESSION,	"CB_PATH_DOWN_SESSION" }, \
 		{ SEQ4_STATUS_BACKCHANNEL_FAULT,	"BACKCHANNEL_FAULT" })
+
+#define show_nfs4_exchgid4_flags(x) \
+	__print_flags(x, "|", \
+		{ EXCHGID4_FLAG_SUPP_MOVED_REFER,	"SUPP_MOVED_REFER" }, \
+		{ EXCHGID4_FLAG_SUPP_MOVED_MIGR,	"SUPP_MOVED_MIGR" }, \
+		{ EXCHGID4_FLAG_BIND_PRINC_STATEID,	"BIND_PRINC_STATEID" }, \
+		{ EXCHGID4_FLAG_USE_NON_PNFS,		"USE_NON_PNFS" }, \
+		{ EXCHGID4_FLAG_USE_PNFS_MDS,		"USE_PNFS_MDS" }, \
+		{ EXCHGID4_FLAG_USE_PNFS_DS,		"USE_PNFS_DS" }, \
+		{ EXCHGID4_FLAG_MASK_PNFS,		"MASK_PNFS" }, \
+		{ EXCHGID4_FLAG_UPD_CONFIRMED_REC_A,	"UPD_CONFIRMED_REC_A" }, \
+		{ EXCHGID4_FLAG_CONFIRMED_R,		"CONFIRMED_R" })
+
+TRACE_DEFINE_ENUM(SP4_NONE);
+TRACE_DEFINE_ENUM(SP4_MACH_CRED);
+TRACE_DEFINE_ENUM(SP4_SSV);
+
+#define show_nfs4_exchid4_spa_how(x) \
+	__print_symbolic(x, \
+		{ SP4_NONE,				"NONE" }, \
+		{ SP4_MACH_CRED,			"MACH_CRED" }, \
+		{ SP4_SSV,				"SSV" })



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

* [PATCH v2 16/27] NFSD: Add tracepoints to report NFSv4 session state
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (14 preceding siblings ...)
  2020-09-21 18:12 ` [PATCH v2 15/27] NFSD: Add client ID lifetime tracepoints Chuck Lever
@ 2020-09-21 18:12 ` Chuck Lever
  2020-09-21 18:12 ` [PATCH v2 17/27] NFSD: Add a tracepoint to report the current filehandle Chuck Lever
                   ` (11 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:12 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

These record the SEQ4 status flags and session slot and sequence
information for debugging purposes. Examples:

nfsd-1034  [001]   217.828352: nfsd4_create_session: xid=0x0059d52e client 5f611a66:37899067 sessionid=661a615f679089370300000000000000
nfsd-1034  [001]   217.830900: nfsd4_sequence:       xid=0x0159d52e sessionid=661a615f679089370300000000000000 seqid=1 slot=0/30 flags=

 ...

nfsd-1034  [002]   627.709041: nfsd4_destroy_session: xid=0x54bed52e sessionid=661a615f679089370300000000000000

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4state.c        |    6 ++
 fs/nfsd/trace.h            |  118 ++++++++++++++++++++++++++++++++++++++++++++
 include/trace/events/nfs.h |    7 +++
 3 files changed, 131 insertions(+)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 974b3303d2fc..f101202ed536 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3446,6 +3446,7 @@ nfsd4_create_session(struct svc_rqst *rqstp,
 	nfsd4_put_session(new);
 	if (old)
 		expire_client(old);
+	trace_nfsd4_create_session(rqstp, cr_ses);
 	return status;
 out_free_conn:
 	spin_unlock(&nn->client_lock);
@@ -3545,6 +3546,8 @@ __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
 	struct net *net = SVC_NET(rqstp);
 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
+	trace_nfsd4_bind_conn_to_session(rqstp, bcts);
+
 	if (!nfsd4_last_compound_op(rqstp))
 		return nfserr_not_only_op;
 	spin_lock(&nn->client_lock);
@@ -3591,6 +3594,8 @@ nfsd4_destroy_session(struct svc_rqst *r, struct nfsd4_compound_state *cstate,
 	struct net *net = SVC_NET(r);
 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
+	trace_nfsd4_destroy_session(r, sessionid);
+
 	status = nfserr_not_only_op;
 	if (nfsd4_compound_in_session(cstate, sessionid)) {
 		if (!nfsd4_last_compound_op(r))
@@ -3812,6 +3817,7 @@ nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	}
 	if (!list_empty(&clp->cl_revoked))
 		seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
+	trace_nfsd4_sequence(rqstp, seq);
 out_no_session:
 	if (conn)
 		free_conn(conn);
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 192d039da0ec..6f707e9f3786 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -368,6 +368,124 @@ TRACE_EVENT(nfsd4_exchange_id,
 	)
 );
 
+TRACE_EVENT(nfsd4_create_session,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct nfsd4_create_session *cr_ses
+	),
+	TP_ARGS(rqstp, cr_ses),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, cl_boot)
+		__field(u32, cl_id)
+		__array(unsigned char, sessionid, NFS4_MAX_SESSIONID_LEN)
+
+		__field(u32, fore_maxreqsz)
+		__field(u32, fore_maxrespsz)
+		__field(u32, fore_maxops)
+		__field(u32, fore_maxreps)
+
+		__field(u32, back_maxreqsz)
+		__field(u32, back_maxrespsz)
+		__field(u32, back_maxops)
+		__field(u32, back_maxreps)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->cl_boot = cr_ses->clientid.cl_boot;
+		__entry->cl_id = cr_ses->clientid.cl_id;
+		memcpy(__entry->sessionid, &cr_ses->sessionid,
+		       NFS4_MAX_SESSIONID_LEN);
+		__entry->fore_maxreqsz = cr_ses->fore_channel.maxreq_sz;
+		__entry->fore_maxrespsz = cr_ses->fore_channel.maxresp_sz;
+		__entry->fore_maxops = cr_ses->fore_channel.maxops;
+		__entry->fore_maxreps = cr_ses->fore_channel.maxreqs;
+		__entry->back_maxreqsz = cr_ses->back_channel.maxreq_sz;
+		__entry->back_maxrespsz = cr_ses->back_channel.maxresp_sz;
+		__entry->back_maxops = cr_ses->back_channel.maxops;
+		__entry->back_maxreps = cr_ses->back_channel.maxreqs;
+	),
+	TP_printk("xid=0x%08x client=%08x:%08x sessionid=%s",
+		__entry->xid, __entry->cl_boot, __entry->cl_id,
+		__print_hex_str(__entry->sessionid, NFS4_MAX_SESSIONID_LEN)
+	)
+);
+
+TRACE_EVENT(nfsd4_bind_conn_to_session,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct nfsd4_bind_conn_to_session *bcts
+	),
+	TP_ARGS(rqstp, bcts),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(unsigned long, dir)
+		__array(unsigned char, sessionid, NFS4_MAX_SESSIONID_LEN)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->dir = bcts->dir;
+		memcpy(__entry->sessionid, &bcts->sessionid,
+		       NFS4_MAX_SESSIONID_LEN);
+	),
+	TP_printk("xid=0x%08x sessionid=%s, dir=%s",
+		__entry->xid,
+		__print_hex_str(__entry->sessionid, NFS4_MAX_SESSIONID_LEN),
+		show_nfs4_bcts_dir(__entry->dir)
+	)
+);
+
+TRACE_EVENT(nfsd4_destroy_session,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct nfs4_sessionid *sessionid
+	),
+	TP_ARGS(rqstp, sessionid),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__array(unsigned char, sessionid, NFS4_MAX_SESSIONID_LEN)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		memcpy(__entry->sessionid, sessionid, NFS4_MAX_SESSIONID_LEN);
+	),
+	TP_printk("xid=0x%08x sessionid=%s",
+		__entry->xid,
+		__print_hex_str(__entry->sessionid, NFS4_MAX_SESSIONID_LEN)
+	)
+);
+
+TRACE_EVENT(nfsd4_sequence,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct nfsd4_sequence *seq
+	),
+	TP_ARGS(rqstp, seq),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, seqid)
+		__field(u32, slotid)
+		__field(u32, maxslots)
+		__field(unsigned long, flags)
+		__array(unsigned char, sessionid, NFS4_MAX_SESSIONID_LEN)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->seqid = seq->seqid;
+		__entry->slotid = seq->slotid;
+		__entry->maxslots = seq->maxslots;
+		__entry->flags = seq->status_flags;
+		memcpy(__entry->sessionid, &seq->sessionid,
+		       NFS4_MAX_SESSIONID_LEN);
+	),
+	TP_printk("xid=0x%08x sessionid=%s slot=%u/%u seqid=%u flags=%s",
+		__entry->xid,
+		__print_hex_str(__entry->sessionid, NFS4_MAX_SESSIONID_LEN),
+		__entry->slotid, __entry->maxslots, __entry->seqid,
+		show_nfs4_seq4_status(__entry->flags)
+	)
+);
+
 TRACE_EVENT(nfsd4_compound,
 	TP_PROTO(
 		const struct svc_rqst *rqstp,
diff --git a/include/trace/events/nfs.h b/include/trace/events/nfs.h
index 76f661e8cdf4..a152ed94e538 100644
--- a/include/trace/events/nfs.h
+++ b/include/trace/events/nfs.h
@@ -381,3 +381,10 @@ TRACE_DEFINE_ENUM(SP4_SSV);
 		{ SP4_NONE,				"NONE" }, \
 		{ SP4_MACH_CRED,			"MACH_CRED" }, \
 		{ SP4_SSV,				"SSV" })
+
+#define show_nfs4_bcts_dir(x) \
+	__print_symbolic(x, \
+		{ NFS4_CDFC4_FORE,			"FORE" }, \
+		{ NFS4_CDFC4_BACK,			"BACK" }, \
+		{ NFS4_CDFC4_FORE_OR_BOTH,		"FORE_OR_BOTH" }, \
+		{ NFS4_CDFC4_BACK_OR_BOTH,		"BACK_OR_BOTH" })



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

* [PATCH v2 17/27] NFSD: Add a tracepoint to report the current filehandle
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (15 preceding siblings ...)
  2020-09-21 18:12 ` [PATCH v2 16/27] NFSD: Add tracepoints to report NFSv4 session state Chuck Lever
@ 2020-09-21 18:12 ` Chuck Lever
  2020-09-21 18:12 ` [PATCH v2 18/27] NFSD: Add GETATTR tracepoint Chuck Lever
                   ` (10 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:12 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Expose the "current_fh", which is an implicit argument in many NFSv4
operations. I've tried to insert this tracepoint at each place that
can change the current filehandle. Typically:

nfsd-1034  [000]   165.214516: nfsd_compound:        xid=0x012e9610 opcnt=3
nfsd-1034  [000]   165.214518: nfsd_fh_current:      xid=0x012e9610 fh_hash=0x90351828 name=Makefile
nfsd-1034  [000]   165.214581: nfsd_compound_status: xid=0x012e9610 op=1/3 OP_PUTFH status=OK

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4proc.c |   22 ++++++++++++++++++----
 fs/nfsd/trace.h    |   31 +++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 17a627f97766..e378aa91ba46 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -467,6 +467,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	}
 	nfsd4_cleanup_open_state(cstate, open);
 	nfsd4_bump_seqid(cstate, status);
+	trace_nfsd4_fh_current(rqstp, &cstate->current_fh);
 	return status;
 }
 
@@ -517,6 +518,7 @@ nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		ret = 0;
 	}
 #endif
+	trace_nfsd4_fh_current(rqstp, &cstate->current_fh);
 	return ret;
 }
 
@@ -528,6 +530,7 @@ nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
 	fh_put(&cstate->current_fh);
 	status = exp_pseudoroot(rqstp, &cstate->current_fh);
+	trace_nfsd4_fh_current(rqstp, &cstate->current_fh);
 	return status;
 }
 
@@ -543,6 +546,7 @@ nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		memcpy(&cstate->current_stateid, &cstate->save_stateid, sizeof(stateid_t));
 		SET_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG);
 	}
+	trace_nfsd4_fh_current(rqstp, &cstate->current_fh);
 	return nfs_ok;
 }
 
@@ -687,6 +691,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	fh_unlock(&cstate->current_fh);
 	set_change_info(&create->cr_cinfo, &cstate->current_fh);
 	fh_dup2(&cstate->current_fh, &resfh);
+	trace_nfsd4_fh_current(rqstp, &cstate->current_fh);
 out:
 	fh_put(&resfh);
 out_umask:
@@ -751,16 +756,24 @@ static __be32
 nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	      union nfsd4_op_u *u)
 {
-	return nfsd4_do_lookupp(rqstp, &cstate->current_fh);
+	__be32 status;
+
+	status = nfsd4_do_lookupp(rqstp, &cstate->current_fh);
+	trace_nfsd4_fh_current(rqstp, &cstate->current_fh);
+	return status;
 }
 
 static __be32
 nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	     union nfsd4_op_u *u)
 {
-	return nfsd_lookup(rqstp, &cstate->current_fh,
-			   u->lookup.lo_name, u->lookup.lo_len,
-			   &cstate->current_fh);
+	__be32 status;
+
+	status = nfsd_lookup(rqstp, &cstate->current_fh,
+			     u->lookup.lo_name, u->lookup.lo_len,
+			     &cstate->current_fh);
+	trace_nfsd4_fh_current(rqstp, &cstate->current_fh);
+	return status;
 }
 
 static __be32
@@ -928,6 +941,7 @@ nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstat
 		err = nfsd4_do_lookupp(rqstp, &cstate->current_fh);
 		if (err)
 			return err;
+		trace_nfsd4_fh_current(rqstp, &cstate->current_fh);
 		break;
 	default:
 		return nfserr_inval;
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 6f707e9f3786..c2e72b880e6a 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -533,6 +533,37 @@ TRACE_EVENT(nfsd4_compoundstatus,
 	)
 )
 
+TRACE_EVENT(nfsd4_fh_current,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct svc_fh *fhp
+	),
+	TP_ARGS(rqstp, fhp),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, fh_hash)
+		__dynamic_array(unsigned char, name,
+				fhp->fh_dentry ?
+				fhp->fh_dentry->d_name.len + 1 : 0)
+	),
+	TP_fast_assign(
+		const struct dentry *dentry = fhp->fh_dentry;
+
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->fh_hash = knfsd_fh_hash(&fhp->fh_handle);
+		if (dentry) {
+			memcpy(__get_str(name), dentry->d_name.name,
+			       dentry->d_name.len);
+			__get_str(name)[dentry->d_name.len] = '\0';
+		} else {
+			__get_str(name)[0] = '\0';
+		}
+	),
+	TP_printk("xid=0x%08x fh_hash=0x%08x name=%s",
+		__entry->xid, __entry->fh_hash, __get_str(name)
+	)
+);
+
 #include "state.h"
 #include "filecache.h"
 #include "vfs.h"



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

* [PATCH v2 18/27] NFSD: Add GETATTR tracepoint
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (16 preceding siblings ...)
  2020-09-21 18:12 ` [PATCH v2 17/27] NFSD: Add a tracepoint to report the current filehandle Chuck Lever
@ 2020-09-21 18:12 ` Chuck Lever
  2020-09-21 18:12 ` [PATCH v2 19/27] NFSD: Add tracepoint in nfsd4_stateid_preprocess() Chuck Lever
                   ` (9 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:12 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Record the set of attributes requested by an NFSv4 client in an
NFSv4 GETATTR request.

nfsd-1034  [002]   164.067026: nfsd_get_fattr4:      xid=0xcb4c4e33 bm[0]=TYPE|CHANGE|SIZE|FSID|FILEID bm[1]=MODE|NUMLINKS|OWNER|OWNER_GROUP|RAWDEV|SPACE_USED|TIME_ACCESS|TIME_METADATA|TIME_MODIFY|MOUNTED_ON_FILEID bm[2]=

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4proc.c         |    2 +
 fs/nfsd/trace.h            |   26 +++++++++++++++
 include/trace/events/nfs.h |   75 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 103 insertions(+)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index e378aa91ba46..065ed5930250 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -706,6 +706,8 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	struct nfsd4_getattr *getattr = &u->getattr;
 	__be32 status;
 
+	trace_nfsd4_getattr(rqstp, getattr->ga_bmval);
+
 	status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP);
 	if (status)
 		return status;
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index c2e72b880e6a..4fb668257ce2 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -564,6 +564,32 @@ TRACE_EVENT(nfsd4_fh_current,
 	)
 );
 
+TRACE_EVENT(nfsd4_getattr,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const u32 *bitmask
+	),
+	TP_ARGS(rqstp, bitmask),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(unsigned long, bm0)
+		__field(unsigned long, bm1)
+		__field(unsigned long, bm2)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->bm0 = bitmask[0];
+		__entry->bm1 = bitmask[1];
+		__entry->bm2 = bitmask[2];
+	),
+	TP_printk("xid=0x%08x bm[0]=%s bm[1]=%s bm[2]=%s",
+		__entry->xid,
+		show_nfs4_fattr4_bm_word0(__entry->bm0),
+		show_nfs4_fattr4_bm_word1(__entry->bm1),
+		show_nfs4_fattr4_bm_word2(__entry->bm2)
+	)
+);
+
 #include "state.h"
 #include "filecache.h"
 #include "vfs.h"
diff --git a/include/trace/events/nfs.h b/include/trace/events/nfs.h
index a152ed94e538..19f7444e4bb2 100644
--- a/include/trace/events/nfs.h
+++ b/include/trace/events/nfs.h
@@ -388,3 +388,78 @@ TRACE_DEFINE_ENUM(SP4_SSV);
 		{ NFS4_CDFC4_BACK,			"BACK" }, \
 		{ NFS4_CDFC4_FORE_OR_BOTH,		"FORE_OR_BOTH" }, \
 		{ NFS4_CDFC4_BACK_OR_BOTH,		"BACK_OR_BOTH" })
+
+#define show_nfs4_fattr4_bm_word0(x) \
+	__print_flags(x, "|", \
+		{ FATTR4_WORD0_SUPPORTED_ATTRS,		"SUPPORTED_ATTRS" }, \
+		{ FATTR4_WORD0_TYPE,			"TYPE" }, \
+		{ FATTR4_WORD0_FH_EXPIRE_TYPE,		"FH_EXPIRE_TYPE" }, \
+		{ FATTR4_WORD0_CHANGE,			"CHANGE" }, \
+		{ FATTR4_WORD0_SIZE,			"SIZE" }, \
+		{ FATTR4_WORD0_LINK_SUPPORT,		"LINK_SUPPORT" }, \
+		{ FATTR4_WORD0_SYMLINK_SUPPORT,		"SYMLINK_SUPPORT" }, \
+		{ FATTR4_WORD0_NAMED_ATTR,		"NAMED_ATTR" }, \
+		{ FATTR4_WORD0_FSID,			"FSID" }, \
+		{ FATTR4_WORD0_UNIQUE_HANDLES,		"UNIQUE_HANDLES" }, \
+		{ FATTR4_WORD0_LEASE_TIME,		"LEASE_TIME" }, \
+		{ FATTR4_WORD0_RDATTR_ERROR,		"RDATTR_ERROR" }, \
+		{ FATTR4_WORD0_ACL,			"ACL" }, \
+		{ FATTR4_WORD0_ACLSUPPORT,		"ACLSUPPORT" }, \
+		{ FATTR4_WORD0_ARCHIVE,			"ARCHIVE" }, \
+		{ FATTR4_WORD0_CANSETTIME,		"CANSETTIME" }, \
+		{ FATTR4_WORD0_CASE_INSENSITIVE,	"CASE_INSENSITIVE" }, \
+		{ FATTR4_WORD0_CASE_PRESERVING,		"CASE_PRESERVING" }, \
+		{ FATTR4_WORD0_CHOWN_RESTRICTED,	"CHOWN_RESTRICTED" }, \
+		{ FATTR4_WORD0_FILEHANDLE,		"FILEHANDLE" }, \
+		{ FATTR4_WORD0_FILEID,			"FILEID" }, \
+		{ FATTR4_WORD0_FILES_AVAIL,		"FILES_AVAIL" }, \
+		{ FATTR4_WORD0_FILES_FREE,		"FILES_FREE" }, \
+		{ FATTR4_WORD0_FILES_TOTAL,		"FILES_TOTAL" }, \
+		{ FATTR4_WORD0_FS_LOCATIONS,		"FS_LOCATIONS" }, \
+		{ FATTR4_WORD0_HIDDEN,			"HIDDEN" }, \
+		{ FATTR4_WORD0_HOMOGENEOUS,		"HOMOGENEOUS" }, \
+		{ FATTR4_WORD0_MAXFILESIZE,		"MAXFILESIZE" }, \
+		{ FATTR4_WORD0_MAXLINK,			"MAXLINK" }, \
+		{ FATTR4_WORD0_MAXNAME,			"MAXNAME" }, \
+		{ FATTR4_WORD0_MAXREAD,			"MAXREAD" }, \
+		{ FATTR4_WORD0_MAXWRITE,		"MAXWRITE" })
+
+#define show_nfs4_fattr4_bm_word1(x) \
+	__print_flags(x, "|", \
+		{ FATTR4_WORD1_MIMETYPE,		"MIMETYPE" }, \
+		{ FATTR4_WORD1_MODE,			"MODE" }, \
+		{ FATTR4_WORD1_NO_TRUNC,		"NO_TRUNC" }, \
+		{ FATTR4_WORD1_NUMLINKS,		"NUMLINKS" }, \
+		{ FATTR4_WORD1_OWNER,			"OWNER" }, \
+		{ FATTR4_WORD1_OWNER_GROUP,		"OWNER_GROUP" }, \
+		{ FATTR4_WORD1_QUOTA_HARD,		"QUOTA_HARD" }, \
+		{ FATTR4_WORD1_QUOTA_SOFT,		"QUOTA_SOFT" }, \
+		{ FATTR4_WORD1_QUOTA_USED,		"QUOTA_USED" }, \
+		{ FATTR4_WORD1_RAWDEV,			"RAWDEV" }, \
+		{ FATTR4_WORD1_SPACE_AVAIL,		"SPACE_AVAIL" }, \
+		{ FATTR4_WORD1_SPACE_FREE,		"SPACE_FREE" }, \
+		{ FATTR4_WORD1_SPACE_TOTAL,		"SPACE_TOTAL" }, \
+		{ FATTR4_WORD1_SPACE_USED,		"SPACE_USED" }, \
+		{ FATTR4_WORD1_SYSTEM,			"SYSTEM" }, \
+		{ FATTR4_WORD1_TIME_ACCESS,		"TIME_ACCESS" }, \
+		{ FATTR4_WORD1_TIME_ACCESS_SET,		"TIME_ACCESS_SET" }, \
+		{ FATTR4_WORD1_TIME_BACKUP,		"TIME_BACKUP" }, \
+		{ FATTR4_WORD1_TIME_CREATE,		"TIME_CREATE" }, \
+		{ FATTR4_WORD1_TIME_DELTA,		"TIME_DELTA" }, \
+		{ FATTR4_WORD1_TIME_METADATA,		"TIME_METADATA" }, \
+		{ FATTR4_WORD1_TIME_MODIFY,		"TIME_MODIFY" }, \
+		{ FATTR4_WORD1_TIME_MODIFY_SET,		"TIME_MODIFY_SET" }, \
+		{ FATTR4_WORD1_MOUNTED_ON_FILEID,	"MOUNTED_ON_FILEID" }, \
+		{ FATTR4_WORD1_FS_LAYOUT_TYPES,		"FS_LAYOUT_TYPES" })
+
+#define show_nfs4_fattr4_bm_word2(x) \
+	__print_flags(x, "|", \
+		{ FATTR4_WORD2_LAYOUT_TYPES,		"LAYOUT_TYPES" }, \
+		{ FATTR4_WORD2_LAYOUT_BLKSIZE,		"LAYOUT_BLKSIZE" }, \
+		{ FATTR4_WORD2_MDSTHRESHOLD,		"MDSTHRESHOLD" }, \
+		{ FATTR4_WORD2_SUPPATTR_EXCLCREAT,	"SUPPATTR_EXCLCREAT" }, \
+		{ FATTR4_WORD2_CLONE_BLKSIZE,		"CLONE_BLKSIZE" }, \
+		{ FATTR4_WORD2_CHANGE_ATTR_TYPE,	"CHANGE_ATTR_TYPE" }, \
+		{ FATTR4_WORD2_SECURITY_LABEL,		"SECURITY_LABEL" }, \
+		{ FATTR4_WORD2_MODE_UMASK,		"MODE_UMASK" }, \
+		{ FATTR4_WORD2_XATTR_SUPPORT,		"XATTR_SUPPORT" })



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

* [PATCH v2 19/27] NFSD: Add tracepoint in nfsd4_stateid_preprocess()
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (17 preceding siblings ...)
  2020-09-21 18:12 ` [PATCH v2 18/27] NFSD: Add GETATTR tracepoint Chuck Lever
@ 2020-09-21 18:12 ` Chuck Lever
  2020-09-21 18:12 ` [PATCH v2 20/27] NFSD: Add tracepoint to report arguments to NFSv4 OPEN Chuck Lever
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:12 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Record the stateid being processed by each COMPOUND.

nfsd-1033  [003]   165.199589: nfsd_stateid_prep:    xid=0xeb2d9610 client 5f4fdc70:dbdb3569 stateid 00000001:00000002 status=OK

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4state.c |   24 ++++++++++++++----------
 fs/nfsd/trace.h     |   34 ++++++++++++++++++++++++++++++++--
 2 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index f101202ed536..0cc928328c22 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -5881,12 +5881,14 @@ nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
 	if (nfp)
 		*nfp = NULL;
 
-	if (grace_disallows_io(net, ino))
-		return nfserr_grace;
+	if (grace_disallows_io(net, ino)) {
+		status = nfserr_grace;
+		goto out;
+	}
 
 	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
 		status = check_special_stateids(net, fhp, stateid, flags);
-		goto done;
+		goto out_check;
 	}
 
 	status = nfsd4_lookup_stateid(cstate, stateid,
@@ -5895,11 +5897,11 @@ nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
 	if (status == nfserr_bad_stateid)
 		status = find_cpntf_state(nn, stateid, &s);
 	if (status)
-		return status;
+		goto out;
 	status = nfsd4_stid_check_stateid_generation(stateid, s,
 			nfsd4_has_session(cstate));
 	if (status)
-		goto out;
+		goto out_put;
 
 	switch (s->sc_type) {
 	case NFS4_DELEG_STID:
@@ -5914,19 +5916,21 @@ nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
 		break;
 	}
 	if (status)
-		goto out;
+		goto out_put;
 	status = nfs4_check_fh(fhp, s);
 
-done:
+out_check:
 	if (status == nfs_ok && nfp)
 		status = nfs4_check_file(rqstp, fhp, s, nfp, flags);
-out:
+out_put:
 	if (s) {
 		if (!status && cstid)
 			*cstid = s;
 		else
 			nfs4_put_stid(s);
 	}
+out:
+	trace_nfsd4_stateid_prep(rqstp, stateid, status);
 	return status;
 }
 
@@ -6066,7 +6070,7 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
 	struct nfs4_stid *s;
 	struct nfs4_ol_stateid *stp = NULL;
 
-	trace_nfsd_preprocess(seqid, stateid);
+	trace_nfsd4_seqid_prep(seqid, stateid);
 
 	*stpp = NULL;
 	status = nfsd4_lookup_stateid(cstate, stateid, typemask, &s, nn);
@@ -6135,7 +6139,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	oo->oo_flags |= NFS4_OO_CONFIRMED;
 	nfs4_inc_and_copy_stateid(&oc->oc_resp_stateid, &stp->st_stid);
 	mutex_unlock(&stp->st_mutex);
-	trace_nfsd_open_confirm(oc->oc_seqid, &stp->st_stid.sc_stateid);
+	trace_nfsd4_open_confirm(oc->oc_seqid, &stp->st_stid.sc_stateid);
 	nfsd4_client_record_create(oo->oo_owner.so_client);
 	status = nfs_ok;
 put_stateid:
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 4fb668257ce2..be5fc0ce3c13 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -594,6 +594,36 @@ TRACE_EVENT(nfsd4_getattr,
 #include "filecache.h"
 #include "vfs.h"
 
+TRACE_EVENT(nfsd4_stateid_prep,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const stateid_t *stp,
+		__be32 status
+	),
+	TP_ARGS(rqstp, stp, status),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, cl_boot)
+		__field(u32, cl_id)
+		__field(u32, si_id)
+		__field(u32, si_generation)
+		__field(unsigned long, status)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->cl_boot = stp->si_opaque.so_clid.cl_boot;
+		__entry->cl_id = stp->si_opaque.so_clid.cl_id;
+		__entry->si_id = stp->si_opaque.so_id;
+		__entry->si_generation = stp->si_generation;
+		__entry->status = be32_to_cpu(status);
+	),
+	TP_printk("xid=0x%08x client %08x:%08x stateid %08x:%08x status=%s",
+		__entry->xid, __entry->cl_boot, __entry->cl_id,
+		__entry->si_id, __entry->si_generation,
+		show_nfs4_status(__entry->status)
+	)
+);
+
 DECLARE_EVENT_CLASS(nfsd_stateid_class,
 	TP_PROTO(stateid_t *stp),
 	TP_ARGS(stp),
@@ -660,11 +690,11 @@ DECLARE_EVENT_CLASS(nfsd_stateseqid_class,
 )
 
 #define DEFINE_STATESEQID_EVENT(name) \
-DEFINE_EVENT(nfsd_stateseqid_class, nfsd_##name, \
+DEFINE_EVENT(nfsd_stateseqid_class, nfsd4_##name, \
 	TP_PROTO(u32 seqid, const stateid_t *stp), \
 	TP_ARGS(seqid, stp))
 
-DEFINE_STATESEQID_EVENT(preprocess);
+DEFINE_STATESEQID_EVENT(seqid_prep);
 DEFINE_STATESEQID_EVENT(open_confirm);
 
 DECLARE_EVENT_CLASS(nfsd_clientid_class,



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

* [PATCH v2 20/27] NFSD: Add tracepoint to report arguments to NFSv4 OPEN
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (18 preceding siblings ...)
  2020-09-21 18:12 ` [PATCH v2 19/27] NFSD: Add tracepoint in nfsd4_stateid_preprocess() Chuck Lever
@ 2020-09-21 18:12 ` Chuck Lever
  2020-09-21 18:12 ` [PATCH v2 21/27] NFSD: Add a tracepoint for DELEGRETURN Chuck Lever
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:12 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Surface the open create type and claim type, as well as the XID and
the file handle and open sequence number.

            nfsd-1025  [001]   257.085227: nfsd_open_args:       xid=0x08157d7a fh_hash=0x1ac91976 seqid=97 type=CREATE claim=NULL

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4proc.c         |    4 +--
 fs/nfsd/nfs4state.c        |    3 +-
 fs/nfsd/trace.h            |   55 ++++++++++++++++++++++++++++++++++++++++++++
 include/trace/events/nfs.h |   32 ++++++++++++++++++++++++++
 4 files changed, 89 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 065ed5930250..914eb3f2a233 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -358,9 +358,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 	bool reclaim = false;
 
-	dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
-		(int)open->op_fname.len, open->op_fname.data,
-		open->op_openowner);
+	trace_nfsd4_open(rqstp, open);
 
 	/* This check required by spec. */
 	if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 0cc928328c22..47790c7a29a3 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -6184,8 +6184,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
 	struct nfs4_ol_stateid *stp;
 	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 
-	dprintk("NFSD: nfsd4_open_downgrade on file %pd\n", 
-			cstate->current_fh.fh_dentry);
+	trace_nfsd4_open_downgrade(rqstp, od);
 
 	/* We don't yet support WANT bits: */
 	if (od->od_deleg_want)
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index be5fc0ce3c13..18b359a04d96 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -594,6 +594,61 @@ TRACE_EVENT(nfsd4_getattr,
 #include "filecache.h"
 #include "vfs.h"
 
+TRACE_EVENT(nfsd4_open,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct nfsd4_open *open
+	),
+	TP_ARGS(rqstp, open),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, seqid)
+		__field(unsigned long, create)
+		__field(unsigned long, claim)
+		__field(unsigned long, share)
+		__dynamic_array(unsigned char, name, open->op_fname.len + 1)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->seqid = open->op_seqid;
+		__entry->create = open->op_create;
+		__entry->claim = open->op_claim_type;
+		__entry->share = open->op_share_access;
+		memcpy(__get_str(name), open->op_fname.data,
+		       open->op_fname.len);
+		__get_str(name)[open->op_fname.len] = '\0';
+	),
+	TP_printk("xid=0x%08x seqid=%u type=%s claim=%s share=%s name=%s",
+		__entry->xid, __entry->seqid,
+		show_nfs4_open_create(__entry->create),
+		show_nfs4_open_claimtype(__entry->claim),
+		show_nfs4_open_sharedeny_flags(__entry->share),
+		__get_str(name)
+	)
+);
+
+TRACE_EVENT(nfsd4_open_downgrade,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct nfsd4_open_downgrade *open
+	),
+	TP_ARGS(rqstp, open),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, seqid)
+		__field(unsigned long, share)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->seqid = open->od_seqid;
+		__entry->share = open->od_share_access;
+	),
+	TP_printk("xid=0x%08x seqid=%u share=%s",
+		__entry->xid, __entry->seqid,
+		show_nfs4_open_sharedeny_flags(__entry->share)
+	)
+);
+
 TRACE_EVENT(nfsd4_stateid_prep,
 	TP_PROTO(
 		const struct svc_rqst *rqstp,
diff --git a/include/trace/events/nfs.h b/include/trace/events/nfs.h
index 19f7444e4bb2..e6da77eb95b5 100644
--- a/include/trace/events/nfs.h
+++ b/include/trace/events/nfs.h
@@ -463,3 +463,35 @@ TRACE_DEFINE_ENUM(SP4_SSV);
 		{ FATTR4_WORD2_SECURITY_LABEL,		"SECURITY_LABEL" }, \
 		{ FATTR4_WORD2_MODE_UMASK,		"MODE_UMASK" }, \
 		{ FATTR4_WORD2_XATTR_SUPPORT,		"XATTR_SUPPORT" })
+
+TRACE_DEFINE_ENUM(NFS4_OPEN_NOCREATE);
+TRACE_DEFINE_ENUM(NFS4_OPEN_CREATE);
+
+#define show_nfs4_open_create(x) \
+	__print_symbolic(x, \
+		{ NFS4_OPEN_NOCREATE,			"NOCREATE" }, \
+		{ NFS4_OPEN_CREATE,			"CREATE" })
+
+TRACE_DEFINE_ENUM(NFS4_OPEN_CLAIM_NULL);
+TRACE_DEFINE_ENUM(NFS4_OPEN_CLAIM_PREVIOUS);
+TRACE_DEFINE_ENUM(NFS4_OPEN_CLAIM_DELEGATE_CUR);
+TRACE_DEFINE_ENUM(NFS4_OPEN_CLAIM_DELEGATE_PREV);
+TRACE_DEFINE_ENUM(NFS4_OPEN_CLAIM_FH);
+TRACE_DEFINE_ENUM(NFS4_OPEN_CLAIM_DELEG_CUR_FH);
+TRACE_DEFINE_ENUM(NFS4_OPEN_CLAIM_DELEG_PREV_FH);
+
+#define show_nfs4_open_claimtype(x) \
+	__print_symbolic(x, \
+		{ NFS4_OPEN_CLAIM_NULL,			"NULL" }, \
+		{ NFS4_OPEN_CLAIM_PREVIOUS,		"PREVIOUS" }, \
+		{ NFS4_OPEN_CLAIM_DELEGATE_CUR,		"DELEGATE_CUR" }, \
+		{ NFS4_OPEN_CLAIM_DELEGATE_PREV,	"DELEGATE_PREV" }, \
+		{ NFS4_OPEN_CLAIM_FH,			"FH" }, \
+		{ NFS4_OPEN_CLAIM_DELEG_CUR_FH,		"DELEG_CUR_FH" }, \
+		{ NFS4_OPEN_CLAIM_DELEG_PREV_FH,	"DELEG_PREV_FH" })
+
+#define show_nfs4_open_sharedeny_flags(x) \
+	__print_symbolic(x, \
+		{ NFS4_SHARE_ACCESS_READ,		"READ" }, \
+		{ NFS4_SHARE_ACCESS_WRITE,		"WRITE" }, \
+		{ NFS4_SHARE_ACCESS_BOTH,		"BOTH" })



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

* [PATCH v2 21/27] NFSD: Add a tracepoint for DELEGRETURN
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (19 preceding siblings ...)
  2020-09-21 18:12 ` [PATCH v2 20/27] NFSD: Add tracepoint to report arguments to NFSv4 OPEN Chuck Lever
@ 2020-09-21 18:12 ` Chuck Lever
  2020-09-21 18:12 ` [PATCH v2 22/27] NFSD: Add a lookup tracepoint Chuck Lever
                   ` (6 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:12 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Record the stateid being returned to help troubleshoot problems
with delegation. The status code is reported by the
nfsd_compound_status tracepoint.

nfsd-1035  [002]    75.873544: nfsd4_delegreturn:    xid=0x6575fc16 client 5f68de0f:f04d8b16 stateid 0000005c:00000001
nfsd-1035  [002]    75.873574: nfsd_file_put:        hash=0xac7 inode=0xffff8887050d7470 ref=1 flags=REFERENCED may=READ file=0xffff888717a79680
nfsd-1035  [002]    75.873575: nfsd_file_put_final:  hash=0xac7 inode=0xffff8887050d7470 ref=0 flags=REFERENCED may=READ file=0xffff888717a79680
nfsd-1035  [002]    75.873601: nfsd4_compoundstatus: xid=0x6575fc16 op=4/4 OP_DELEGRETURN status=OK

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4state.c |    2 ++
 fs/nfsd/trace.h     |   26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 47790c7a29a3..992ac867e52e 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -6303,6 +6303,8 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	__be32 status;
 	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 
+	trace_nfsd4_delegreturn(rqstp, stateid);
+
 	if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
 		return status;
 
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 18b359a04d96..234b4ea7a4c7 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -679,6 +679,32 @@ TRACE_EVENT(nfsd4_stateid_prep,
 	)
 );
 
+TRACE_EVENT(nfsd4_delegreturn,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const stateid_t *stp
+	),
+	TP_ARGS(rqstp, stp),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, cl_boot)
+		__field(u32, cl_id)
+		__field(u32, si_id)
+		__field(u32, si_generation)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->cl_boot = stp->si_opaque.so_clid.cl_boot;
+		__entry->cl_id = stp->si_opaque.so_clid.cl_id;
+		__entry->si_id = stp->si_opaque.so_id;
+		__entry->si_generation = stp->si_generation;
+	),
+	TP_printk("xid=0x%08x client %08x:%08x stateid %08x:%08x",
+		__entry->xid, __entry->cl_boot, __entry->cl_id,
+		__entry->si_id, __entry->si_generation
+	)
+);
+
 DECLARE_EVENT_CLASS(nfsd_stateid_class,
 	TP_PROTO(stateid_t *stp),
 	TP_ARGS(stp),



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

* [PATCH v2 22/27] NFSD: Add a lookup tracepoint
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (20 preceding siblings ...)
  2020-09-21 18:12 ` [PATCH v2 21/27] NFSD: Add a tracepoint for DELEGRETURN Chuck Lever
@ 2020-09-21 18:12 ` Chuck Lever
  2020-09-21 18:12 ` [PATCH v2 23/27] NFSD: Add lock and locku tracepoints Chuck Lever
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:12 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Unfortunately, some callers pass the same memory as the input and
result FH argument. This means we can't capture both and the status
code with a single tracepoint. The status code is recorded by other
existing tracepoints (for example in the SVC layer).

Also note that RFC 5661 S. 18.13.3 explicitly states that:

"if the object exists, the current filehandle is replaced with the
component’s filehandle... " otherwise "... an error will be returned
and the current filehandle will be unchanged."

Given that nfsd4_lookup() passes &cstate->current_fh as both the
input and output arguement, the current filehandle is set even in
the error case. This is probably not behaviorally consequential
because COMPOUND processing stops as soon as an operation fails, but
it is not compliant with the spec language.

NFSv2/3:
nfsd-1035  [001]  1162.390149: nfsd_lookup:          xid=0x8c2e5fd5 parent fh_hash=0xcf756a3e \
	name=Makefile result fh_hash=0x00000000 status=NOENT


NFSv4:
nfsd-1035  [003]    72.687149: nfsd4_lookup:         xid=0x8673fc16 name=Makefile status=ENOENT
nfsd-1035  [003]    72.687150: nfsd4_fh_current:     xid=0x8673fc16 fh_hash=0x5f73bc5d name=Makefile
nfsd-1035  [003]    72.687151: nfsd4_compoundstatus: xid=0x8673fc16 op=3/5 OP_LOOKUP status=ENOENT

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3proc.c |    3 +++
 fs/nfsd/nfs4proc.c |    1 +
 fs/nfsd/nfsproc.c  |    3 +++
 fs/nfsd/trace.h    |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/nfsd/vfs.c      |   15 ++++++++++----
 5 files changed, 75 insertions(+), 4 deletions(-)

diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 02f6bb6d749e..7d6667024440 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -12,6 +12,7 @@
 #include "cache.h"
 #include "xdr3.h"
 #include "vfs.h"
+#include "trace.h"
 
 #define NFSDDBG_FACILITY		NFSDDBG_PROC
 
@@ -102,6 +103,8 @@ nfsd3_proc_lookup(struct svc_rqst *rqstp)
 				    argp->name,
 				    argp->len,
 				    &resp->fh);
+	trace_nfsd_lookup(rqstp, &resp->dirfh, argp->name, argp->len,
+			  &resp->fh, nfserr);
 	RETURN_STATUS(nfserr);
 }
 
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 914eb3f2a233..c4fa121560ae 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -772,6 +772,7 @@ nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	status = nfsd_lookup(rqstp, &cstate->current_fh,
 			     u->lookup.lo_name, u->lookup.lo_len,
 			     &cstate->current_fh);
+	trace_nfsd4_lookup(rqstp, u->lookup.lo_name, u->lookup.lo_len, status);
 	trace_nfsd4_fh_current(rqstp, &cstate->current_fh);
 	return status;
 }
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index fd78651bd21d..5657f2523559 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -10,6 +10,7 @@
 #include "cache.h"
 #include "xdr.h"
 #include "vfs.h"
+#include "trace.h"
 
 typedef struct svc_rqst	svc_rqst;
 typedef struct svc_buf	svc_buf;
@@ -137,6 +138,8 @@ nfsd_proc_lookup(struct svc_rqst *rqstp)
 	fh_init(&resp->fh, NFS_FHSIZE);
 	nfserr = nfsd_lookup(rqstp, &argp->fh, argp->name, argp->len,
 				 &resp->fh);
+	trace_nfsd_lookup(rqstp, &argp->fh, argp->name, argp->len,
+			  &resp->fh, nfserr);
 
 	fh_put(&argp->fh);
 	return nfsd_return_dirop(nfserr, resp);
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 234b4ea7a4c7..5c37112106c6 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -76,6 +76,38 @@ TRACE_EVENT(nfsd_access,
 	)
 );
 
+TRACE_EVENT(nfsd_lookup,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct svc_fh *parent,
+		const char *name,
+		unsigned int namelen,
+		const struct svc_fh *result,
+		__be32 status
+	),
+	TP_ARGS(rqstp, parent, name, namelen, result, status),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, parent)
+		__field(u32, result)
+		__field(unsigned long, status)
+		__dynamic_array(unsigned char, name, namelen + 1)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->parent = knfsd_fh_hash(&parent->fh_handle);
+		__entry->result = (status == nfs_ok) ?
+					knfsd_fh_hash(&result->fh_handle) : 0;
+		__entry->status = be32_to_cpu(status);
+		memcpy(__get_str(name), name, namelen);
+		__get_str(name)[namelen] = '\0';
+	),
+	TP_printk("xid=0x%08x parent fh_hash=0x%08x name=%s result fh_hash=0x%08x status=%s",
+		__entry->xid, __entry->parent, __get_str(name),
+		__entry->result, show_nfs_status(__entry->status)
+	)
+);
+
 TRACE_EVENT(nfsd_setattr_args,
 	TP_PROTO(
 		const struct svc_rqst *rqstp,
@@ -564,6 +596,31 @@ TRACE_EVENT(nfsd4_fh_current,
 	)
 );
 
+TRACE_EVENT(nfsd4_lookup,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const char *name,
+		unsigned int namelen,
+		__be32 status
+	),
+	TP_ARGS(rqstp, name, namelen, status),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(unsigned long, status)
+		__dynamic_array(unsigned char, name, namelen + 1)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->status = be32_to_cpu(status);
+		memcpy(__get_str(name), name, namelen);
+		__get_str(name)[namelen] = '\0';
+	),
+	TP_printk("xid=0x%08x name=%s status=%s",
+		__entry->xid, __get_str(name),
+		show_nfs4_status(__entry->status)
+	)
+);
+
 TRACE_EVENT(nfsd4_getattr,
 	TP_PROTO(
 		const struct svc_rqst *rqstp,
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 0d354531ed19..db61cfb521f9 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -179,8 +179,6 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
 	struct dentry		*dentry;
 	int			host_err;
 
-	dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name);
-
 	dparent = fhp->fh_dentry;
 	exp = exp_get(fhp->fh_export);
 
@@ -234,14 +232,23 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
 	return nfserrno(host_err);
 }
 
-/*
- * Look up one component of a pathname.
+/**
+ * nfsd_lookup - Look up one component of a pathname
+ * @rqstp: RPC Call being processed
+ * @fhp: file handle of parent directory
+ * @name: non-terminated C string of file name to look up
+ * @len: length of @name
+ * @resfh: on success, file handle of the looked-up object
+ *
  * N.B. After this call _both_ fhp and resfh need an fh_put
+ * When callers pass the same memory for @fhp and @resfh,
+ * fh_compose() fh_put's @fhp before overwritting it.
  *
  * If the lookup would cross a mountpoint, and the mounted filesystem
  * is exported to the client with NFSEXP_NOHIDE, then the lookup is
  * accepted as it stands and the mounted directory is
  * returned. Otherwise the covered directory is returned.
+ *
  * NOTE: this mountpoint crossing is not supported properly by all
  *   clients and is explicitly disallowed for NFSv3
  *      NeilBrown <neilb@cse.unsw.edu.au>



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

* [PATCH v2 23/27] NFSD: Add lock and locku tracepoints
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (21 preceding siblings ...)
  2020-09-21 18:12 ` [PATCH v2 22/27] NFSD: Add a lookup tracepoint Chuck Lever
@ 2020-09-21 18:12 ` Chuck Lever
  2020-09-21 18:12 ` [PATCH v2 24/27] NFSD: Add tracepoints to record the result of TEST_STATEID and FREE_STATEID Chuck Lever
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:12 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Record lock metadata.

nfsd-1035  [003]   842.934033: nfsd4_lock:           xid=0xf9651b20 type=WRITE start=2 length=1 (not new)
nfsd-1035  [003]   842.934055: nfsd4_seqid_prep:     seqid=0 client 5f68de0f:f04d8b18 stateid 00000014:00000001
nfsd-1035  [003]   842.934089: nfsd_file_put:        hash=0x6ca inode=0xffff88873c0953f0 ref=4 flags=HASHED|REFERENCED may=WRITE|READ file=0xffff888708173400
nfsd-1035  [003]   842.934095: nfsd4_compoundstatus: xid=0xf9651b20 op=3/3 OP_LOCK status=OK

nfsd-1035  [003]   842.937579: nfsd4_locku:          xid=0xff651b20 start=0 length=1
nfsd-1035  [003]   842.937580: nfsd4_seqid_prep:     seqid=0 client 5f68de0f:f04d8b18 stateid 00000014:00000002
nfsd-1035  [003]   842.937611: nfsd_file_put:        hash=0x6ca inode=0xffff88873c0953f0 ref=3 flags=HASHED|REFERENCED may=WRITE|READ file=0xffff888708173400
nfsd-1035  [003]   842.937616: nfsd4_compoundstatus: xid=0xff651b20 op=3/3 OP_LOCKU status=OK

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4state.c        |    8 ++-----
 fs/nfsd/trace.h            |   48 ++++++++++++++++++++++++++++++++++++++++++++
 include/trace/events/nfs.h |   14 +++++++++++++
 3 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 992ac867e52e..79fe2ab2e773 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -6702,9 +6702,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	struct net *net = SVC_NET(rqstp);
 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
-	dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
-		(long long) lock->lk_offset,
-		(long long) lock->lk_length);
+	trace_nfsd4_lock(rqstp, lock);
 
 	if (check_lock_length(lock->lk_offset, lock->lk_length))
 		 return nfserr_inval;
@@ -7002,9 +7000,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	int err;
 	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 
-	dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
-		(long long) locku->lu_offset,
-		(long long) locku->lu_length);
+	trace_nfsd4_locku(rqstp, locku);
 
 	if (check_lock_length(locku->lu_offset, locku->lu_length))
 		 return nfserr_inval;
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 5c37112106c6..e933464316d7 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -736,6 +736,54 @@ TRACE_EVENT(nfsd4_stateid_prep,
 	)
 );
 
+TRACE_EVENT(nfsd4_lock,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct nfsd4_lock *lock
+	),
+	TP_ARGS(rqstp, lock),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(unsigned long, type)
+		__field(bool, new)
+		__field(long long, start)
+		__field(long long, length)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->type = lock->lk_type;
+		__entry->new = lock->lk_is_new;
+		__entry->start = lock->lk_offset;
+		__entry->length = lock->lk_length;
+	),
+	TP_printk("xid=0x%08x type=%s start=%Ld length=%Ld (%s)",
+		__entry->xid, show_nfs4_lock_type(__entry->type),
+		__entry->start, __entry->length,
+		__entry->new ? "new" : "not new"
+	)
+);
+
+TRACE_EVENT(nfsd4_locku,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct nfsd4_locku *locku
+	),
+	TP_ARGS(rqstp, locku),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(long long, start)
+		__field(long long, length)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->start = locku->lu_offset;
+		__entry->length = locku->lu_length;
+	),
+	TP_printk("xid=0x%08x start=%Ld length=%Ld",
+		__entry->xid, __entry->start, __entry->length
+	)
+);
+
 TRACE_EVENT(nfsd4_delegreturn,
 	TP_PROTO(
 		const struct svc_rqst *rqstp,
diff --git a/include/trace/events/nfs.h b/include/trace/events/nfs.h
index e6da77eb95b5..235ec353d90a 100644
--- a/include/trace/events/nfs.h
+++ b/include/trace/events/nfs.h
@@ -495,3 +495,17 @@ TRACE_DEFINE_ENUM(NFS4_OPEN_CLAIM_DELEG_PREV_FH);
 		{ NFS4_SHARE_ACCESS_READ,		"READ" }, \
 		{ NFS4_SHARE_ACCESS_WRITE,		"WRITE" }, \
 		{ NFS4_SHARE_ACCESS_BOTH,		"BOTH" })
+
+TRACE_DEFINE_ENUM(NFS4_UNLOCK_LT);
+TRACE_DEFINE_ENUM(NFS4_READ_LT);
+TRACE_DEFINE_ENUM(NFS4_WRITE_LT);
+TRACE_DEFINE_ENUM(NFS4_READW_LT);
+TRACE_DEFINE_ENUM(NFS4_WRITEW_LT);
+
+#define show_nfs4_lock_type(x) \
+	__print_symbolic(x, \
+		{ NFS4_UNLOCK_LT,			"UNLOCK" }, \
+		{ NFS4_READ_LT,				"READ" }, \
+		{ NFS4_WRITE_LT,			"WRITE" }, \
+		{ NFS4_READW_LT,			"READW" }, \
+		{ NFS4_WRITEW_LT,			"WRITEW" })



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

* [PATCH v2 24/27] NFSD: Add tracepoints to record the result of TEST_STATEID and FREE_STATEID
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (22 preceding siblings ...)
  2020-09-21 18:12 ` [PATCH v2 23/27] NFSD: Add lock and locku tracepoints Chuck Lever
@ 2020-09-21 18:12 ` Chuck Lever
  2020-09-21 18:13 ` [PATCH v2 25/27] NFSD: Rename nfsd_ tracepoints to nfsd4_ Chuck Lever
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:12 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

These tracepoints record information about NFSv4 state recovery.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4state.c |    6 +++++
 fs/nfsd/trace.h     |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 79fe2ab2e773..eaad1763d33a 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -5945,9 +5945,11 @@ nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	struct nfsd4_test_stateid_id *stateid;
 	struct nfs4_client *cl = cstate->session->se_client;
 
-	list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list)
+	list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list) {
 		stateid->ts_id_status =
 			nfsd4_validate_stateid(cl, &stateid->ts_id_stateid);
+		trace_nfsd4_test_stateid(rqstp, stateid);
+	}
 
 	return nfs_ok;
 }
@@ -5992,6 +5994,8 @@ nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	struct nfs4_client *cl = cstate->session->se_client;
 	__be32 ret = nfserr_bad_stateid;
 
+	trace_nfsd4_free_stateid(rqstp, stateid);
+
 	spin_lock(&cl->cl_lock);
 	s = find_stateid_locked(cl, stateid);
 	if (!s)
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index e933464316d7..10927da9d016 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -784,6 +784,62 @@ TRACE_EVENT(nfsd4_locku,
 	)
 );
 
+TRACE_EVENT(nfsd4_test_stateid,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct nfsd4_test_stateid_id *stateid
+	),
+	TP_ARGS(rqstp, stateid),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, cl_boot)
+		__field(u32, cl_id)
+		__field(u32, si_id)
+		__field(u32, si_generation)
+		__field(int, status)
+	),
+	TP_fast_assign(
+		const stateid_t *stp = &stateid->ts_id_stateid;
+
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->cl_boot = stp->si_opaque.so_clid.cl_boot;
+		__entry->cl_id = stp->si_opaque.so_clid.cl_id;
+		__entry->si_id = stp->si_opaque.so_id;
+		__entry->si_generation = stp->si_generation;
+		__entry->status = be32_to_cpu(stateid->ts_id_status);
+	),
+	TP_printk("xid=0x%08x client=%08x:%08x stateid=%08x:%08x status=%d",
+		__entry->xid, __entry->cl_boot, __entry->cl_id,
+		__entry->si_id, __entry->si_generation, __entry->status
+	)
+);
+
+TRACE_EVENT(nfsd4_free_stateid,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const stateid_t *stp
+	),
+	TP_ARGS(rqstp, stp),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, cl_boot)
+		__field(u32, cl_id)
+		__field(u32, si_id)
+		__field(u32, si_generation)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->cl_boot = stp->si_opaque.so_clid.cl_boot;
+		__entry->cl_id = stp->si_opaque.so_clid.cl_id;
+		__entry->si_id = stp->si_opaque.so_id;
+		__entry->si_generation = stp->si_generation;
+	),
+	TP_printk("xid=0x%08x client=%08x:%08x stateid=%08x:%08x",
+		__entry->xid, __entry->cl_boot, __entry->cl_id,
+		__entry->si_id, __entry->si_generation
+	)
+);
+
 TRACE_EVENT(nfsd4_delegreturn,
 	TP_PROTO(
 		const struct svc_rqst *rqstp,



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

* [PATCH v2 25/27] NFSD: Rename nfsd_ tracepoints to nfsd4_
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (23 preceding siblings ...)
  2020-09-21 18:12 ` [PATCH v2 24/27] NFSD: Add tracepoints to record the result of TEST_STATEID and FREE_STATEID Chuck Lever
@ 2020-09-21 18:13 ` Chuck Lever
  2020-09-21 18:13 ` [PATCH v2 26/27] NFSD: Add tracepoints in the NFS dispatcher Chuck Lever
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:13 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Allow administrators to enable just NFS4-related or non-NFSv4-related
server tracepoints by changing the prefix of NFSv4-related
tracepoints.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4callback.c |   28 ++++++++++++++--------------
 fs/nfsd/nfs4layouts.c  |   16 ++++++++--------
 fs/nfsd/nfs4proc.c     |    4 ++--
 fs/nfsd/nfs4state.c    |   14 +++++++-------
 fs/nfsd/trace.h        |   16 ++++++++--------
 5 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 052be5bf9ef5..65675c0158ed 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -906,7 +906,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
 	if (clp->cl_minorversion == 0) {
 		if (!clp->cl_cred.cr_principal &&
 		    (clp->cl_cred.cr_flavor >= RPC_AUTH_GSS_KRB5)) {
-			trace_nfsd_cb_setup_err(clp, -EINVAL);
+			trace_nfsd4_cb_setup_err(clp, -EINVAL);
 			return -EINVAL;
 		}
 		args.client_name = clp->cl_cred.cr_principal;
@@ -916,7 +916,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
 		clp->cl_cb_ident = conn->cb_ident;
 	} else {
 		if (!conn->cb_xprt) {
-			trace_nfsd_cb_setup_err(clp, -EINVAL);
+			trace_nfsd4_cb_setup_err(clp, -EINVAL);
 			return -EINVAL;
 		}
 		clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
@@ -930,18 +930,18 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
 	/* Create RPC client */
 	client = rpc_create(&args);
 	if (IS_ERR(client)) {
-		trace_nfsd_cb_setup_err(clp, PTR_ERR(client));
+		trace_nfsd4_cb_setup_err(clp, PTR_ERR(client));
 		return PTR_ERR(client);
 	}
 	cred = get_backchannel_cred(clp, client, ses);
 	if (!cred) {
-		trace_nfsd_cb_setup_err(clp, -ENOMEM);
+		trace_nfsd4_cb_setup_err(clp, -ENOMEM);
 		rpc_shutdown_client(client);
 		return -ENOMEM;
 	}
 	clp->cl_cb_client = client;
 	clp->cl_cb_cred = cred;
-	trace_nfsd_cb_setup(clp);
+	trace_nfsd4_cb_setup(clp);
 	return 0;
 }
 
@@ -950,7 +950,7 @@ static void nfsd4_mark_cb_down(struct nfs4_client *clp, int reason)
 	if (test_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags))
 		return;
 	clp->cl_cb_state = NFSD4_CB_DOWN;
-	trace_nfsd_cb_state(clp);
+	trace_nfsd4_cb_state(clp);
 }
 
 static void nfsd4_mark_cb_fault(struct nfs4_client *clp, int reason)
@@ -958,19 +958,19 @@ static void nfsd4_mark_cb_fault(struct nfs4_client *clp, int reason)
 	if (test_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags))
 		return;
 	clp->cl_cb_state = NFSD4_CB_FAULT;
-	trace_nfsd_cb_state(clp);
+	trace_nfsd4_cb_state(clp);
 }
 
 static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
 {
 	struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null);
 
-	trace_nfsd_cb_done(clp, task->tk_status);
+	trace_nfsd4_cb_done(clp, task->tk_status);
 	if (task->tk_status)
 		nfsd4_mark_cb_down(clp, task->tk_status);
 	else {
 		clp->cl_cb_state = NFSD4_CB_UP;
-		trace_nfsd_cb_state(clp);
+		trace_nfsd4_cb_state(clp);
 	}
 }
 
@@ -996,7 +996,7 @@ static const struct rpc_call_ops nfsd4_cb_probe_ops = {
 void nfsd4_probe_callback(struct nfs4_client *clp)
 {
 	clp->cl_cb_state = NFSD4_CB_UNKNOWN;
-	trace_nfsd_cb_state(clp);
+	trace_nfsd4_cb_state(clp);
 	set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags);
 	nfsd4_run_cb(&clp->cl_cb_null);
 }
@@ -1013,7 +1013,7 @@ void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
 	spin_lock(&clp->cl_lock);
 	memcpy(&clp->cl_cb_conn, conn, sizeof(struct nfs4_cb_conn));
 	spin_unlock(&clp->cl_lock);
-	trace_nfsd_cb_state(clp);
+	trace_nfsd4_cb_state(clp);
 }
 
 /*
@@ -1170,7 +1170,7 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
 	struct nfsd4_callback *cb = calldata;
 	struct nfs4_client *clp = cb->cb_clp;
 
-	trace_nfsd_cb_done(clp, task->tk_status);
+	trace_nfsd4_cb_done(clp, task->tk_status);
 
 	if (!nfsd4_cb_sequence_done(task, cb))
 		return;
@@ -1275,7 +1275,7 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
 	 * kill the old client:
 	 */
 	if (clp->cl_cb_client) {
-		trace_nfsd_cb_shutdown(clp);
+		trace_nfsd4_cb_shutdown(clp);
 		rpc_shutdown_client(clp->cl_cb_client);
 		clp->cl_cb_client = NULL;
 		put_cred(clp->cl_cb_cred);
@@ -1321,7 +1321,7 @@ nfsd4_run_cb_work(struct work_struct *work)
 	struct rpc_clnt *clnt;
 	int flags;
 
-	trace_nfsd_cb_work(clp, cb->cb_msg.rpc_proc->p_name);
+	trace_nfsd4_cb_work(clp, cb->cb_msg.rpc_proc->p_name);
 
 	if (cb->cb_need_restart) {
 		cb->cb_need_restart = false;
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index a97873f2d22b..7daa553abba4 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -158,7 +158,7 @@ nfsd4_free_layout_stateid(struct nfs4_stid *stid)
 	struct nfs4_client *clp = ls->ls_stid.sc_client;
 	struct nfs4_file *fp = ls->ls_stid.sc_file;
 
-	trace_nfsd_layoutstate_free(&ls->ls_stid.sc_stateid);
+	trace_nfsd4_layoutstate_free(&ls->ls_stid.sc_stateid);
 
 	spin_lock(&clp->cl_lock);
 	list_del_init(&ls->ls_perclnt);
@@ -257,7 +257,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
 	list_add(&ls->ls_perfile, &fp->fi_lo_states);
 	spin_unlock(&fp->fi_lock);
 
-	trace_nfsd_layoutstate_alloc(&ls->ls_stid.sc_stateid);
+	trace_nfsd4_layoutstate_alloc(&ls->ls_stid.sc_stateid);
 	return ls;
 }
 
@@ -327,7 +327,7 @@ nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls)
 	if (list_empty(&ls->ls_layouts))
 		goto out_unlock;
 
-	trace_nfsd_layout_recall(&ls->ls_stid.sc_stateid);
+	trace_nfsd4_layout_recall(&ls->ls_stid.sc_stateid);
 
 	refcount_inc(&ls->ls_stid.sc_count);
 	nfsd4_run_cb(&ls->ls_recall);
@@ -500,7 +500,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
 						false, lrp->lr_layout_type,
 						&ls);
 	if (nfserr) {
-		trace_nfsd_layout_return_lookup_fail(&lrp->lr_sid);
+		trace_nfsd4_layout_return_lookup_fail(&lrp->lr_sid);
 		return nfserr;
 	}
 
@@ -516,7 +516,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
 			nfs4_inc_and_copy_stateid(&lrp->lr_sid, &ls->ls_stid);
 		lrp->lrs_present = 1;
 	} else {
-		trace_nfsd_layoutstate_unhash(&ls->ls_stid.sc_stateid);
+		trace_nfsd4_layoutstate_unhash(&ls->ls_stid.sc_stateid);
 		nfs4_unhash_stid(&ls->ls_stid);
 		lrp->lrs_present = 0;
 	}
@@ -686,7 +686,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
 		/*
 		 * Unknown error or non-responding client, we'll need to fence.
 		 */
-		trace_nfsd_layout_recall_fail(&ls->ls_stid.sc_stateid);
+		trace_nfsd4_layout_recall_fail(&ls->ls_stid.sc_stateid);
 
 		ops = nfsd4_layout_ops[ls->ls_layout_type];
 		if (ops->fence_client)
@@ -695,7 +695,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
 			nfsd4_cb_layout_fail(ls);
 		return 1;
 	case -NFS4ERR_NOMATCHING_LAYOUT:
-		trace_nfsd_layout_recall_done(&ls->ls_stid.sc_stateid);
+		trace_nfsd4_layout_recall_done(&ls->ls_stid.sc_stateid);
 		task->tk_status = 0;
 		return 1;
 	}
@@ -708,7 +708,7 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb)
 		container_of(cb, struct nfs4_layout_stateid, ls_recall);
 	LIST_HEAD(reaplist);
 
-	trace_nfsd_layout_recall_release(&ls->ls_stid.sc_stateid);
+	trace_nfsd4_layout_recall_release(&ls->ls_stid.sc_stateid);
 
 	nfsd4_return_all_layouts(ls, &reaplist);
 	nfsd4_free_layouts(&reaplist);
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index c4fa121560ae..49109645af24 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1973,7 +1973,7 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
 	nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lgp->lg_sid,
 						true, lgp->lg_layout_type, &ls);
 	if (nfserr) {
-		trace_nfsd_layout_get_lookup_fail(&lgp->lg_sid);
+		trace_nfsd4_layout_get_lookup_fail(&lgp->lg_sid);
 		goto out;
 	}
 
@@ -2042,7 +2042,7 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
 						false, lcp->lc_layout_type,
 						&ls);
 	if (nfserr) {
-		trace_nfsd_layout_commit_lookup_fail(&lcp->lc_sid);
+		trace_nfsd4_layout_commit_lookup_fail(&lcp->lc_sid);
 		/* fixup error code as per RFC5661 */
 		if (nfserr == nfserr_bad_stateid)
 			nfserr = nfserr_badlayout;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index eaad1763d33a..690483e0b933 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2893,12 +2893,12 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_r
 	conn->cb_prog = se->se_callback_prog;
 	conn->cb_ident = se->se_callback_ident;
 	memcpy(&conn->cb_saddr, &rqstp->rq_daddr, rqstp->rq_daddrlen);
-	trace_nfsd_cb_args(clp, conn);
+	trace_nfsd4_cb_args(clp, conn);
 	return;
 out_err:
 	conn->cb_addr.ss_family = AF_UNSPEC;
 	conn->cb_addrlen = 0;
-	trace_nfsd_cb_nodelegs(clp);
+	trace_nfsd4_cb_nodelegs(clp);
 	return;
 }
 
@@ -3954,7 +3954,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		if (clp_used_exchangeid(conf))
 			goto out;
 		if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
-			trace_nfsd_clid_inuse_err(conf);
+			trace_nfsd4_clid_inuse_err(conf);
 			goto out;
 		}
 	}
@@ -4578,7 +4578,7 @@ nfsd_break_deleg_cb(struct file_lock *fl)
 	struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
 	struct nfs4_file *fp = dp->dl_stid.sc_file;
 
-	trace_nfsd_deleg_break(&dp->dl_stid.sc_stateid);
+	trace_nfsd4_deleg_break(&dp->dl_stid.sc_stateid);
 
 	/*
 	 * We don't want the locks code to timeout the lease for us;
@@ -5145,7 +5145,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open,
 
 	memcpy(&open->op_delegate_stateid, &dp->dl_stid.sc_stateid, sizeof(dp->dl_stid.sc_stateid));
 
-	trace_nfsd_deleg_open(&dp->dl_stid.sc_stateid);
+	trace_nfsd4_deleg_open(&dp->dl_stid.sc_stateid);
 	open->op_delegate_type = NFS4_OPEN_DELEGATE_READ;
 	nfs4_put_stid(&dp->dl_stid);
 	return;
@@ -5262,7 +5262,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
 	nfs4_open_delegation(current_fh, open, stp);
 nodeleg:
 	status = nfs_ok;
-	trace_nfsd_deleg_none(&stp->st_stid.sc_stateid);
+	trace_nfsd4_deleg_none(&stp->st_stid.sc_stateid);
 out:
 	/* 4.1 client trying to upgrade/downgrade delegation? */
 	if (open->op_delegate_type == NFS4_OPEN_DELEGATE_NONE && dp &&
@@ -7804,7 +7804,7 @@ nfsd_recall_delegations(struct list_head *reaplist)
 		list_del_init(&dp->dl_recall_lru);
 		clp = dp->dl_stid.sc_client;
 
-		trace_nfsd_deleg_recall(&dp->dl_stid.sc_stateid);
+		trace_nfsd4_deleg_recall(&dp->dl_stid.sc_stateid);
 
 		/*
 		 * We skipped all entries that had a zero dl_time before,
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 10927da9d016..53115fbc00b2 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -889,7 +889,7 @@ DECLARE_EVENT_CLASS(nfsd_stateid_class,
 )
 
 #define DEFINE_STATEID_EVENT(name) \
-DEFINE_EVENT(nfsd_stateid_class, nfsd_##name, \
+DEFINE_EVENT(nfsd_stateid_class, nfsd4_##name, \
 	TP_PROTO(stateid_t *stp), \
 	TP_ARGS(stp))
 
@@ -985,7 +985,7 @@ DEFINE_EVENT(nfsd_net_class, nfsd_##name, \
 DEFINE_NET_EVENT(grace_start);
 DEFINE_NET_EVENT(grace_complete);
 
-TRACE_EVENT(nfsd_clid_inuse_err,
+TRACE_EVENT(nfsd4_clid_inuse_err,
 	TP_PROTO(const struct nfs4_client *clp),
 	TP_ARGS(clp),
 	TP_STRUCT__entry(
@@ -1208,7 +1208,7 @@ TRACE_EVENT(nfsd_drc_mismatch,
 		__entry->ingress)
 );
 
-TRACE_EVENT(nfsd_cb_args,
+TRACE_EVENT(nfsd4_cb_args,
 	TP_PROTO(
 		const struct nfs4_client *clp,
 		const struct nfs4_cb_conn *conn
@@ -1234,7 +1234,7 @@ TRACE_EVENT(nfsd_cb_args,
 		__entry->addr, __entry->prog, __entry->ident)
 );
 
-TRACE_EVENT(nfsd_cb_nodelegs,
+TRACE_EVENT(nfsd4_cb_nodelegs,
 	TP_PROTO(const struct nfs4_client *clp),
 	TP_ARGS(clp),
 	TP_STRUCT__entry(
@@ -1282,7 +1282,7 @@ DECLARE_EVENT_CLASS(nfsd_cb_class,
 );
 
 #define DEFINE_NFSD_CB_EVENT(name)			\
-DEFINE_EVENT(nfsd_cb_class, nfsd_cb_##name,		\
+DEFINE_EVENT(nfsd_cb_class, nfsd4_cb_##name,		\
 	TP_PROTO(const struct nfs4_client *clp),	\
 	TP_ARGS(clp))
 
@@ -1290,7 +1290,7 @@ DEFINE_NFSD_CB_EVENT(setup);
 DEFINE_NFSD_CB_EVENT(state);
 DEFINE_NFSD_CB_EVENT(shutdown);
 
-TRACE_EVENT(nfsd_cb_setup_err,
+TRACE_EVENT(nfsd4_cb_setup_err,
 	TP_PROTO(
 		const struct nfs4_client *clp,
 		long error
@@ -1313,7 +1313,7 @@ TRACE_EVENT(nfsd_cb_setup_err,
 		__entry->addr, __entry->cl_boot, __entry->cl_id, __entry->error)
 );
 
-TRACE_EVENT(nfsd_cb_work,
+TRACE_EVENT(nfsd4_cb_work,
 	TP_PROTO(
 		const struct nfs4_client *clp,
 		const char *procedure
@@ -1337,7 +1337,7 @@ TRACE_EVENT(nfsd_cb_work,
 		__get_str(procedure))
 );
 
-TRACE_EVENT(nfsd_cb_done,
+TRACE_EVENT(nfsd4_cb_done,
 	TP_PROTO(
 		const struct nfs4_client *clp,
 		int status



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

* [PATCH v2 26/27] NFSD: Add tracepoints in the NFS dispatcher
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (24 preceding siblings ...)
  2020-09-21 18:13 ` [PATCH v2 25/27] NFSD: Rename nfsd_ tracepoints to nfsd4_ Chuck Lever
@ 2020-09-21 18:13 ` Chuck Lever
  2020-09-24 23:45   ` J. Bruce Fields
  2020-09-21 18:13 ` [PATCH v2 27/27] NFSD: Replace dprintk callsites in fs/nfsd/nfsfh.c Chuck Lever
  2020-09-24 21:36 ` [PATCH v2 00/27] NFSD operation monitoring tracepoints J. Bruce Fields
  27 siblings, 1 reply; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:13 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

This is follow-on work to the tracepoints added in the NFS server's
duplicate reply cache. Here, tracepoints are introduced that report
replies from cache as well as encoding and decoding errors.

The NFSv2, v3, and v4 dispatcher requirements have diverged over
time, leaving us with a little bit of technical debt. In addition,
I wanted to add a tracepoint for NFSv2 and NFSv3 similar to the
nfsd4_compound/compoundstatus tracepoints. Lastly, removing some
conditional branches from this hot path helps optimize CPU
utilization. So, I've duplicated the nfsd_dispatcher function.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs2acl.c  |    2 -
 fs/nfsd/nfs3acl.c  |    2 -
 fs/nfsd/nfs4proc.c |    2 -
 fs/nfsd/nfsd.h     |    1 
 fs/nfsd/nfssvc.c   |  198 ++++++++++++++++++++++++++++++++++------------------
 fs/nfsd/trace.h    |   50 +++++++++++++
 6 files changed, 183 insertions(+), 72 deletions(-)

diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 54e597918822..894b8f0594e2 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -416,6 +416,6 @@ const struct svc_version nfsd_acl_version2 = {
 	.vs_nproc	= 5,
 	.vs_proc	= nfsd_acl_procedures2,
 	.vs_count	= nfsd_acl_count2,
-	.vs_dispatch	= nfsd_dispatch,
+	.vs_dispatch	= nfsd4_dispatch,
 	.vs_xdrsize	= NFS3_SVC_XDRSIZE,
 };
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index 7f512dec7460..924ebb19c59c 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -282,7 +282,7 @@ const struct svc_version nfsd_acl_version3 = {
 	.vs_nproc	= 3,
 	.vs_proc	= nfsd_acl_procedures3,
 	.vs_count	= nfsd_acl_count3,
-	.vs_dispatch	= nfsd_dispatch,
+	.vs_dispatch	= nfsd4_dispatch,
 	.vs_xdrsize	= NFS3_SVC_XDRSIZE,
 };
 
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 49109645af24..61302641f651 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -3320,7 +3320,7 @@ const struct svc_version nfsd_version4 = {
 	.vs_nproc		= 2,
 	.vs_proc		= nfsd_procedures4,
 	.vs_count		= nfsd_count3,
-	.vs_dispatch		= nfsd_dispatch,
+	.vs_dispatch		= nfsd4_dispatch,
 	.vs_xdrsize		= NFS4_SVC_XDRSIZE,
 	.vs_rpcb_optnl		= true,
 	.vs_need_cong_ctrl	= true,
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index cb742e17e04a..7fa4b19dd2f7 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -78,6 +78,7 @@ extern const struct seq_operations nfs_exports_op;
  */
 int		nfsd_svc(int nrservs, struct net *net, const struct cred *cred);
 int		nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
+int		nfsd4_dispatch(struct svc_rqst *rqstp, __be32 *statp);
 
 int		nfsd_nrthreads(struct net *);
 int		nfsd_nrpools(struct net *);
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index f7f6473578af..d626eea1c78a 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -28,6 +28,7 @@
 #include "vfs.h"
 #include "netns.h"
 #include "filecache.h"
+#include "trace.h"
 
 #define NFSDDBG_FACILITY	NFSDDBG_SVC
 
@@ -964,7 +965,7 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
 {
 	if (nfserr == nfserr_jukebox && vers == 2)
 		return nfserr_dropit;
-	if (nfserr == nfserr_wrongsec && vers < 4)
+	if (nfserr == nfserr_wrongsec)
 		return nfserr_acces;
 	return nfserr;
 }
@@ -980,18 +981,6 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
 static bool nfs_request_too_big(struct svc_rqst *rqstp,
 				const struct svc_procedure *proc)
 {
-	/*
-	 * The ACL code has more careful bounds-checking and is not
-	 * susceptible to this problem:
-	 */
-	if (rqstp->rq_prog != NFS_PROGRAM)
-		return false;
-	/*
-	 * Ditto NFSv4 (which can in theory have argument and reply both
-	 * more than a page):
-	 */
-	if (rqstp->rq_vers >= 4)
-		return false;
 	/* The reply will be small, we're OK: */
 	if (proc->pc_xdrressize > 0 &&
 	    proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
@@ -1000,81 +989,152 @@ static bool nfs_request_too_big(struct svc_rqst *rqstp,
 	return rqstp->rq_arg.len > PAGE_SIZE;
 }
 
-int
-nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
+/**
+ * nfsd_dispatch - Process an NFSv2 or NFSv3 request
+ * @rqstp: incoming NFS request
+ * @statp: OUT: RPC accept_stat value
+ *
+ * Return values:
+ *  %0: Processing complete; do not send a Reply
+ *  %1: Processing complete; send a Reply
+ */
+int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 {
-	const struct svc_procedure *proc;
-	__be32			nfserr;
-	__be32			*nfserrp;
-
-	dprintk("nfsd_dispatch: vers %d proc %d\n",
-				rqstp->rq_vers, rqstp->rq_proc);
-	proc = rqstp->rq_procinfo;
-
-	if (nfs_request_too_big(rqstp, proc)) {
-		dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
-		*statp = rpc_garbage_args;
-		return 1;
+	const struct svc_procedure *proc = rqstp->rq_procinfo;
+	struct kvec *argv = &rqstp->rq_arg.head[0];
+	struct kvec *resv = &rqstp->rq_res.head[0];
+	__be32 nfserr, *nfserrp;
+
+	if (nfs_request_too_big(rqstp, proc))
+		goto out_too_large;
+
+	if (proc->pc_decode && !procp->pc_decode(rqstp, argv->iov_base))
+		goto out_decode_err;
+
+	rqstp->rq_cachetype = proc->pc_cachetype;
+	switch (nfsd_cache_lookup(rqstp)) {
+	case RC_DROPIT:
+		goto out_dropit;
+	case RC_REPLY:
+		goto out_cached_reply;
+	case RC_DOIT:
+		break;
 	}
-	rqstp->rq_lease_breaker = NULL;
+
+	nfserrp = resv->iov_base + resv->iov_len;
+	resv->iov_len += sizeof(__be32);
+	nfserr = proc->pc_func(rqstp);
+	nfserr = map_new_errors(rqstp->rq_vers, nfserr);
+	if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags))
+		goto out_update_drop;
+	if (rqstp->rq_proc)
+		*nfserrp++ = nfserr;
+
+	/* For NFSv2, additional info is never returned in case of an error. */
+	if (!(nfserr && rqstp->rq_vers == 2))
+		if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp))
+			goto out_encode_err;
+
+	nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1);
+	trace_nfsd_svc_status(rqstp, proc, nfserr);
+	return 1;
+
+out_too_large:
+	trace_nfsd_svc_too_large_err(rqstp);
+	*statp = rpc_garbage_args;
+	return 1;
+
+out_decode_err:
+	trace_nfsd_svc_decode_err(rqstp);
+	*statp = rpc_garbage_args;
+	return 1;
+
+out_update_drop:
+	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
+out_dropit:
+	trace_nfsd_svc_dropit(rqstp);
+	return 0;
+
+out_cached_reply:
+	trace_nfsd_svc_cached_reply(rqstp);
+	return 1;
+
+out_encode_err:
+	trace_nfsd_svc_encode_err(rqstp);
+	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
+	*statp = rpc_system_err;
+	return 1;
+}
+
+/**
+ * nfsd4_dispatch - Process an NFSv4 or NFSACL request
+ * @rqstp: incoming NFS request
+ * @statp: OUT: RPC accept_stat value
+ *
+ * Return values:
+ *  %0: Processing complete; do not send a Reply
+ *  %1: Processing complete; send a Reply
+ */
+int nfsd4_dispatch(struct svc_rqst *rqstp, __be32 *statp)
+{
+	const struct svc_procedure *proc = rqstp->rq_procinfo;
+	struct kvec *argv = &rqstp->rq_arg.head[0];
+	struct kvec *resv = &rqstp->rq_res.head[0];
+	__be32 nfserr, *nfserrp;
+
 	/*
 	 * Give the xdr decoder a chance to change this if it wants
 	 * (necessary in the NFSv4.0 compound case)
 	 */
 	rqstp->rq_cachetype = proc->pc_cachetype;
-	/* Decode arguments */
-	if (proc->pc_decode &&
-	    !proc->pc_decode(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base)) {
-		dprintk("nfsd: failed to decode arguments!\n");
-		*statp = rpc_garbage_args;
-		return 1;
-	}
+	rqstp->rq_lease_breaker = NULL;
+
+	if (proc->pc_decode && !procp->pc_decode(rqstp, argv->iov_base))
+		goto out_decode_err;
 
-	/* Check whether we have this call in the cache. */
 	switch (nfsd_cache_lookup(rqstp)) {
 	case RC_DROPIT:
-		return 0;
+		goto out_dropit;
 	case RC_REPLY:
-		return 1;
-	case RC_DOIT:;
-		/* do it */
+		goto out_cached_reply;
+	case RC_DOIT:
+		break;
 	}
 
-	/* need to grab the location to store the status, as
-	 * nfsv4 does some encoding while processing 
-	 */
-	nfserrp = rqstp->rq_res.head[0].iov_base
-		+ rqstp->rq_res.head[0].iov_len;
-	rqstp->rq_res.head[0].iov_len += sizeof(__be32);
-
-	/* Now call the procedure handler, and encode NFS status. */
+	nfserrp = resv->iov_base + resv->iov_len;
+	resv->iov_len += sizeof(__be32);
 	nfserr = proc->pc_func(rqstp);
-	nfserr = map_new_errors(rqstp->rq_vers, nfserr);
-	if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags)) {
-		dprintk("nfsd: Dropping request; may be revisited later\n");
-		nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
-		return 0;
-	}
-
-	if (rqstp->rq_proc != 0)
+	if (test_bit(RQ_DROPME, &rqstp->rq_flags))
+		goto out_update_drop;
+	if (rqstp->rq_proc)
 		*nfserrp++ = nfserr;
 
-	/* Encode result.
-	 * For NFSv2, additional info is never returned in case of an error.
-	 */
-	if (!(nfserr && rqstp->rq_vers == 2)) {
-		if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp)) {
-			/* Failed to encode result. Release cache entry */
-			dprintk("nfsd: failed to encode result!\n");
-			nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
-			*statp = rpc_system_err;
-			return 1;
-		}
-	}
+	if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp))
+		goto out_encode_err;
 
-	/* Store reply in cache. */
 	nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1);
 	return 1;
+
+out_decode_err:
+	trace_nfsd_svc_decode_err(rqstp);
+	*statp = rpc_garbage_args;
+	return 1;
+
+out_update_drop:
+	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
+out_dropit:
+	trace_nfsd_svc_dropit(rqstp);
+	return 0;
+
+out_cached_reply:
+	trace_nfsd_svc_cached_reply(rqstp);
+	return 1;
+
+out_encode_err:
+	trace_nfsd_svc_encode_err(rqstp);
+	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
+	*statp = rpc_system_err;
+	return 1;
 }
 
 int nfsd_pool_stats_open(struct inode *inode, struct file *file)
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 53115fbc00b2..50ab4a84c25f 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -32,6 +32,56 @@
 		{ NFSD_MAY_READ_IF_EXEC,	"READ_IF_EXEC" },	\
 		{ NFSD_MAY_64BIT_COOKIE,	"64BIT_COOKIE" })
 
+DECLARE_EVENT_CLASS(nfsd_simple_class,
+	TP_PROTO(
+		const struct svc_rqst *rqstp
+	),
+	TP_ARGS(rqstp),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+	),
+	TP_printk("xid=0x%08x", __entry->xid)
+);
+
+#define DEFINE_NFSD_SIMPLE_EVENT(name)			\
+DEFINE_EVENT(nfsd_simple_class, nfsd_##name,		\
+	TP_PROTO(const struct svc_rqst *rqstp),		\
+	TP_ARGS(rqstp))
+
+DEFINE_NFSD_SIMPLE_EVENT(svc_too_large_err);
+DEFINE_NFSD_SIMPLE_EVENT(svc_decode_err);
+DEFINE_NFSD_SIMPLE_EVENT(svc_dropit);
+DEFINE_NFSD_SIMPLE_EVENT(svc_cached_reply);
+DEFINE_NFSD_SIMPLE_EVENT(svc_encode_err);
+
+TRACE_EVENT(nfsd_svc_status,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct svc_procedure *proc,
+		__be32 status
+	),
+	TP_ARGS(rqstp, proc, status),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, version)
+		__field(unsigned long, status)
+		__string(procedure, rqstp->rq_procinfo->pc_name)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->version = rqstp->rq_vers;
+		__entry->status = be32_to_cpu(status);
+		__assign_str(procedure, rqstp->rq_procinfo->pc_name);
+	),
+	TP_printk("xid=0x%08x version=%u procedure=%s status=%s",
+		__entry->xid, __entry->version, __get_str(procedure),
+		show_nfs_status(__entry->status)
+	)
+);
+
 TRACE_EVENT(nfsd_access,
 	TP_PROTO(
 		const struct svc_rqst *rqstp,



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

* [PATCH v2 27/27] NFSD: Replace dprintk callsites in fs/nfsd/nfsfh.c
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (25 preceding siblings ...)
  2020-09-21 18:13 ` [PATCH v2 26/27] NFSD: Add tracepoints in the NFS dispatcher Chuck Lever
@ 2020-09-21 18:13 ` Chuck Lever
  2020-09-24 21:36 ` [PATCH v2 00/27] NFSD operation monitoring tracepoints J. Bruce Fields
  27 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-21 18:13 UTC (permalink / raw)
  To: bfields, Bill.Baker; +Cc: linux-nfs

Report the input and result of fh_verify. The other dprintk
callsites are rather stale and so are removed.

nfsd-1025  [002]   256.807404: nfsd_fh_verify:       xid=0x12147d7a fh_hash=0x6085d6fb type=NONE access=WRITE|SATTR|OWNER_OVERRIDE status=0

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsfh.c |   36 ++----------------------------------
 fs/nfsd/trace.h |   42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index c81dbbad8792..dd2d26ddf3f4 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -16,9 +16,6 @@
 #include "auth.h"
 #include "trace.h"
 
-#define NFSDDBG_FACILITY		NFSDDBG_FH
-
-
 /*
  * our acceptability function.
  * if NOSUBTREECHECK, accept anything
@@ -48,8 +45,6 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry)
 		dput(tdentry);
 		tdentry = parent;
 	}
-	if (tdentry != exp->ex_path.dentry)
-		dprintk("nfsd_acceptable failed at %p %pd\n", tdentry, tdentry);
 	rv = (tdentry == exp->ex_path.dentry);
 	dput(tdentry);
 	return rv;
@@ -104,12 +99,8 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
 	int flags = nfsexp_flags(rqstp, exp);
 
 	/* Check if the request originated from a secure port. */
-	if (!nfsd_originating_port_ok(rqstp, flags)) {
-		RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
-		dprintk("nfsd: request from insecure port %s!\n",
-		        svc_print_addr(rqstp, buf, sizeof(buf)));
+	if (!nfsd_originating_port_ok(rqstp, flags))
 		return nfserr_perm;
-	}
 
 	/* Set user creds for this exportpoint */
 	return nfserrno(nfsd_setuser(rqstp, exp));
@@ -331,8 +322,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access)
 	struct dentry	*dentry;
 	__be32		error;
 
-	dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
-
 	if (!fhp->fh_dentry) {
 		error = nfsd_set_fh_dentry(rqstp, fhp);
 		if (error)
@@ -391,16 +380,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access)
 skip_pseudoflavor_check:
 	/* Finally, check access permissions. */
 	error = nfsd_permission(rqstp, exp, dentry, access);
-
-	if (error) {
-		dprintk("fh_verify: %pd2 permission failure, "
-			"acc=%x, error=%d\n",
-			dentry,
-			access, ntohl(error));
-	}
 out:
 	if (error == nfserr_stale)
 		nfsdstats.fh_stale++;
+	trace_nfsd_fh_verify(rqstp, fhp, type, access, error);
 	return error;
 }
 
@@ -547,12 +530,6 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
 	struct inode * inode = d_inode(dentry);
 	dev_t ex_dev = exp_sb(exp)->s_dev;
 
-	dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %pd2, ino=%ld)\n",
-		MAJOR(ex_dev), MINOR(ex_dev),
-		(long) d_inode(exp->ex_path.dentry)->i_ino,
-		dentry,
-		(inode ? inode->i_ino : 0));
-
 	/* Choose filehandle version and fsid type based on
 	 * the reference filehandle (if it is in the same export)
 	 * or the export options.
@@ -562,15 +539,6 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
 	if (ref_fh == fhp)
 		fh_put(ref_fh);
 
-	if (fhp->fh_locked || fhp->fh_dentry) {
-		printk(KERN_ERR "fh_compose: fh %pd2 not initialized!\n",
-		       dentry);
-	}
-	if (fhp->fh_maxsize < NFS_FHSIZE)
-		printk(KERN_ERR "fh_compose: called with maxsize %d! %pd2\n",
-		       fhp->fh_maxsize,
-		       dentry);
-
 	fhp->fh_dentry = dget(dentry); /* our internal copy */
 	fhp->fh_export = exp_get(exp);
 
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 50ab4a84c25f..47d0fea70f34 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -181,6 +181,48 @@ TRACE_EVENT(nfsd_setattr_args,
 	)
 );
 
+TRACE_EVENT(nfsd_fh_verify,
+	TP_PROTO(
+		const struct svc_rqst *rqstp,
+		const struct svc_fh *fhp,
+		umode_t type,
+		int access,
+		__be32 status
+	),
+	TP_ARGS(rqstp, fhp, type, access, status),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, fh_hash)
+		__field(unsigned long, type)
+		__field(unsigned long, access)
+		__field(unsigned long, status)
+		__dynamic_array(unsigned char, name,
+				fhp->fh_dentry->d_name.len + 1)
+	),
+	TP_fast_assign(
+		const struct dentry *dentry = fhp->fh_dentry;
+
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->fh_hash = knfsd_fh_hash(&fhp->fh_handle);
+		__entry->type = type & S_IFMT;
+		__entry->access = access;
+		__entry->status = be32_to_cpu(status);
+		if (dentry) {
+			memcpy(__get_str(name), dentry->d_name.name,
+			       dentry->d_name.len);
+			__get_str(name)[dentry->d_name.len] = '\0';
+		} else {
+			__get_str(name)[0] = '\0';
+		}
+	),
+	TP_printk("xid=0x%08x fh_hash=0x%08x type=%s access=%s name=%s status=%s",
+		__entry->xid, __entry->fh_hash,
+		show_inode_type(__entry->type),
+		show_nfsd_may_flags(__entry->access),
+		__get_str(name), show_nfs4_status(__entry->status)
+	)
+);
+
 DECLARE_EVENT_CLASS(nfsd_fh_err_class,
 	TP_PROTO(struct svc_rqst *rqstp,
 		 struct svc_fh	*fhp,



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

* Re: [PATCH v2 00/27] NFSD operation monitoring tracepoints
  2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
                   ` (26 preceding siblings ...)
  2020-09-21 18:13 ` [PATCH v2 27/27] NFSD: Replace dprintk callsites in fs/nfsd/nfsfh.c Chuck Lever
@ 2020-09-24 21:36 ` J. Bruce Fields
  2020-09-25 13:59   ` Chuck Lever
  27 siblings, 1 reply; 43+ messages in thread
From: J. Bruce Fields @ 2020-09-24 21:36 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Bill.Baker, linux-nfs

On Mon, Sep 21, 2020 at 02:10:49PM -0400, Chuck Lever wrote:
> As I've been working on various server bugs, I've been adding
> tracepoints that record NFS operation arguments. Here's an updated
> snapshot of this work for your review and comment.
> 
> The idea here is to provide a degree of NFS traffic observability
> without needing network capture. Tracepoints are generally lighter-
> weight than full network capture, allowing effective capture-time
> data reduction:

I do wonder when tracepoints seem to duplicate information you could get
from network traces, so thanks for taking the time to explain this.  It
makes sense to me.

The patches look fine.  The only one I'm I'm on the fence about is the
last with the split up of the dispatch functions.  I'll ask some
questions there....

--b.

> 
> - One or a handful of these can be enabled at a time
> - Each tracepoint records much less data per operation than capture
> - Extra capture-time filtering can reduce data amount even further
> - Some of these operations are infrequent enough that their
>  tracepoint could be enabled persistently without a significant
>  performance impact (for example, for security auditing)
> 
> The topic branch has been updated as well:
> 
> git://git.linux-nfs.org/projects/cel/cel-2.6.git nfsd-more-tracepoints
> 
> 
> Changes since RFC:
> * s/SPDK/SPDX and corrected the spelling of Christoph's surname
> * Fixed a build error noticed by <lkp@intel.com>
> * Introduced generic headers for VFS and NFS protocol display macros
> * nfsd4_compoundstatus now displays NFS4ERR codes symbolically
> * The svc_process tracepoint now displays the RPC procedure symbolically
> * NFSD dispatcher now displays procedure names and status codes symbolically
> * fh_verify tracepoint tentatively included; it adds a lot of noise, but perhaps not much value
> * Cleaned up the remaining PROC() macros in the server code
> * Removed trace_printk's that were introduced during the RFC series
> * Removed redundant nfsd4_close tracepoint
> 
> ---
> 
> Chuck Lever (27):
>       NFS: Move generic FS show macros to global header
>       NFS: Move NFS protocol display macros to global header
>       NFSD: Add SPDX header for fs/nfsd/trace.c
>       SUNRPC: Move the svc_xdr_recvfrom() tracepoint
>       SUNRPC: Add svc_xdr_authenticate tracepoint
>       lockd: Replace PROC() macro with open code
>       NFSACL: Replace PROC() macro with open code
>       SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
>       NFSD: Clean up the show_nf_may macro
>       NFSD: Remove extra "0x" in tracepoint format specifier
>       NFSD: Constify @fh argument of knfsd_fh_hash()
>       NFSD: Add tracepoint in nfsd_setattr()
>       NFSD: Add tracepoint for nfsd_access()
>       NFSD: nfsd_compound_status tracepoint should record XID
>       NFSD: Add client ID lifetime tracepoints
>       NFSD: Add tracepoints to report NFSv4 session state
>       NFSD: Add a tracepoint to report the current filehandle
>       NFSD: Add GETATTR tracepoint
>       NFSD: Add tracepoint in nfsd4_stateid_preprocess()
>       NFSD: Add tracepoint to report arguments to NFSv4 OPEN
>       NFSD: Add a tracepoint for DELEGRETURN
>       NFSD: Add a lookup tracepoint
>       NFSD: Add lock and locku tracepoints
>       NFSD: Add tracepoints to record the result of TEST_STATEID and FREE_STATEID
>       NFSD: Rename nfsd_ tracepoints to nfsd4_
>       NFSD: Add tracepoints in the NFS dispatcher
>       NFSD: Replace dprintk callsites in fs/nfsd/nfsfh.c
> 
> 
>  fs/lockd/svc4proc.c           | 263 +++++++++--
>  fs/lockd/svcproc.c            | 265 +++++++++--
>  fs/nfs/callback_xdr.c         |   2 +
>  fs/nfs/nfs4trace.h            | 387 ++--------------
>  fs/nfs/nfstrace.h             | 113 +----
>  fs/nfs/pnfs.h                 |   4 -
>  fs/nfsd/nfs2acl.c             |  79 +++-
>  fs/nfsd/nfs3acl.c             |  54 ++-
>  fs/nfsd/nfs3proc.c            |  25 +
>  fs/nfsd/nfs4callback.c        |  28 +-
>  fs/nfsd/nfs4layouts.c         |  16 +-
>  fs/nfsd/nfs4proc.c            |  43 +-
>  fs/nfsd/nfs4state.c           | 100 ++--
>  fs/nfsd/nfsd.h                |   1 +
>  fs/nfsd/nfsfh.c               |  36 +-
>  fs/nfsd/nfsfh.h               |   7 +-
>  fs/nfsd/nfsproc.c             |  21 +
>  fs/nfsd/nfssvc.c              | 198 +++++---
>  fs/nfsd/trace.c               |   1 +
>  fs/nfsd/trace.h               | 844 ++++++++++++++++++++++++++++++----
>  fs/nfsd/vfs.c                 |  18 +-
>  fs/nfsd/xdr4.h                |   3 +-
>  include/linux/nfs4.h          |   4 +
>  include/linux/sunrpc/svc.h    |   1 +
>  include/trace/events/fs.h     |  30 ++
>  include/trace/events/nfs.h    | 511 ++++++++++++++++++++
>  include/trace/events/sunrpc.h |  33 +-
>  include/uapi/linux/nfsacl.h   |   2 +
>  net/sunrpc/svc_xprt.c         |   4 +-
>  net/sunrpc/svcauth.c          |   5 +-
>  30 files changed, 2187 insertions(+), 911 deletions(-)
>  create mode 100644 include/trace/events/nfs.h
> 
> --
> Chuck Lever

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

* Re: [PATCH v2 26/27] NFSD: Add tracepoints in the NFS dispatcher
  2020-09-21 18:13 ` [PATCH v2 26/27] NFSD: Add tracepoints in the NFS dispatcher Chuck Lever
@ 2020-09-24 23:45   ` J. Bruce Fields
  2020-09-25 13:59     ` Chuck Lever
  0 siblings, 1 reply; 43+ messages in thread
From: J. Bruce Fields @ 2020-09-24 23:45 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Bill.Baker, linux-nfs

On Mon, Sep 21, 2020 at 02:13:07PM -0400, Chuck Lever wrote:
> This is follow-on work to the tracepoints added in the NFS server's
> duplicate reply cache. Here, tracepoints are introduced that report
> replies from cache as well as encoding and decoding errors.
> 
> The NFSv2, v3, and v4 dispatcher requirements have diverged over
> time, leaving us with a little bit of technical debt. In addition,
> I wanted to add a tracepoint for NFSv2 and NFSv3 similar to the
> nfsd4_compound/compoundstatus tracepoints. Lastly, removing some
> conditional branches from this hot path helps optimize CPU
> utilization. So, I've duplicated the nfsd_dispatcher function.

Comparing current nfsd_dispatch to the nfsv2/v3 nfsd_dispatch: the only
thing I spotted removed from the v2/v3-specific dispatch is the
rq_lease_breaker = NULL.  (I think that's not correct, actually.  We
could remove the need for that to be set in the v2/v3 case, but with the
current code it does need to be set.)

Comparing current nfsd_dispatch to the nfsv4 nfsd4_dispatch, the
v4-specific dispatch does away with nfs_request_too_big() and the
v2-specific shortcut in the error encoding case.

So these still look *very* similar.  I don't feel like we're getting a
lot of benefit out of splitting these out.

By the way, the combination of copying a bunch of code, doing some
common cleanup, and dropping version-specific stuff makes it a little
hard to sort out what's going on.  If it were me, I'd do this as:

	- one patch to do common cleanup (dropping some redundant
	  comments, using argv/resv variables to cleanup calculations,
	  etc.)
	- a second patch that just duplicates the one nfsd_dispatch into
	  nfsd_dispatch and nfsd4_dispatch
	- a third patch that just removes the stuff we don't need from
	  the newly duplicated dispatchers.

and then it'd be obvious what's changed.

--b.

> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
>  fs/nfsd/nfs2acl.c  |    2 -
>  fs/nfsd/nfs3acl.c  |    2 -
>  fs/nfsd/nfs4proc.c |    2 -
>  fs/nfsd/nfsd.h     |    1 
>  fs/nfsd/nfssvc.c   |  198 ++++++++++++++++++++++++++++++++++------------------
>  fs/nfsd/trace.h    |   50 +++++++++++++
>  6 files changed, 183 insertions(+), 72 deletions(-)
> 
> diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
> index 54e597918822..894b8f0594e2 100644
> --- a/fs/nfsd/nfs2acl.c
> +++ b/fs/nfsd/nfs2acl.c
> @@ -416,6 +416,6 @@ const struct svc_version nfsd_acl_version2 = {
>  	.vs_nproc	= 5,
>  	.vs_proc	= nfsd_acl_procedures2,
>  	.vs_count	= nfsd_acl_count2,
> -	.vs_dispatch	= nfsd_dispatch,
> +	.vs_dispatch	= nfsd4_dispatch,
>  	.vs_xdrsize	= NFS3_SVC_XDRSIZE,
>  };
> diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
> index 7f512dec7460..924ebb19c59c 100644
> --- a/fs/nfsd/nfs3acl.c
> +++ b/fs/nfsd/nfs3acl.c
> @@ -282,7 +282,7 @@ const struct svc_version nfsd_acl_version3 = {
>  	.vs_nproc	= 3,
>  	.vs_proc	= nfsd_acl_procedures3,
>  	.vs_count	= nfsd_acl_count3,
> -	.vs_dispatch	= nfsd_dispatch,
> +	.vs_dispatch	= nfsd4_dispatch,
>  	.vs_xdrsize	= NFS3_SVC_XDRSIZE,
>  };
>  
> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
> index 49109645af24..61302641f651 100644
> --- a/fs/nfsd/nfs4proc.c
> +++ b/fs/nfsd/nfs4proc.c
> @@ -3320,7 +3320,7 @@ const struct svc_version nfsd_version4 = {
>  	.vs_nproc		= 2,
>  	.vs_proc		= nfsd_procedures4,
>  	.vs_count		= nfsd_count3,
> -	.vs_dispatch		= nfsd_dispatch,
> +	.vs_dispatch		= nfsd4_dispatch,
>  	.vs_xdrsize		= NFS4_SVC_XDRSIZE,
>  	.vs_rpcb_optnl		= true,
>  	.vs_need_cong_ctrl	= true,
> diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
> index cb742e17e04a..7fa4b19dd2f7 100644
> --- a/fs/nfsd/nfsd.h
> +++ b/fs/nfsd/nfsd.h
> @@ -78,6 +78,7 @@ extern const struct seq_operations nfs_exports_op;
>   */
>  int		nfsd_svc(int nrservs, struct net *net, const struct cred *cred);
>  int		nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
> +int		nfsd4_dispatch(struct svc_rqst *rqstp, __be32 *statp);
>  
>  int		nfsd_nrthreads(struct net *);
>  int		nfsd_nrpools(struct net *);
> diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
> index f7f6473578af..d626eea1c78a 100644
> --- a/fs/nfsd/nfssvc.c
> +++ b/fs/nfsd/nfssvc.c
> @@ -28,6 +28,7 @@
>  #include "vfs.h"
>  #include "netns.h"
>  #include "filecache.h"
> +#include "trace.h"
>  
>  #define NFSDDBG_FACILITY	NFSDDBG_SVC
>  
> @@ -964,7 +965,7 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
>  {
>  	if (nfserr == nfserr_jukebox && vers == 2)
>  		return nfserr_dropit;
> -	if (nfserr == nfserr_wrongsec && vers < 4)
> +	if (nfserr == nfserr_wrongsec)
>  		return nfserr_acces;
>  	return nfserr;
>  }
> @@ -980,18 +981,6 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
>  static bool nfs_request_too_big(struct svc_rqst *rqstp,
>  				const struct svc_procedure *proc)
>  {
> -	/*
> -	 * The ACL code has more careful bounds-checking and is not
> -	 * susceptible to this problem:
> -	 */
> -	if (rqstp->rq_prog != NFS_PROGRAM)
> -		return false;
> -	/*
> -	 * Ditto NFSv4 (which can in theory have argument and reply both
> -	 * more than a page):
> -	 */
> -	if (rqstp->rq_vers >= 4)
> -		return false;
>  	/* The reply will be small, we're OK: */
>  	if (proc->pc_xdrressize > 0 &&
>  	    proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
> @@ -1000,81 +989,152 @@ static bool nfs_request_too_big(struct svc_rqst *rqstp,
>  	return rqstp->rq_arg.len > PAGE_SIZE;
>  }
>  
> -int
> -nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
> +/**
> + * nfsd_dispatch - Process an NFSv2 or NFSv3 request
> + * @rqstp: incoming NFS request
> + * @statp: OUT: RPC accept_stat value
> + *
> + * Return values:
> + *  %0: Processing complete; do not send a Reply
> + *  %1: Processing complete; send a Reply
> + */
> +int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
>  {
> -	const struct svc_procedure *proc;
> -	__be32			nfserr;
> -	__be32			*nfserrp;
> -
> -	dprintk("nfsd_dispatch: vers %d proc %d\n",
> -				rqstp->rq_vers, rqstp->rq_proc);
> -	proc = rqstp->rq_procinfo;
> -
> -	if (nfs_request_too_big(rqstp, proc)) {
> -		dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
> -		*statp = rpc_garbage_args;
> -		return 1;
> +	const struct svc_procedure *proc = rqstp->rq_procinfo;
> +	struct kvec *argv = &rqstp->rq_arg.head[0];
> +	struct kvec *resv = &rqstp->rq_res.head[0];
> +	__be32 nfserr, *nfserrp;
> +
> +	if (nfs_request_too_big(rqstp, proc))
> +		goto out_too_large;
> +
> +	if (proc->pc_decode && !procp->pc_decode(rqstp, argv->iov_base))
> +		goto out_decode_err;
> +
> +	rqstp->rq_cachetype = proc->pc_cachetype;
> +	switch (nfsd_cache_lookup(rqstp)) {
> +	case RC_DROPIT:
> +		goto out_dropit;
> +	case RC_REPLY:
> +		goto out_cached_reply;
> +	case RC_DOIT:
> +		break;
>  	}
> -	rqstp->rq_lease_breaker = NULL;
> +
> +	nfserrp = resv->iov_base + resv->iov_len;
> +	resv->iov_len += sizeof(__be32);
> +	nfserr = proc->pc_func(rqstp);
> +	nfserr = map_new_errors(rqstp->rq_vers, nfserr);
> +	if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags))
> +		goto out_update_drop;
> +	if (rqstp->rq_proc)
> +		*nfserrp++ = nfserr;
> +
> +	/* For NFSv2, additional info is never returned in case of an error. */
> +	if (!(nfserr && rqstp->rq_vers == 2))
> +		if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp))
> +			goto out_encode_err;
> +
> +	nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1);
> +	trace_nfsd_svc_status(rqstp, proc, nfserr);
> +	return 1;
> +
> +out_too_large:
> +	trace_nfsd_svc_too_large_err(rqstp);
> +	*statp = rpc_garbage_args;
> +	return 1;
> +
> +out_decode_err:
> +	trace_nfsd_svc_decode_err(rqstp);
> +	*statp = rpc_garbage_args;
> +	return 1;
> +
> +out_update_drop:
> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
> +out_dropit:
> +	trace_nfsd_svc_dropit(rqstp);
> +	return 0;
> +
> +out_cached_reply:
> +	trace_nfsd_svc_cached_reply(rqstp);
> +	return 1;
> +
> +out_encode_err:
> +	trace_nfsd_svc_encode_err(rqstp);
> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
> +	*statp = rpc_system_err;
> +	return 1;
> +}
> +
> +/**
> + * nfsd4_dispatch - Process an NFSv4 or NFSACL request
> + * @rqstp: incoming NFS request
> + * @statp: OUT: RPC accept_stat value
> + *
> + * Return values:
> + *  %0: Processing complete; do not send a Reply
> + *  %1: Processing complete; send a Reply
> + */
> +int nfsd4_dispatch(struct svc_rqst *rqstp, __be32 *statp)
> +{
> +	const struct svc_procedure *proc = rqstp->rq_procinfo;
> +	struct kvec *argv = &rqstp->rq_arg.head[0];
> +	struct kvec *resv = &rqstp->rq_res.head[0];
> +	__be32 nfserr, *nfserrp;
> +
>  	/*
>  	 * Give the xdr decoder a chance to change this if it wants
>  	 * (necessary in the NFSv4.0 compound case)
>  	 */
>  	rqstp->rq_cachetype = proc->pc_cachetype;
> -	/* Decode arguments */
> -	if (proc->pc_decode &&
> -	    !proc->pc_decode(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base)) {
> -		dprintk("nfsd: failed to decode arguments!\n");
> -		*statp = rpc_garbage_args;
> -		return 1;
> -	}
> +	rqstp->rq_lease_breaker = NULL;
> +
> +	if (proc->pc_decode && !procp->pc_decode(rqstp, argv->iov_base))
> +		goto out_decode_err;
>  
> -	/* Check whether we have this call in the cache. */
>  	switch (nfsd_cache_lookup(rqstp)) {
>  	case RC_DROPIT:
> -		return 0;
> +		goto out_dropit;
>  	case RC_REPLY:
> -		return 1;
> -	case RC_DOIT:;
> -		/* do it */
> +		goto out_cached_reply;
> +	case RC_DOIT:
> +		break;
>  	}
>  
> -	/* need to grab the location to store the status, as
> -	 * nfsv4 does some encoding while processing 
> -	 */
> -	nfserrp = rqstp->rq_res.head[0].iov_base
> -		+ rqstp->rq_res.head[0].iov_len;
> -	rqstp->rq_res.head[0].iov_len += sizeof(__be32);
> -
> -	/* Now call the procedure handler, and encode NFS status. */
> +	nfserrp = resv->iov_base + resv->iov_len;
> +	resv->iov_len += sizeof(__be32);
>  	nfserr = proc->pc_func(rqstp);
> -	nfserr = map_new_errors(rqstp->rq_vers, nfserr);
> -	if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags)) {
> -		dprintk("nfsd: Dropping request; may be revisited later\n");
> -		nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
> -		return 0;
> -	}
> -
> -	if (rqstp->rq_proc != 0)
> +	if (test_bit(RQ_DROPME, &rqstp->rq_flags))
> +		goto out_update_drop;
> +	if (rqstp->rq_proc)
>  		*nfserrp++ = nfserr;
>  
> -	/* Encode result.
> -	 * For NFSv2, additional info is never returned in case of an error.
> -	 */
> -	if (!(nfserr && rqstp->rq_vers == 2)) {
> -		if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp)) {
> -			/* Failed to encode result. Release cache entry */
> -			dprintk("nfsd: failed to encode result!\n");
> -			nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
> -			*statp = rpc_system_err;
> -			return 1;
> -		}
> -	}
> +	if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp))
> +		goto out_encode_err;
>  
> -	/* Store reply in cache. */
>  	nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1);
>  	return 1;
> +
> +out_decode_err:
> +	trace_nfsd_svc_decode_err(rqstp);
> +	*statp = rpc_garbage_args;
> +	return 1;
> +
> +out_update_drop:
> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
> +out_dropit:
> +	trace_nfsd_svc_dropit(rqstp);
> +	return 0;
> +
> +out_cached_reply:
> +	trace_nfsd_svc_cached_reply(rqstp);
> +	return 1;
> +
> +out_encode_err:
> +	trace_nfsd_svc_encode_err(rqstp);
> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
> +	*statp = rpc_system_err;
> +	return 1;
>  }
>  
>  int nfsd_pool_stats_open(struct inode *inode, struct file *file)
> diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
> index 53115fbc00b2..50ab4a84c25f 100644
> --- a/fs/nfsd/trace.h
> +++ b/fs/nfsd/trace.h
> @@ -32,6 +32,56 @@
>  		{ NFSD_MAY_READ_IF_EXEC,	"READ_IF_EXEC" },	\
>  		{ NFSD_MAY_64BIT_COOKIE,	"64BIT_COOKIE" })
>  
> +DECLARE_EVENT_CLASS(nfsd_simple_class,
> +	TP_PROTO(
> +		const struct svc_rqst *rqstp
> +	),
> +	TP_ARGS(rqstp),
> +	TP_STRUCT__entry(
> +		__field(u32, xid)
> +	),
> +	TP_fast_assign(
> +		__entry->xid = be32_to_cpu(rqstp->rq_xid);
> +	),
> +	TP_printk("xid=0x%08x", __entry->xid)
> +);
> +
> +#define DEFINE_NFSD_SIMPLE_EVENT(name)			\
> +DEFINE_EVENT(nfsd_simple_class, nfsd_##name,		\
> +	TP_PROTO(const struct svc_rqst *rqstp),		\
> +	TP_ARGS(rqstp))
> +
> +DEFINE_NFSD_SIMPLE_EVENT(svc_too_large_err);
> +DEFINE_NFSD_SIMPLE_EVENT(svc_decode_err);
> +DEFINE_NFSD_SIMPLE_EVENT(svc_dropit);
> +DEFINE_NFSD_SIMPLE_EVENT(svc_cached_reply);
> +DEFINE_NFSD_SIMPLE_EVENT(svc_encode_err);
> +
> +TRACE_EVENT(nfsd_svc_status,
> +	TP_PROTO(
> +		const struct svc_rqst *rqstp,
> +		const struct svc_procedure *proc,
> +		__be32 status
> +	),
> +	TP_ARGS(rqstp, proc, status),
> +	TP_STRUCT__entry(
> +		__field(u32, xid)
> +		__field(u32, version)
> +		__field(unsigned long, status)
> +		__string(procedure, rqstp->rq_procinfo->pc_name)
> +	),
> +	TP_fast_assign(
> +		__entry->xid = be32_to_cpu(rqstp->rq_xid);
> +		__entry->version = rqstp->rq_vers;
> +		__entry->status = be32_to_cpu(status);
> +		__assign_str(procedure, rqstp->rq_procinfo->pc_name);
> +	),
> +	TP_printk("xid=0x%08x version=%u procedure=%s status=%s",
> +		__entry->xid, __entry->version, __get_str(procedure),
> +		show_nfs_status(__entry->status)
> +	)
> +);
> +
>  TRACE_EVENT(nfsd_access,
>  	TP_PROTO(
>  		const struct svc_rqst *rqstp,
> 

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

* Re: [PATCH v2 00/27] NFSD operation monitoring tracepoints
  2020-09-24 21:36 ` [PATCH v2 00/27] NFSD operation monitoring tracepoints J. Bruce Fields
@ 2020-09-25 13:59   ` Chuck Lever
  2020-09-25 14:32     ` Bruce Fields
  0 siblings, 1 reply; 43+ messages in thread
From: Chuck Lever @ 2020-09-25 13:59 UTC (permalink / raw)
  To: Bruce Fields; +Cc: Bill Baker, Linux NFS Mailing List

Thanks Bruce, for your time, attention, and comments!

> On Sep 24, 2020, at 5:36 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
> 
> On Mon, Sep 21, 2020 at 02:10:49PM -0400, Chuck Lever wrote:
>> As I've been working on various server bugs, I've been adding
>> tracepoints that record NFS operation arguments. Here's an updated
>> snapshot of this work for your review and comment.
>> 
>> The idea here is to provide a degree of NFS traffic observability
>> without needing network capture. Tracepoints are generally lighter-
>> weight than full network capture, allowing effective capture-time
>> data reduction:
> 
> I do wonder when tracepoints seem to duplicate information you could get
> from network traces, so thanks for taking the time to explain this.  It
> makes sense to me.
> 
> The patches look fine.  The only one I'm I'm on the fence about is the
> last with the split up of the dispatch functions.  I'll ask some
> questions there....

To be clear to everyone, this series is still "preview". I expect
more churn in these patches, thus I don't consider the series ready
to be merged by any stretch.


> --b.
> 
>> 
>> - One or a handful of these can be enabled at a time
>> - Each tracepoint records much less data per operation than capture
>> - Extra capture-time filtering can reduce data amount even further
>> - Some of these operations are infrequent enough that their
>> tracepoint could be enabled persistently without a significant
>> performance impact (for example, for security auditing)
>> 
>> The topic branch has been updated as well:
>> 
>> git://git.linux-nfs.org/projects/cel/cel-2.6.git nfsd-more-tracepoints
>> 
>> 
>> Changes since RFC:
>> * s/SPDK/SPDX and corrected the spelling of Christoph's surname
>> * Fixed a build error noticed by <lkp@intel.com>
>> * Introduced generic headers for VFS and NFS protocol display macros
>> * nfsd4_compoundstatus now displays NFS4ERR codes symbolically
>> * The svc_process tracepoint now displays the RPC procedure symbolically
>> * NFSD dispatcher now displays procedure names and status codes symbolically
>> * fh_verify tracepoint tentatively included; it adds a lot of noise, but perhaps not much value
>> * Cleaned up the remaining PROC() macros in the server code
>> * Removed trace_printk's that were introduced during the RFC series
>> * Removed redundant nfsd4_close tracepoint
>> 
>> ---
>> 
>> Chuck Lever (27):
>>      NFS: Move generic FS show macros to global header
>>      NFS: Move NFS protocol display macros to global header
>>      NFSD: Add SPDX header for fs/nfsd/trace.c
>>      SUNRPC: Move the svc_xdr_recvfrom() tracepoint
>>      SUNRPC: Add svc_xdr_authenticate tracepoint
>>      lockd: Replace PROC() macro with open code
>>      NFSACL: Replace PROC() macro with open code
>>      SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
>>      NFSD: Clean up the show_nf_may macro
>>      NFSD: Remove extra "0x" in tracepoint format specifier
>>      NFSD: Constify @fh argument of knfsd_fh_hash()
>>      NFSD: Add tracepoint in nfsd_setattr()
>>      NFSD: Add tracepoint for nfsd_access()
>>      NFSD: nfsd_compound_status tracepoint should record XID
>>      NFSD: Add client ID lifetime tracepoints
>>      NFSD: Add tracepoints to report NFSv4 session state
>>      NFSD: Add a tracepoint to report the current filehandle
>>      NFSD: Add GETATTR tracepoint
>>      NFSD: Add tracepoint in nfsd4_stateid_preprocess()
>>      NFSD: Add tracepoint to report arguments to NFSv4 OPEN
>>      NFSD: Add a tracepoint for DELEGRETURN
>>      NFSD: Add a lookup tracepoint
>>      NFSD: Add lock and locku tracepoints
>>      NFSD: Add tracepoints to record the result of TEST_STATEID and FREE_STATEID
>>      NFSD: Rename nfsd_ tracepoints to nfsd4_
>>      NFSD: Add tracepoints in the NFS dispatcher
>>      NFSD: Replace dprintk callsites in fs/nfsd/nfsfh.c
>> 
>> 
>> fs/lockd/svc4proc.c           | 263 +++++++++--
>> fs/lockd/svcproc.c            | 265 +++++++++--
>> fs/nfs/callback_xdr.c         |   2 +
>> fs/nfs/nfs4trace.h            | 387 ++--------------
>> fs/nfs/nfstrace.h             | 113 +----
>> fs/nfs/pnfs.h                 |   4 -
>> fs/nfsd/nfs2acl.c             |  79 +++-
>> fs/nfsd/nfs3acl.c             |  54 ++-
>> fs/nfsd/nfs3proc.c            |  25 +
>> fs/nfsd/nfs4callback.c        |  28 +-
>> fs/nfsd/nfs4layouts.c         |  16 +-
>> fs/nfsd/nfs4proc.c            |  43 +-
>> fs/nfsd/nfs4state.c           | 100 ++--
>> fs/nfsd/nfsd.h                |   1 +
>> fs/nfsd/nfsfh.c               |  36 +-
>> fs/nfsd/nfsfh.h               |   7 +-
>> fs/nfsd/nfsproc.c             |  21 +
>> fs/nfsd/nfssvc.c              | 198 +++++---
>> fs/nfsd/trace.c               |   1 +
>> fs/nfsd/trace.h               | 844 ++++++++++++++++++++++++++++++----
>> fs/nfsd/vfs.c                 |  18 +-
>> fs/nfsd/xdr4.h                |   3 +-
>> include/linux/nfs4.h          |   4 +
>> include/linux/sunrpc/svc.h    |   1 +
>> include/trace/events/fs.h     |  30 ++
>> include/trace/events/nfs.h    | 511 ++++++++++++++++++++
>> include/trace/events/sunrpc.h |  33 +-
>> include/uapi/linux/nfsacl.h   |   2 +
>> net/sunrpc/svc_xprt.c         |   4 +-
>> net/sunrpc/svcauth.c          |   5 +-
>> 30 files changed, 2187 insertions(+), 911 deletions(-)
>> create mode 100644 include/trace/events/nfs.h
>> 
>> --
>> Chuck Lever

--
Chuck Lever




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

* Re: [PATCH v2 26/27] NFSD: Add tracepoints in the NFS dispatcher
  2020-09-24 23:45   ` J. Bruce Fields
@ 2020-09-25 13:59     ` Chuck Lever
  2020-09-25 14:17       ` Bruce Fields
                         ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-25 13:59 UTC (permalink / raw)
  To: Bruce Fields; +Cc: Bill Baker, Linux NFS Mailing List



> On Sep 24, 2020, at 7:45 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
> 
> On Mon, Sep 21, 2020 at 02:13:07PM -0400, Chuck Lever wrote:
>> This is follow-on work to the tracepoints added in the NFS server's
>> duplicate reply cache. Here, tracepoints are introduced that report
>> replies from cache as well as encoding and decoding errors.
>> 
>> The NFSv2, v3, and v4 dispatcher requirements have diverged over
>> time, leaving us with a little bit of technical debt. In addition,
>> I wanted to add a tracepoint for NFSv2 and NFSv3 similar to the
>> nfsd4_compound/compoundstatus tracepoints. Lastly, removing some
>> conditional branches from this hot path helps optimize CPU
>> utilization. So, I've duplicated the nfsd_dispatcher function.
> 
> Comparing current nfsd_dispatch to the nfsv2/v3 nfsd_dispatch: the only
> thing I spotted removed from the v2/v3-specific dispatch is the
> rq_lease_breaker = NULL.  (I think that's not correct, actually.  We
> could remove the need for that to be set in the v2/v3 case, but with the
> current code it does need to be set.)

Noted with thanks.


> Comparing current nfsd_dispatch to the nfsv4 nfsd4_dispatch, the
> v4-specific dispatch does away with nfs_request_too_big() and the
> v2-specific shortcut in the error encoding case.
> 
> So these still look *very* similar.  I don't feel like we're getting a
> lot of benefit out of splitting these out.

I don't disagree with that at all. At this point I'm just noodling
to see what's possible. I'm now toying with other ways to add high-
value tracing in the legacy ULPs. In the end I might end up avoiding
significant changes in the dispatchers in order to add tracing.

However, a few thoughts I had while learning how the dispatcher
code works.

There are some opportunities for reducing instruction path length
and the number of conditional branches in here. It's a hot path,
so I think we should consider some careful micro-optimizations
even if they don't add significant new features or do add some
code duplication.

In user space, the library (iirc) assumes each ULP provides it's
own dispatcher function. I'd consider duplicating and removing
svc_generic_dispatcher() to simplify the pasta in svc_process(),
again as a micro-optimization and for better code legibility.

lockd's pc_func returns an RPC accept_stat, but the NFSD pc_func
methods return an NFS status. The latter feels like a layering
violation for the sake of reducing a small amount of code
duplication. I'd rather see encoding of the NFS status handled in
the NFS Reply encoders, since that is an XDR function, and because
that logic seems slightly different for NFSv2, support for which
we'd like to deprecate at some point.

Note also that *statp in nfsd_dispatch is never explicitly set to
rpc_success in the normal execution flow. It relies on the
equivalence of rpc_success and nfs_ok, which is convenient, but
confusing to read. It might be cleaner if *statp was made an enum
to make it explicit what set of values go in that return variable.


> By the way, the combination of copying a bunch of code, doing some
> common cleanup, and dropping version-specific stuff makes it a little
> hard to sort out what's going on.  If it were me, I'd do this as:
> 
> 	- one patch to do common cleanup (dropping some redundant
> 	  comments, using argv/resv variables to cleanup calculations,
> 	  etc.)
> 	- a second patch that just duplicates the one nfsd_dispatch into
> 	  nfsd_dispatch and nfsd4_dispatch
> 	- a third patch that just removes the stuff we don't need from
> 	  the newly duplicated dispatchers.
> 
> and then it'd be obvious what's changed.

Good points. The series is still immature, and I tend to maintain
larger checkpoint patches that get broken down over time to make
it more obvious what is changing and why. I'll keep your comments
in mind as this work evolves. Feel free to make similar suggestions
about my future work.


> --b.
> 
>> 
>> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
>> ---
>> fs/nfsd/nfs2acl.c  |    2 -
>> fs/nfsd/nfs3acl.c  |    2 -
>> fs/nfsd/nfs4proc.c |    2 -
>> fs/nfsd/nfsd.h     |    1 
>> fs/nfsd/nfssvc.c   |  198 ++++++++++++++++++++++++++++++++++------------------
>> fs/nfsd/trace.h    |   50 +++++++++++++
>> 6 files changed, 183 insertions(+), 72 deletions(-)
>> 
>> diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
>> index 54e597918822..894b8f0594e2 100644
>> --- a/fs/nfsd/nfs2acl.c
>> +++ b/fs/nfsd/nfs2acl.c
>> @@ -416,6 +416,6 @@ const struct svc_version nfsd_acl_version2 = {
>> 	.vs_nproc	= 5,
>> 	.vs_proc	= nfsd_acl_procedures2,
>> 	.vs_count	= nfsd_acl_count2,
>> -	.vs_dispatch	= nfsd_dispatch,
>> +	.vs_dispatch	= nfsd4_dispatch,
>> 	.vs_xdrsize	= NFS3_SVC_XDRSIZE,
>> };
>> diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
>> index 7f512dec7460..924ebb19c59c 100644
>> --- a/fs/nfsd/nfs3acl.c
>> +++ b/fs/nfsd/nfs3acl.c
>> @@ -282,7 +282,7 @@ const struct svc_version nfsd_acl_version3 = {
>> 	.vs_nproc	= 3,
>> 	.vs_proc	= nfsd_acl_procedures3,
>> 	.vs_count	= nfsd_acl_count3,
>> -	.vs_dispatch	= nfsd_dispatch,
>> +	.vs_dispatch	= nfsd4_dispatch,
>> 	.vs_xdrsize	= NFS3_SVC_XDRSIZE,
>> };
>> 
>> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
>> index 49109645af24..61302641f651 100644
>> --- a/fs/nfsd/nfs4proc.c
>> +++ b/fs/nfsd/nfs4proc.c
>> @@ -3320,7 +3320,7 @@ const struct svc_version nfsd_version4 = {
>> 	.vs_nproc		= 2,
>> 	.vs_proc		= nfsd_procedures4,
>> 	.vs_count		= nfsd_count3,
>> -	.vs_dispatch		= nfsd_dispatch,
>> +	.vs_dispatch		= nfsd4_dispatch,
>> 	.vs_xdrsize		= NFS4_SVC_XDRSIZE,
>> 	.vs_rpcb_optnl		= true,
>> 	.vs_need_cong_ctrl	= true,
>> diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
>> index cb742e17e04a..7fa4b19dd2f7 100644
>> --- a/fs/nfsd/nfsd.h
>> +++ b/fs/nfsd/nfsd.h
>> @@ -78,6 +78,7 @@ extern const struct seq_operations nfs_exports_op;
>>  */
>> int		nfsd_svc(int nrservs, struct net *net, const struct cred *cred);
>> int		nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
>> +int		nfsd4_dispatch(struct svc_rqst *rqstp, __be32 *statp);
>> 
>> int		nfsd_nrthreads(struct net *);
>> int		nfsd_nrpools(struct net *);
>> diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
>> index f7f6473578af..d626eea1c78a 100644
>> --- a/fs/nfsd/nfssvc.c
>> +++ b/fs/nfsd/nfssvc.c
>> @@ -28,6 +28,7 @@
>> #include "vfs.h"
>> #include "netns.h"
>> #include "filecache.h"
>> +#include "trace.h"
>> 
>> #define NFSDDBG_FACILITY	NFSDDBG_SVC
>> 
>> @@ -964,7 +965,7 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
>> {
>> 	if (nfserr == nfserr_jukebox && vers == 2)
>> 		return nfserr_dropit;
>> -	if (nfserr == nfserr_wrongsec && vers < 4)
>> +	if (nfserr == nfserr_wrongsec)
>> 		return nfserr_acces;
>> 	return nfserr;
>> }
>> @@ -980,18 +981,6 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
>> static bool nfs_request_too_big(struct svc_rqst *rqstp,
>> 				const struct svc_procedure *proc)
>> {
>> -	/*
>> -	 * The ACL code has more careful bounds-checking and is not
>> -	 * susceptible to this problem:
>> -	 */
>> -	if (rqstp->rq_prog != NFS_PROGRAM)
>> -		return false;
>> -	/*
>> -	 * Ditto NFSv4 (which can in theory have argument and reply both
>> -	 * more than a page):
>> -	 */
>> -	if (rqstp->rq_vers >= 4)
>> -		return false;
>> 	/* The reply will be small, we're OK: */
>> 	if (proc->pc_xdrressize > 0 &&
>> 	    proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
>> @@ -1000,81 +989,152 @@ static bool nfs_request_too_big(struct svc_rqst *rqstp,
>> 	return rqstp->rq_arg.len > PAGE_SIZE;
>> }
>> 
>> -int
>> -nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
>> +/**
>> + * nfsd_dispatch - Process an NFSv2 or NFSv3 request
>> + * @rqstp: incoming NFS request
>> + * @statp: OUT: RPC accept_stat value
>> + *
>> + * Return values:
>> + *  %0: Processing complete; do not send a Reply
>> + *  %1: Processing complete; send a Reply
>> + */
>> +int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
>> {
>> -	const struct svc_procedure *proc;
>> -	__be32			nfserr;
>> -	__be32			*nfserrp;
>> -
>> -	dprintk("nfsd_dispatch: vers %d proc %d\n",
>> -				rqstp->rq_vers, rqstp->rq_proc);
>> -	proc = rqstp->rq_procinfo;
>> -
>> -	if (nfs_request_too_big(rqstp, proc)) {
>> -		dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
>> -		*statp = rpc_garbage_args;
>> -		return 1;
>> +	const struct svc_procedure *proc = rqstp->rq_procinfo;
>> +	struct kvec *argv = &rqstp->rq_arg.head[0];
>> +	struct kvec *resv = &rqstp->rq_res.head[0];
>> +	__be32 nfserr, *nfserrp;
>> +
>> +	if (nfs_request_too_big(rqstp, proc))
>> +		goto out_too_large;
>> +
>> +	if (proc->pc_decode && !procp->pc_decode(rqstp, argv->iov_base))
>> +		goto out_decode_err;
>> +
>> +	rqstp->rq_cachetype = proc->pc_cachetype;
>> +	switch (nfsd_cache_lookup(rqstp)) {
>> +	case RC_DROPIT:
>> +		goto out_dropit;
>> +	case RC_REPLY:
>> +		goto out_cached_reply;
>> +	case RC_DOIT:
>> +		break;
>> 	}
>> -	rqstp->rq_lease_breaker = NULL;
>> +
>> +	nfserrp = resv->iov_base + resv->iov_len;
>> +	resv->iov_len += sizeof(__be32);
>> +	nfserr = proc->pc_func(rqstp);
>> +	nfserr = map_new_errors(rqstp->rq_vers, nfserr);
>> +	if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags))
>> +		goto out_update_drop;
>> +	if (rqstp->rq_proc)
>> +		*nfserrp++ = nfserr;
>> +
>> +	/* For NFSv2, additional info is never returned in case of an error. */
>> +	if (!(nfserr && rqstp->rq_vers == 2))
>> +		if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp))
>> +			goto out_encode_err;
>> +
>> +	nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1);
>> +	trace_nfsd_svc_status(rqstp, proc, nfserr);
>> +	return 1;
>> +
>> +out_too_large:
>> +	trace_nfsd_svc_too_large_err(rqstp);
>> +	*statp = rpc_garbage_args;
>> +	return 1;
>> +
>> +out_decode_err:
>> +	trace_nfsd_svc_decode_err(rqstp);
>> +	*statp = rpc_garbage_args;
>> +	return 1;
>> +
>> +out_update_drop:
>> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>> +out_dropit:
>> +	trace_nfsd_svc_dropit(rqstp);
>> +	return 0;
>> +
>> +out_cached_reply:
>> +	trace_nfsd_svc_cached_reply(rqstp);
>> +	return 1;
>> +
>> +out_encode_err:
>> +	trace_nfsd_svc_encode_err(rqstp);
>> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>> +	*statp = rpc_system_err;
>> +	return 1;
>> +}
>> +
>> +/**
>> + * nfsd4_dispatch - Process an NFSv4 or NFSACL request
>> + * @rqstp: incoming NFS request
>> + * @statp: OUT: RPC accept_stat value
>> + *
>> + * Return values:
>> + *  %0: Processing complete; do not send a Reply
>> + *  %1: Processing complete; send a Reply
>> + */
>> +int nfsd4_dispatch(struct svc_rqst *rqstp, __be32 *statp)
>> +{
>> +	const struct svc_procedure *proc = rqstp->rq_procinfo;
>> +	struct kvec *argv = &rqstp->rq_arg.head[0];
>> +	struct kvec *resv = &rqstp->rq_res.head[0];
>> +	__be32 nfserr, *nfserrp;
>> +
>> 	/*
>> 	 * Give the xdr decoder a chance to change this if it wants
>> 	 * (necessary in the NFSv4.0 compound case)
>> 	 */
>> 	rqstp->rq_cachetype = proc->pc_cachetype;
>> -	/* Decode arguments */
>> -	if (proc->pc_decode &&
>> -	    !proc->pc_decode(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base)) {
>> -		dprintk("nfsd: failed to decode arguments!\n");
>> -		*statp = rpc_garbage_args;
>> -		return 1;
>> -	}
>> +	rqstp->rq_lease_breaker = NULL;
>> +
>> +	if (proc->pc_decode && !procp->pc_decode(rqstp, argv->iov_base))
>> +		goto out_decode_err;
>> 
>> -	/* Check whether we have this call in the cache. */
>> 	switch (nfsd_cache_lookup(rqstp)) {
>> 	case RC_DROPIT:
>> -		return 0;
>> +		goto out_dropit;
>> 	case RC_REPLY:
>> -		return 1;
>> -	case RC_DOIT:;
>> -		/* do it */
>> +		goto out_cached_reply;
>> +	case RC_DOIT:
>> +		break;
>> 	}
>> 
>> -	/* need to grab the location to store the status, as
>> -	 * nfsv4 does some encoding while processing 
>> -	 */
>> -	nfserrp = rqstp->rq_res.head[0].iov_base
>> -		+ rqstp->rq_res.head[0].iov_len;
>> -	rqstp->rq_res.head[0].iov_len += sizeof(__be32);
>> -
>> -	/* Now call the procedure handler, and encode NFS status. */
>> +	nfserrp = resv->iov_base + resv->iov_len;
>> +	resv->iov_len += sizeof(__be32);
>> 	nfserr = proc->pc_func(rqstp);
>> -	nfserr = map_new_errors(rqstp->rq_vers, nfserr);
>> -	if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags)) {
>> -		dprintk("nfsd: Dropping request; may be revisited later\n");
>> -		nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>> -		return 0;
>> -	}
>> -
>> -	if (rqstp->rq_proc != 0)
>> +	if (test_bit(RQ_DROPME, &rqstp->rq_flags))
>> +		goto out_update_drop;
>> +	if (rqstp->rq_proc)
>> 		*nfserrp++ = nfserr;
>> 
>> -	/* Encode result.
>> -	 * For NFSv2, additional info is never returned in case of an error.
>> -	 */
>> -	if (!(nfserr && rqstp->rq_vers == 2)) {
>> -		if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp)) {
>> -			/* Failed to encode result. Release cache entry */
>> -			dprintk("nfsd: failed to encode result!\n");
>> -			nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>> -			*statp = rpc_system_err;
>> -			return 1;
>> -		}
>> -	}
>> +	if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp))
>> +		goto out_encode_err;
>> 
>> -	/* Store reply in cache. */
>> 	nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1);
>> 	return 1;
>> +
>> +out_decode_err:
>> +	trace_nfsd_svc_decode_err(rqstp);
>> +	*statp = rpc_garbage_args;
>> +	return 1;
>> +
>> +out_update_drop:
>> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>> +out_dropit:
>> +	trace_nfsd_svc_dropit(rqstp);
>> +	return 0;
>> +
>> +out_cached_reply:
>> +	trace_nfsd_svc_cached_reply(rqstp);
>> +	return 1;
>> +
>> +out_encode_err:
>> +	trace_nfsd_svc_encode_err(rqstp);
>> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>> +	*statp = rpc_system_err;
>> +	return 1;
>> }
>> 
>> int nfsd_pool_stats_open(struct inode *inode, struct file *file)
>> diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
>> index 53115fbc00b2..50ab4a84c25f 100644
>> --- a/fs/nfsd/trace.h
>> +++ b/fs/nfsd/trace.h
>> @@ -32,6 +32,56 @@
>> 		{ NFSD_MAY_READ_IF_EXEC,	"READ_IF_EXEC" },	\
>> 		{ NFSD_MAY_64BIT_COOKIE,	"64BIT_COOKIE" })
>> 
>> +DECLARE_EVENT_CLASS(nfsd_simple_class,
>> +	TP_PROTO(
>> +		const struct svc_rqst *rqstp
>> +	),
>> +	TP_ARGS(rqstp),
>> +	TP_STRUCT__entry(
>> +		__field(u32, xid)
>> +	),
>> +	TP_fast_assign(
>> +		__entry->xid = be32_to_cpu(rqstp->rq_xid);
>> +	),
>> +	TP_printk("xid=0x%08x", __entry->xid)
>> +);
>> +
>> +#define DEFINE_NFSD_SIMPLE_EVENT(name)			\
>> +DEFINE_EVENT(nfsd_simple_class, nfsd_##name,		\
>> +	TP_PROTO(const struct svc_rqst *rqstp),		\
>> +	TP_ARGS(rqstp))
>> +
>> +DEFINE_NFSD_SIMPLE_EVENT(svc_too_large_err);
>> +DEFINE_NFSD_SIMPLE_EVENT(svc_decode_err);
>> +DEFINE_NFSD_SIMPLE_EVENT(svc_dropit);
>> +DEFINE_NFSD_SIMPLE_EVENT(svc_cached_reply);
>> +DEFINE_NFSD_SIMPLE_EVENT(svc_encode_err);
>> +
>> +TRACE_EVENT(nfsd_svc_status,
>> +	TP_PROTO(
>> +		const struct svc_rqst *rqstp,
>> +		const struct svc_procedure *proc,
>> +		__be32 status
>> +	),
>> +	TP_ARGS(rqstp, proc, status),
>> +	TP_STRUCT__entry(
>> +		__field(u32, xid)
>> +		__field(u32, version)
>> +		__field(unsigned long, status)
>> +		__string(procedure, rqstp->rq_procinfo->pc_name)
>> +	),
>> +	TP_fast_assign(
>> +		__entry->xid = be32_to_cpu(rqstp->rq_xid);
>> +		__entry->version = rqstp->rq_vers;
>> +		__entry->status = be32_to_cpu(status);
>> +		__assign_str(procedure, rqstp->rq_procinfo->pc_name);
>> +	),
>> +	TP_printk("xid=0x%08x version=%u procedure=%s status=%s",
>> +		__entry->xid, __entry->version, __get_str(procedure),
>> +		show_nfs_status(__entry->status)
>> +	)
>> +);
>> +
>> TRACE_EVENT(nfsd_access,
>> 	TP_PROTO(
>> 		const struct svc_rqst *rqstp,
>> 

--
Chuck Lever




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

* Re: [PATCH v2 26/27] NFSD: Add tracepoints in the NFS dispatcher
  2020-09-25 13:59     ` Chuck Lever
@ 2020-09-25 14:17       ` Bruce Fields
  2020-09-25 14:21         ` Chuck Lever
  2020-09-25 14:18       ` Chuck Lever
  2020-09-25 14:47       ` Bruce Fields
  2 siblings, 1 reply; 43+ messages in thread
From: Bruce Fields @ 2020-09-25 14:17 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Bill Baker, Linux NFS Mailing List

On Fri, Sep 25, 2020 at 09:59:54AM -0400, Chuck Lever wrote:
> 
> 
> > On Sep 24, 2020, at 7:45 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
> > 
> > On Mon, Sep 21, 2020 at 02:13:07PM -0400, Chuck Lever wrote:
> >> This is follow-on work to the tracepoints added in the NFS server's
> >> duplicate reply cache. Here, tracepoints are introduced that report
> >> replies from cache as well as encoding and decoding errors.
> >> 
> >> The NFSv2, v3, and v4 dispatcher requirements have diverged over
> >> time, leaving us with a little bit of technical debt. In addition,
> >> I wanted to add a tracepoint for NFSv2 and NFSv3 similar to the
> >> nfsd4_compound/compoundstatus tracepoints. Lastly, removing some
> >> conditional branches from this hot path helps optimize CPU
> >> utilization. So, I've duplicated the nfsd_dispatcher function.
> > 
> > Comparing current nfsd_dispatch to the nfsv2/v3 nfsd_dispatch: the only
> > thing I spotted removed from the v2/v3-specific dispatch is the
> > rq_lease_breaker = NULL.  (I think that's not correct, actually.  We
> > could remove the need for that to be set in the v2/v3 case, but with the
> > current code it does need to be set.)
> 
> Noted with thanks.

Maybe just do this?

--b.

commit c7265a111269
Author: J. Bruce Fields <bfields@redhat.com>
Date:   Fri Sep 25 10:12:39 2020 -0400

    nfsd: rq_lease_breaker cleanup
    
    Since only the v4 code cares about it, maybe it's better to leave
    rq_lease_breaker out of the common dispatch code?
    
    Signed-off-by: J. Bruce Fields <bfields@redhat.com>

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 62afcae18e17..a498278ba96b 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -4597,6 +4597,9 @@ static bool nfsd_breaker_owns_lease(struct file_lock *fl)
 
 	if (!i_am_nfsd())
 		return NULL;
+	/* Note rq_prog == NFS_ACL_PROGRAM is also possible: */
+	if (rqst->rq_prog != NFS_PROGRAM || rqst->rq_vers < 4)
+		return NULL;
 	rqst = kthread_data(current);
 	clp = *(rqst->rq_lease_breaker);
 	return dl->dl_stid.sc_client == clp;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index b603dfcdd361..8d6f6f4c8b28 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -1016,7 +1016,6 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 		*statp = rpc_garbage_args;
 		return 1;
 	}
-	rqstp->rq_lease_breaker = NULL;
 	/*
 	 * Give the xdr decoder a chance to change this if it wants
 	 * (necessary in the NFSv4.0 compound case)

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

* Re: [PATCH v2 26/27] NFSD: Add tracepoints in the NFS dispatcher
  2020-09-25 13:59     ` Chuck Lever
  2020-09-25 14:17       ` Bruce Fields
@ 2020-09-25 14:18       ` Chuck Lever
  2020-09-25 14:47       ` Bruce Fields
  2 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-25 14:18 UTC (permalink / raw)
  To: Bruce Fields; +Cc: Bill Baker, Linux NFS Mailing List



> On Sep 25, 2020, at 9:59 AM, Chuck Lever <chuck.lever@oracle.com> wrote:
> 
> 
> 
>> On Sep 24, 2020, at 7:45 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
>> 
>> On Mon, Sep 21, 2020 at 02:13:07PM -0400, Chuck Lever wrote:
>>> This is follow-on work to the tracepoints added in the NFS server's
>>> duplicate reply cache. Here, tracepoints are introduced that report
>>> replies from cache as well as encoding and decoding errors.
>>> 
>>> The NFSv2, v3, and v4 dispatcher requirements have diverged over
>>> time, leaving us with a little bit of technical debt. In addition,
>>> I wanted to add a tracepoint for NFSv2 and NFSv3 similar to the
>>> nfsd4_compound/compoundstatus tracepoints. Lastly, removing some
>>> conditional branches from this hot path helps optimize CPU
>>> utilization. So, I've duplicated the nfsd_dispatcher function.
>> 
>> Comparing current nfsd_dispatch to the nfsv2/v3 nfsd_dispatch: the only
>> thing I spotted removed from the v2/v3-specific dispatch is the
>> rq_lease_breaker = NULL.  (I think that's not correct, actually.  We
>> could remove the need for that to be set in the v2/v3 case, but with the
>> current code it does need to be set.)
> 
> Noted with thanks.
> 
> 
>> Comparing current nfsd_dispatch to the nfsv4 nfsd4_dispatch, the
>> v4-specific dispatch does away with nfs_request_too_big() and the
>> v2-specific shortcut in the error encoding case.
>> 
>> So these still look *very* similar.  I don't feel like we're getting a
>> lot of benefit out of splitting these out.
> 
> I don't disagree with that at all. At this point I'm just noodling
> to see what's possible. I'm now toying with other ways to add high-
> value tracing in the legacy ULPs. In the end I might end up avoiding
> significant changes in the dispatchers in order to add tracing.
> 
> However, a few thoughts I had while learning how the dispatcher
> code works.
> 
> There are some opportunities for reducing instruction path length
> and the number of conditional branches in here. It's a hot path,
> so I think we should consider some careful micro-optimizations
> even if they don't add significant new features or do add some
> code duplication.
> 
> In user space, the library (iirc) assumes each ULP provides it's
> own dispatcher function. I'd consider duplicating and removing
> svc_generic_dispatcher() to simplify the pasta in svc_process(),
> again as a micro-optimization and for better code legibility.
> 
> lockd's pc_func returns an RPC accept_stat, but the NFSD pc_func
> methods return an NFS status. The latter feels like a layering
> violation for the sake of reducing a small amount of code
> duplication. I'd rather see encoding of the NFS status handled in
> the NFS Reply encoders, since that is an XDR function, and because
> that logic seems slightly different for NFSv2, support for which
> we'd like to deprecate at some point.

I misremembered this. nfsd_dispatch simply doesn't set *statp
in the success case, which seems strange.


> Note also that *statp in nfsd_dispatch is never explicitly set to
> rpc_success in the normal execution flow. It relies on the
> equivalence of rpc_success and nfs_ok, which is convenient, but
> confusing to read. It might be cleaner if *statp was made an enum
> to make it explicit what set of values go in that return variable.
> 
> 
>> By the way, the combination of copying a bunch of code, doing some
>> common cleanup, and dropping version-specific stuff makes it a little
>> hard to sort out what's going on.  If it were me, I'd do this as:
>> 
>> 	- one patch to do common cleanup (dropping some redundant
>> 	  comments, using argv/resv variables to cleanup calculations,
>> 	  etc.)
>> 	- a second patch that just duplicates the one nfsd_dispatch into
>> 	  nfsd_dispatch and nfsd4_dispatch
>> 	- a third patch that just removes the stuff we don't need from
>> 	  the newly duplicated dispatchers.
>> 
>> and then it'd be obvious what's changed.
> 
> Good points. The series is still immature, and I tend to maintain
> larger checkpoint patches that get broken down over time to make
> it more obvious what is changing and why. I'll keep your comments
> in mind as this work evolves. Feel free to make similar suggestions
> about my future work.
> 
> 
>> --b.
>> 
>>> 
>>> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
>>> ---
>>> fs/nfsd/nfs2acl.c  |    2 -
>>> fs/nfsd/nfs3acl.c  |    2 -
>>> fs/nfsd/nfs4proc.c |    2 -
>>> fs/nfsd/nfsd.h     |    1 
>>> fs/nfsd/nfssvc.c   |  198 ++++++++++++++++++++++++++++++++++------------------
>>> fs/nfsd/trace.h    |   50 +++++++++++++
>>> 6 files changed, 183 insertions(+), 72 deletions(-)
>>> 
>>> diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
>>> index 54e597918822..894b8f0594e2 100644
>>> --- a/fs/nfsd/nfs2acl.c
>>> +++ b/fs/nfsd/nfs2acl.c
>>> @@ -416,6 +416,6 @@ const struct svc_version nfsd_acl_version2 = {
>>> 	.vs_nproc	= 5,
>>> 	.vs_proc	= nfsd_acl_procedures2,
>>> 	.vs_count	= nfsd_acl_count2,
>>> -	.vs_dispatch	= nfsd_dispatch,
>>> +	.vs_dispatch	= nfsd4_dispatch,
>>> 	.vs_xdrsize	= NFS3_SVC_XDRSIZE,
>>> };
>>> diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
>>> index 7f512dec7460..924ebb19c59c 100644
>>> --- a/fs/nfsd/nfs3acl.c
>>> +++ b/fs/nfsd/nfs3acl.c
>>> @@ -282,7 +282,7 @@ const struct svc_version nfsd_acl_version3 = {
>>> 	.vs_nproc	= 3,
>>> 	.vs_proc	= nfsd_acl_procedures3,
>>> 	.vs_count	= nfsd_acl_count3,
>>> -	.vs_dispatch	= nfsd_dispatch,
>>> +	.vs_dispatch	= nfsd4_dispatch,
>>> 	.vs_xdrsize	= NFS3_SVC_XDRSIZE,
>>> };
>>> 
>>> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
>>> index 49109645af24..61302641f651 100644
>>> --- a/fs/nfsd/nfs4proc.c
>>> +++ b/fs/nfsd/nfs4proc.c
>>> @@ -3320,7 +3320,7 @@ const struct svc_version nfsd_version4 = {
>>> 	.vs_nproc		= 2,
>>> 	.vs_proc		= nfsd_procedures4,
>>> 	.vs_count		= nfsd_count3,
>>> -	.vs_dispatch		= nfsd_dispatch,
>>> +	.vs_dispatch		= nfsd4_dispatch,
>>> 	.vs_xdrsize		= NFS4_SVC_XDRSIZE,
>>> 	.vs_rpcb_optnl		= true,
>>> 	.vs_need_cong_ctrl	= true,
>>> diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
>>> index cb742e17e04a..7fa4b19dd2f7 100644
>>> --- a/fs/nfsd/nfsd.h
>>> +++ b/fs/nfsd/nfsd.h
>>> @@ -78,6 +78,7 @@ extern const struct seq_operations nfs_exports_op;
>>> */
>>> int		nfsd_svc(int nrservs, struct net *net, const struct cred *cred);
>>> int		nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
>>> +int		nfsd4_dispatch(struct svc_rqst *rqstp, __be32 *statp);
>>> 
>>> int		nfsd_nrthreads(struct net *);
>>> int		nfsd_nrpools(struct net *);
>>> diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
>>> index f7f6473578af..d626eea1c78a 100644
>>> --- a/fs/nfsd/nfssvc.c
>>> +++ b/fs/nfsd/nfssvc.c
>>> @@ -28,6 +28,7 @@
>>> #include "vfs.h"
>>> #include "netns.h"
>>> #include "filecache.h"
>>> +#include "trace.h"
>>> 
>>> #define NFSDDBG_FACILITY	NFSDDBG_SVC
>>> 
>>> @@ -964,7 +965,7 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
>>> {
>>> 	if (nfserr == nfserr_jukebox && vers == 2)
>>> 		return nfserr_dropit;
>>> -	if (nfserr == nfserr_wrongsec && vers < 4)
>>> +	if (nfserr == nfserr_wrongsec)
>>> 		return nfserr_acces;
>>> 	return nfserr;
>>> }
>>> @@ -980,18 +981,6 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
>>> static bool nfs_request_too_big(struct svc_rqst *rqstp,
>>> 				const struct svc_procedure *proc)
>>> {
>>> -	/*
>>> -	 * The ACL code has more careful bounds-checking and is not
>>> -	 * susceptible to this problem:
>>> -	 */
>>> -	if (rqstp->rq_prog != NFS_PROGRAM)
>>> -		return false;
>>> -	/*
>>> -	 * Ditto NFSv4 (which can in theory have argument and reply both
>>> -	 * more than a page):
>>> -	 */
>>> -	if (rqstp->rq_vers >= 4)
>>> -		return false;
>>> 	/* The reply will be small, we're OK: */
>>> 	if (proc->pc_xdrressize > 0 &&
>>> 	    proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
>>> @@ -1000,81 +989,152 @@ static bool nfs_request_too_big(struct svc_rqst *rqstp,
>>> 	return rqstp->rq_arg.len > PAGE_SIZE;
>>> }
>>> 
>>> -int
>>> -nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
>>> +/**
>>> + * nfsd_dispatch - Process an NFSv2 or NFSv3 request
>>> + * @rqstp: incoming NFS request
>>> + * @statp: OUT: RPC accept_stat value
>>> + *
>>> + * Return values:
>>> + *  %0: Processing complete; do not send a Reply
>>> + *  %1: Processing complete; send a Reply
>>> + */
>>> +int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
>>> {
>>> -	const struct svc_procedure *proc;
>>> -	__be32			nfserr;
>>> -	__be32			*nfserrp;
>>> -
>>> -	dprintk("nfsd_dispatch: vers %d proc %d\n",
>>> -				rqstp->rq_vers, rqstp->rq_proc);
>>> -	proc = rqstp->rq_procinfo;
>>> -
>>> -	if (nfs_request_too_big(rqstp, proc)) {
>>> -		dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
>>> -		*statp = rpc_garbage_args;
>>> -		return 1;
>>> +	const struct svc_procedure *proc = rqstp->rq_procinfo;
>>> +	struct kvec *argv = &rqstp->rq_arg.head[0];
>>> +	struct kvec *resv = &rqstp->rq_res.head[0];
>>> +	__be32 nfserr, *nfserrp;
>>> +
>>> +	if (nfs_request_too_big(rqstp, proc))
>>> +		goto out_too_large;
>>> +
>>> +	if (proc->pc_decode && !procp->pc_decode(rqstp, argv->iov_base))
>>> +		goto out_decode_err;
>>> +
>>> +	rqstp->rq_cachetype = proc->pc_cachetype;
>>> +	switch (nfsd_cache_lookup(rqstp)) {
>>> +	case RC_DROPIT:
>>> +		goto out_dropit;
>>> +	case RC_REPLY:
>>> +		goto out_cached_reply;
>>> +	case RC_DOIT:
>>> +		break;
>>> 	}
>>> -	rqstp->rq_lease_breaker = NULL;
>>> +
>>> +	nfserrp = resv->iov_base + resv->iov_len;
>>> +	resv->iov_len += sizeof(__be32);
>>> +	nfserr = proc->pc_func(rqstp);
>>> +	nfserr = map_new_errors(rqstp->rq_vers, nfserr);
>>> +	if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags))
>>> +		goto out_update_drop;
>>> +	if (rqstp->rq_proc)
>>> +		*nfserrp++ = nfserr;
>>> +
>>> +	/* For NFSv2, additional info is never returned in case of an error. */
>>> +	if (!(nfserr && rqstp->rq_vers == 2))
>>> +		if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp))
>>> +			goto out_encode_err;
>>> +
>>> +	nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1);
>>> +	trace_nfsd_svc_status(rqstp, proc, nfserr);
>>> +	return 1;
>>> +
>>> +out_too_large:
>>> +	trace_nfsd_svc_too_large_err(rqstp);
>>> +	*statp = rpc_garbage_args;
>>> +	return 1;
>>> +
>>> +out_decode_err:
>>> +	trace_nfsd_svc_decode_err(rqstp);
>>> +	*statp = rpc_garbage_args;
>>> +	return 1;
>>> +
>>> +out_update_drop:
>>> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>>> +out_dropit:
>>> +	trace_nfsd_svc_dropit(rqstp);
>>> +	return 0;
>>> +
>>> +out_cached_reply:
>>> +	trace_nfsd_svc_cached_reply(rqstp);
>>> +	return 1;
>>> +
>>> +out_encode_err:
>>> +	trace_nfsd_svc_encode_err(rqstp);
>>> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>>> +	*statp = rpc_system_err;
>>> +	return 1;
>>> +}
>>> +
>>> +/**
>>> + * nfsd4_dispatch - Process an NFSv4 or NFSACL request
>>> + * @rqstp: incoming NFS request
>>> + * @statp: OUT: RPC accept_stat value
>>> + *
>>> + * Return values:
>>> + *  %0: Processing complete; do not send a Reply
>>> + *  %1: Processing complete; send a Reply
>>> + */
>>> +int nfsd4_dispatch(struct svc_rqst *rqstp, __be32 *statp)
>>> +{
>>> +	const struct svc_procedure *proc = rqstp->rq_procinfo;
>>> +	struct kvec *argv = &rqstp->rq_arg.head[0];
>>> +	struct kvec *resv = &rqstp->rq_res.head[0];
>>> +	__be32 nfserr, *nfserrp;
>>> +
>>> 	/*
>>> 	 * Give the xdr decoder a chance to change this if it wants
>>> 	 * (necessary in the NFSv4.0 compound case)
>>> 	 */
>>> 	rqstp->rq_cachetype = proc->pc_cachetype;
>>> -	/* Decode arguments */
>>> -	if (proc->pc_decode &&
>>> -	    !proc->pc_decode(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base)) {
>>> -		dprintk("nfsd: failed to decode arguments!\n");
>>> -		*statp = rpc_garbage_args;
>>> -		return 1;
>>> -	}
>>> +	rqstp->rq_lease_breaker = NULL;
>>> +
>>> +	if (proc->pc_decode && !procp->pc_decode(rqstp, argv->iov_base))
>>> +		goto out_decode_err;
>>> 
>>> -	/* Check whether we have this call in the cache. */
>>> 	switch (nfsd_cache_lookup(rqstp)) {
>>> 	case RC_DROPIT:
>>> -		return 0;
>>> +		goto out_dropit;
>>> 	case RC_REPLY:
>>> -		return 1;
>>> -	case RC_DOIT:;
>>> -		/* do it */
>>> +		goto out_cached_reply;
>>> +	case RC_DOIT:
>>> +		break;
>>> 	}
>>> 
>>> -	/* need to grab the location to store the status, as
>>> -	 * nfsv4 does some encoding while processing 
>>> -	 */
>>> -	nfserrp = rqstp->rq_res.head[0].iov_base
>>> -		+ rqstp->rq_res.head[0].iov_len;
>>> -	rqstp->rq_res.head[0].iov_len += sizeof(__be32);
>>> -
>>> -	/* Now call the procedure handler, and encode NFS status. */
>>> +	nfserrp = resv->iov_base + resv->iov_len;
>>> +	resv->iov_len += sizeof(__be32);
>>> 	nfserr = proc->pc_func(rqstp);
>>> -	nfserr = map_new_errors(rqstp->rq_vers, nfserr);
>>> -	if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags)) {
>>> -		dprintk("nfsd: Dropping request; may be revisited later\n");
>>> -		nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>>> -		return 0;
>>> -	}
>>> -
>>> -	if (rqstp->rq_proc != 0)
>>> +	if (test_bit(RQ_DROPME, &rqstp->rq_flags))
>>> +		goto out_update_drop;
>>> +	if (rqstp->rq_proc)
>>> 		*nfserrp++ = nfserr;
>>> 
>>> -	/* Encode result.
>>> -	 * For NFSv2, additional info is never returned in case of an error.
>>> -	 */
>>> -	if (!(nfserr && rqstp->rq_vers == 2)) {
>>> -		if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp)) {
>>> -			/* Failed to encode result. Release cache entry */
>>> -			dprintk("nfsd: failed to encode result!\n");
>>> -			nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>>> -			*statp = rpc_system_err;
>>> -			return 1;
>>> -		}
>>> -	}
>>> +	if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp))
>>> +		goto out_encode_err;
>>> 
>>> -	/* Store reply in cache. */
>>> 	nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1);
>>> 	return 1;
>>> +
>>> +out_decode_err:
>>> +	trace_nfsd_svc_decode_err(rqstp);
>>> +	*statp = rpc_garbage_args;
>>> +	return 1;
>>> +
>>> +out_update_drop:
>>> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>>> +out_dropit:
>>> +	trace_nfsd_svc_dropit(rqstp);
>>> +	return 0;
>>> +
>>> +out_cached_reply:
>>> +	trace_nfsd_svc_cached_reply(rqstp);
>>> +	return 1;
>>> +
>>> +out_encode_err:
>>> +	trace_nfsd_svc_encode_err(rqstp);
>>> +	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
>>> +	*statp = rpc_system_err;
>>> +	return 1;
>>> }
>>> 
>>> int nfsd_pool_stats_open(struct inode *inode, struct file *file)
>>> diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
>>> index 53115fbc00b2..50ab4a84c25f 100644
>>> --- a/fs/nfsd/trace.h
>>> +++ b/fs/nfsd/trace.h
>>> @@ -32,6 +32,56 @@
>>> 		{ NFSD_MAY_READ_IF_EXEC,	"READ_IF_EXEC" },	\
>>> 		{ NFSD_MAY_64BIT_COOKIE,	"64BIT_COOKIE" })
>>> 
>>> +DECLARE_EVENT_CLASS(nfsd_simple_class,
>>> +	TP_PROTO(
>>> +		const struct svc_rqst *rqstp
>>> +	),
>>> +	TP_ARGS(rqstp),
>>> +	TP_STRUCT__entry(
>>> +		__field(u32, xid)
>>> +	),
>>> +	TP_fast_assign(
>>> +		__entry->xid = be32_to_cpu(rqstp->rq_xid);
>>> +	),
>>> +	TP_printk("xid=0x%08x", __entry->xid)
>>> +);
>>> +
>>> +#define DEFINE_NFSD_SIMPLE_EVENT(name)			\
>>> +DEFINE_EVENT(nfsd_simple_class, nfsd_##name,		\
>>> +	TP_PROTO(const struct svc_rqst *rqstp),		\
>>> +	TP_ARGS(rqstp))
>>> +
>>> +DEFINE_NFSD_SIMPLE_EVENT(svc_too_large_err);
>>> +DEFINE_NFSD_SIMPLE_EVENT(svc_decode_err);
>>> +DEFINE_NFSD_SIMPLE_EVENT(svc_dropit);
>>> +DEFINE_NFSD_SIMPLE_EVENT(svc_cached_reply);
>>> +DEFINE_NFSD_SIMPLE_EVENT(svc_encode_err);
>>> +
>>> +TRACE_EVENT(nfsd_svc_status,
>>> +	TP_PROTO(
>>> +		const struct svc_rqst *rqstp,
>>> +		const struct svc_procedure *proc,
>>> +		__be32 status
>>> +	),
>>> +	TP_ARGS(rqstp, proc, status),
>>> +	TP_STRUCT__entry(
>>> +		__field(u32, xid)
>>> +		__field(u32, version)
>>> +		__field(unsigned long, status)
>>> +		__string(procedure, rqstp->rq_procinfo->pc_name)
>>> +	),
>>> +	TP_fast_assign(
>>> +		__entry->xid = be32_to_cpu(rqstp->rq_xid);
>>> +		__entry->version = rqstp->rq_vers;
>>> +		__entry->status = be32_to_cpu(status);
>>> +		__assign_str(procedure, rqstp->rq_procinfo->pc_name);
>>> +	),
>>> +	TP_printk("xid=0x%08x version=%u procedure=%s status=%s",
>>> +		__entry->xid, __entry->version, __get_str(procedure),
>>> +		show_nfs_status(__entry->status)
>>> +	)
>>> +);
>>> +
>>> TRACE_EVENT(nfsd_access,
>>> 	TP_PROTO(
>>> 		const struct svc_rqst *rqstp,
>>> 
> 
> --
> Chuck Lever

--
Chuck Lever




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

* Re: [PATCH v2 26/27] NFSD: Add tracepoints in the NFS dispatcher
  2020-09-25 14:17       ` Bruce Fields
@ 2020-09-25 14:21         ` Chuck Lever
  0 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-25 14:21 UTC (permalink / raw)
  To: Bruce Fields; +Cc: Bill Baker, Linux NFS Mailing List



> On Sep 25, 2020, at 10:17 AM, Bruce Fields <bfields@fieldses.org> wrote:
> 
> On Fri, Sep 25, 2020 at 09:59:54AM -0400, Chuck Lever wrote:
>> 
>> 
>>> On Sep 24, 2020, at 7:45 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
>>> 
>>> On Mon, Sep 21, 2020 at 02:13:07PM -0400, Chuck Lever wrote:
>>>> This is follow-on work to the tracepoints added in the NFS server's
>>>> duplicate reply cache. Here, tracepoints are introduced that report
>>>> replies from cache as well as encoding and decoding errors.
>>>> 
>>>> The NFSv2, v3, and v4 dispatcher requirements have diverged over
>>>> time, leaving us with a little bit of technical debt. In addition,
>>>> I wanted to add a tracepoint for NFSv2 and NFSv3 similar to the
>>>> nfsd4_compound/compoundstatus tracepoints. Lastly, removing some
>>>> conditional branches from this hot path helps optimize CPU
>>>> utilization. So, I've duplicated the nfsd_dispatcher function.
>>> 
>>> Comparing current nfsd_dispatch to the nfsv2/v3 nfsd_dispatch: the only
>>> thing I spotted removed from the v2/v3-specific dispatch is the
>>> rq_lease_breaker = NULL.  (I think that's not correct, actually.  We
>>> could remove the need for that to be set in the v2/v3 case, but with the
>>> current code it does need to be set.)
>> 
>> Noted with thanks.
> 
> Maybe just do this?

I'll try it out. Thanks!


> --b.
> 
> commit c7265a111269
> Author: J. Bruce Fields <bfields@redhat.com>
> Date:   Fri Sep 25 10:12:39 2020 -0400
> 
>    nfsd: rq_lease_breaker cleanup
> 
>    Since only the v4 code cares about it, maybe it's better to leave
>    rq_lease_breaker out of the common dispatch code?
> 
>    Signed-off-by: J. Bruce Fields <bfields@redhat.com>
> 
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index 62afcae18e17..a498278ba96b 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -4597,6 +4597,9 @@ static bool nfsd_breaker_owns_lease(struct file_lock *fl)
> 
> 	if (!i_am_nfsd())
> 		return NULL;
> +	/* Note rq_prog == NFS_ACL_PROGRAM is also possible: */
> +	if (rqst->rq_prog != NFS_PROGRAM || rqst->rq_vers < 4)
> +		return NULL;
> 	rqst = kthread_data(current);
> 	clp = *(rqst->rq_lease_breaker);
> 	return dl->dl_stid.sc_client == clp;
> diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
> index b603dfcdd361..8d6f6f4c8b28 100644
> --- a/fs/nfsd/nfssvc.c
> +++ b/fs/nfsd/nfssvc.c
> @@ -1016,7 +1016,6 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
> 		*statp = rpc_garbage_args;
> 		return 1;
> 	}
> -	rqstp->rq_lease_breaker = NULL;
> 	/*
> 	 * Give the xdr decoder a chance to change this if it wants
> 	 * (necessary in the NFSv4.0 compound case)

--
Chuck Lever




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

* Re: [PATCH v2 00/27] NFSD operation monitoring tracepoints
  2020-09-25 13:59   ` Chuck Lever
@ 2020-09-25 14:32     ` Bruce Fields
  2020-09-25 14:36       ` Chuck Lever
  0 siblings, 1 reply; 43+ messages in thread
From: Bruce Fields @ 2020-09-25 14:32 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Bill Baker, Linux NFS Mailing List

On Fri, Sep 25, 2020 at 09:59:51AM -0400, Chuck Lever wrote:
> Thanks Bruce, for your time, attention, and comments!
> 
> > On Sep 24, 2020, at 5:36 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
> > 
> > On Mon, Sep 21, 2020 at 02:10:49PM -0400, Chuck Lever wrote:
> >> As I've been working on various server bugs, I've been adding
> >> tracepoints that record NFS operation arguments. Here's an updated
> >> snapshot of this work for your review and comment.
> >> 
> >> The idea here is to provide a degree of NFS traffic observability
> >> without needing network capture. Tracepoints are generally lighter-
> >> weight than full network capture, allowing effective capture-time
> >> data reduction:
> > 
> > I do wonder when tracepoints seem to duplicate information you could get
> > from network traces, so thanks for taking the time to explain this.  It
> > makes sense to me.
> > 
> > The patches look fine.  The only one I'm I'm on the fence about is the
> > last with the split up of the dispatch functions.  I'll ask some
> > questions there....
> 
> To be clear to everyone, this series is still "preview". I expect
> more churn in these patches, thus I don't consider the series ready
> to be merged by any stretch.

OK!

One thing I was wondering about: how would you limit tracing to a single
client, say if you wanted to see all DELEGRETURNs from a single client?
I guess you'd probably turn on a tracepoint in the receive code, look
for your client's IP address, then mask the task id to match later
nfs-level tracepoints.  Is there enough information in those tracepoints
(including network namespace) to uniquely identify a client?

--b.

> >> - One or a handful of these can be enabled at a time
> >> - Each tracepoint records much less data per operation than capture
> >> - Extra capture-time filtering can reduce data amount even further
> >> - Some of these operations are infrequent enough that their
> >> tracepoint could be enabled persistently without a significant
> >> performance impact (for example, for security auditing)
> >> 
> >> The topic branch has been updated as well:
> >> 
> >> git://git.linux-nfs.org/projects/cel/cel-2.6.git nfsd-more-tracepoints
> >> 
> >> 
> >> Changes since RFC:
> >> * s/SPDK/SPDX and corrected the spelling of Christoph's surname
> >> * Fixed a build error noticed by <lkp@intel.com>
> >> * Introduced generic headers for VFS and NFS protocol display macros
> >> * nfsd4_compoundstatus now displays NFS4ERR codes symbolically
> >> * The svc_process tracepoint now displays the RPC procedure symbolically
> >> * NFSD dispatcher now displays procedure names and status codes symbolically
> >> * fh_verify tracepoint tentatively included; it adds a lot of noise, but perhaps not much value
> >> * Cleaned up the remaining PROC() macros in the server code
> >> * Removed trace_printk's that were introduced during the RFC series
> >> * Removed redundant nfsd4_close tracepoint
> >> 
> >> ---
> >> 
> >> Chuck Lever (27):
> >>      NFS: Move generic FS show macros to global header
> >>      NFS: Move NFS protocol display macros to global header
> >>      NFSD: Add SPDX header for fs/nfsd/trace.c
> >>      SUNRPC: Move the svc_xdr_recvfrom() tracepoint
> >>      SUNRPC: Add svc_xdr_authenticate tracepoint
> >>      lockd: Replace PROC() macro with open code
> >>      NFSACL: Replace PROC() macro with open code
> >>      SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
> >>      NFSD: Clean up the show_nf_may macro
> >>      NFSD: Remove extra "0x" in tracepoint format specifier
> >>      NFSD: Constify @fh argument of knfsd_fh_hash()
> >>      NFSD: Add tracepoint in nfsd_setattr()
> >>      NFSD: Add tracepoint for nfsd_access()
> >>      NFSD: nfsd_compound_status tracepoint should record XID
> >>      NFSD: Add client ID lifetime tracepoints
> >>      NFSD: Add tracepoints to report NFSv4 session state
> >>      NFSD: Add a tracepoint to report the current filehandle
> >>      NFSD: Add GETATTR tracepoint
> >>      NFSD: Add tracepoint in nfsd4_stateid_preprocess()
> >>      NFSD: Add tracepoint to report arguments to NFSv4 OPEN
> >>      NFSD: Add a tracepoint for DELEGRETURN
> >>      NFSD: Add a lookup tracepoint
> >>      NFSD: Add lock and locku tracepoints
> >>      NFSD: Add tracepoints to record the result of TEST_STATEID and FREE_STATEID
> >>      NFSD: Rename nfsd_ tracepoints to nfsd4_
> >>      NFSD: Add tracepoints in the NFS dispatcher
> >>      NFSD: Replace dprintk callsites in fs/nfsd/nfsfh.c
> >> 
> >> 
> >> fs/lockd/svc4proc.c           | 263 +++++++++--
> >> fs/lockd/svcproc.c            | 265 +++++++++--
> >> fs/nfs/callback_xdr.c         |   2 +
> >> fs/nfs/nfs4trace.h            | 387 ++--------------
> >> fs/nfs/nfstrace.h             | 113 +----
> >> fs/nfs/pnfs.h                 |   4 -
> >> fs/nfsd/nfs2acl.c             |  79 +++-
> >> fs/nfsd/nfs3acl.c             |  54 ++-
> >> fs/nfsd/nfs3proc.c            |  25 +
> >> fs/nfsd/nfs4callback.c        |  28 +-
> >> fs/nfsd/nfs4layouts.c         |  16 +-
> >> fs/nfsd/nfs4proc.c            |  43 +-
> >> fs/nfsd/nfs4state.c           | 100 ++--
> >> fs/nfsd/nfsd.h                |   1 +
> >> fs/nfsd/nfsfh.c               |  36 +-
> >> fs/nfsd/nfsfh.h               |   7 +-
> >> fs/nfsd/nfsproc.c             |  21 +
> >> fs/nfsd/nfssvc.c              | 198 +++++---
> >> fs/nfsd/trace.c               |   1 +
> >> fs/nfsd/trace.h               | 844 ++++++++++++++++++++++++++++++----
> >> fs/nfsd/vfs.c                 |  18 +-
> >> fs/nfsd/xdr4.h                |   3 +-
> >> include/linux/nfs4.h          |   4 +
> >> include/linux/sunrpc/svc.h    |   1 +
> >> include/trace/events/fs.h     |  30 ++
> >> include/trace/events/nfs.h    | 511 ++++++++++++++++++++
> >> include/trace/events/sunrpc.h |  33 +-
> >> include/uapi/linux/nfsacl.h   |   2 +
> >> net/sunrpc/svc_xprt.c         |   4 +-
> >> net/sunrpc/svcauth.c          |   5 +-
> >> 30 files changed, 2187 insertions(+), 911 deletions(-)
> >> create mode 100644 include/trace/events/nfs.h
> >> 
> >> --
> >> Chuck Lever
> 
> --
> Chuck Lever
> 
> 

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

* Re: [PATCH v2 00/27] NFSD operation monitoring tracepoints
  2020-09-25 14:32     ` Bruce Fields
@ 2020-09-25 14:36       ` Chuck Lever
  2020-09-25 15:00         ` Bruce Fields
  0 siblings, 1 reply; 43+ messages in thread
From: Chuck Lever @ 2020-09-25 14:36 UTC (permalink / raw)
  To: Bruce Fields; +Cc: Bill Baker, Linux NFS Mailing List



> On Sep 25, 2020, at 10:32 AM, Bruce Fields <bfields@fieldses.org> wrote:
> 
> On Fri, Sep 25, 2020 at 09:59:51AM -0400, Chuck Lever wrote:
>> Thanks Bruce, for your time, attention, and comments!
>> 
>>> On Sep 24, 2020, at 5:36 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
>>> 
>>> On Mon, Sep 21, 2020 at 02:10:49PM -0400, Chuck Lever wrote:
>>>> As I've been working on various server bugs, I've been adding
>>>> tracepoints that record NFS operation arguments. Here's an updated
>>>> snapshot of this work for your review and comment.
>>>> 
>>>> The idea here is to provide a degree of NFS traffic observability
>>>> without needing network capture. Tracepoints are generally lighter-
>>>> weight than full network capture, allowing effective capture-time
>>>> data reduction:
>>> 
>>> I do wonder when tracepoints seem to duplicate information you could get
>>> from network traces, so thanks for taking the time to explain this.  It
>>> makes sense to me.
>>> 
>>> The patches look fine.  The only one I'm I'm on the fence about is the
>>> last with the split up of the dispatch functions.  I'll ask some
>>> questions there....
>> 
>> To be clear to everyone, this series is still "preview". I expect
>> more churn in these patches, thus I don't consider the series ready
>> to be merged by any stretch.
> 
> OK!
> 
> One thing I was wondering about: how would you limit tracing to a single
> client, say if you wanted to see all DELEGRETURNs from a single client?
> I guess you'd probably turn on a tracepoint in the receive code, look
> for your client's IP address, then mask the task id to match later
> nfs-level tracepoints.  Is there enough information in those tracepoints
> (including network namespace) to uniquely identify a client?

Client IP address information is in the RPC layer trace data. The
DELEGRETURN trace record includes client ID. So maybe not as
straightforward as it could be.


> --b.
> 
>>>> - One or a handful of these can be enabled at a time
>>>> - Each tracepoint records much less data per operation than capture
>>>> - Extra capture-time filtering can reduce data amount even further
>>>> - Some of these operations are infrequent enough that their
>>>> tracepoint could be enabled persistently without a significant
>>>> performance impact (for example, for security auditing)
>>>> 
>>>> The topic branch has been updated as well:
>>>> 
>>>> git://git.linux-nfs.org/projects/cel/cel-2.6.git nfsd-more-tracepoints
>>>> 
>>>> 
>>>> Changes since RFC:
>>>> * s/SPDK/SPDX and corrected the spelling of Christoph's surname
>>>> * Fixed a build error noticed by <lkp@intel.com>
>>>> * Introduced generic headers for VFS and NFS protocol display macros
>>>> * nfsd4_compoundstatus now displays NFS4ERR codes symbolically
>>>> * The svc_process tracepoint now displays the RPC procedure symbolically
>>>> * NFSD dispatcher now displays procedure names and status codes symbolically
>>>> * fh_verify tracepoint tentatively included; it adds a lot of noise, but perhaps not much value
>>>> * Cleaned up the remaining PROC() macros in the server code
>>>> * Removed trace_printk's that were introduced during the RFC series
>>>> * Removed redundant nfsd4_close tracepoint
>>>> 
>>>> ---
>>>> 
>>>> Chuck Lever (27):
>>>>     NFS: Move generic FS show macros to global header
>>>>     NFS: Move NFS protocol display macros to global header
>>>>     NFSD: Add SPDX header for fs/nfsd/trace.c
>>>>     SUNRPC: Move the svc_xdr_recvfrom() tracepoint
>>>>     SUNRPC: Add svc_xdr_authenticate tracepoint
>>>>     lockd: Replace PROC() macro with open code
>>>>     NFSACL: Replace PROC() macro with open code
>>>>     SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
>>>>     NFSD: Clean up the show_nf_may macro
>>>>     NFSD: Remove extra "0x" in tracepoint format specifier
>>>>     NFSD: Constify @fh argument of knfsd_fh_hash()
>>>>     NFSD: Add tracepoint in nfsd_setattr()
>>>>     NFSD: Add tracepoint for nfsd_access()
>>>>     NFSD: nfsd_compound_status tracepoint should record XID
>>>>     NFSD: Add client ID lifetime tracepoints
>>>>     NFSD: Add tracepoints to report NFSv4 session state
>>>>     NFSD: Add a tracepoint to report the current filehandle
>>>>     NFSD: Add GETATTR tracepoint
>>>>     NFSD: Add tracepoint in nfsd4_stateid_preprocess()
>>>>     NFSD: Add tracepoint to report arguments to NFSv4 OPEN
>>>>     NFSD: Add a tracepoint for DELEGRETURN
>>>>     NFSD: Add a lookup tracepoint
>>>>     NFSD: Add lock and locku tracepoints
>>>>     NFSD: Add tracepoints to record the result of TEST_STATEID and FREE_STATEID
>>>>     NFSD: Rename nfsd_ tracepoints to nfsd4_
>>>>     NFSD: Add tracepoints in the NFS dispatcher
>>>>     NFSD: Replace dprintk callsites in fs/nfsd/nfsfh.c
>>>> 
>>>> 
>>>> fs/lockd/svc4proc.c           | 263 +++++++++--
>>>> fs/lockd/svcproc.c            | 265 +++++++++--
>>>> fs/nfs/callback_xdr.c         |   2 +
>>>> fs/nfs/nfs4trace.h            | 387 ++--------------
>>>> fs/nfs/nfstrace.h             | 113 +----
>>>> fs/nfs/pnfs.h                 |   4 -
>>>> fs/nfsd/nfs2acl.c             |  79 +++-
>>>> fs/nfsd/nfs3acl.c             |  54 ++-
>>>> fs/nfsd/nfs3proc.c            |  25 +
>>>> fs/nfsd/nfs4callback.c        |  28 +-
>>>> fs/nfsd/nfs4layouts.c         |  16 +-
>>>> fs/nfsd/nfs4proc.c            |  43 +-
>>>> fs/nfsd/nfs4state.c           | 100 ++--
>>>> fs/nfsd/nfsd.h                |   1 +
>>>> fs/nfsd/nfsfh.c               |  36 +-
>>>> fs/nfsd/nfsfh.h               |   7 +-
>>>> fs/nfsd/nfsproc.c             |  21 +
>>>> fs/nfsd/nfssvc.c              | 198 +++++---
>>>> fs/nfsd/trace.c               |   1 +
>>>> fs/nfsd/trace.h               | 844 ++++++++++++++++++++++++++++++----
>>>> fs/nfsd/vfs.c                 |  18 +-
>>>> fs/nfsd/xdr4.h                |   3 +-
>>>> include/linux/nfs4.h          |   4 +
>>>> include/linux/sunrpc/svc.h    |   1 +
>>>> include/trace/events/fs.h     |  30 ++
>>>> include/trace/events/nfs.h    | 511 ++++++++++++++++++++
>>>> include/trace/events/sunrpc.h |  33 +-
>>>> include/uapi/linux/nfsacl.h   |   2 +
>>>> net/sunrpc/svc_xprt.c         |   4 +-
>>>> net/sunrpc/svcauth.c          |   5 +-
>>>> 30 files changed, 2187 insertions(+), 911 deletions(-)
>>>> create mode 100644 include/trace/events/nfs.h
>>>> 
>>>> --
>>>> Chuck Lever
>> 
>> --
>> Chuck Lever

--
Chuck Lever




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

* Re: [PATCH v2 26/27] NFSD: Add tracepoints in the NFS dispatcher
  2020-09-25 13:59     ` Chuck Lever
  2020-09-25 14:17       ` Bruce Fields
  2020-09-25 14:18       ` Chuck Lever
@ 2020-09-25 14:47       ` Bruce Fields
  2 siblings, 0 replies; 43+ messages in thread
From: Bruce Fields @ 2020-09-25 14:47 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Bill Baker, Linux NFS Mailing List

On Fri, Sep 25, 2020 at 09:59:54AM -0400, Chuck Lever wrote:
> 
> 
> > On Sep 24, 2020, at 7:45 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
> > 
> > On Mon, Sep 21, 2020 at 02:13:07PM -0400, Chuck Lever wrote:
> >> This is follow-on work to the tracepoints added in the NFS server's
> >> duplicate reply cache. Here, tracepoints are introduced that report
> >> replies from cache as well as encoding and decoding errors.
> >> 
> >> The NFSv2, v3, and v4 dispatcher requirements have diverged over
> >> time, leaving us with a little bit of technical debt. In addition,
> >> I wanted to add a tracepoint for NFSv2 and NFSv3 similar to the
> >> nfsd4_compound/compoundstatus tracepoints. Lastly, removing some
> >> conditional branches from this hot path helps optimize CPU
> >> utilization. So, I've duplicated the nfsd_dispatcher function.
> > 
> > Comparing current nfsd_dispatch to the nfsv2/v3 nfsd_dispatch: the only
> > thing I spotted removed from the v2/v3-specific dispatch is the
> > rq_lease_breaker = NULL.  (I think that's not correct, actually.  We
> > could remove the need for that to be set in the v2/v3 case, but with the
> > current code it does need to be set.)
> 
> Noted with thanks.
> 
> 
> > Comparing current nfsd_dispatch to the nfsv4 nfsd4_dispatch, the
> > v4-specific dispatch does away with nfs_request_too_big() and the
> > v2-specific shortcut in the error encoding case.
> > 
> > So these still look *very* similar.  I don't feel like we're getting a
> > lot of benefit out of splitting these out.
> 
> I don't disagree with that at all. At this point I'm just noodling
> to see what's possible. I'm now toying with other ways to add high-
> value tracing in the legacy ULPs. In the end I might end up avoiding
> significant changes in the dispatchers in order to add tracing.

OK.

> However, a few thoughts I had while learning how the dispatcher
> code works.
> 
> There are some opportunities for reducing instruction path length
> and the number of conditional branches in here. It's a hot path,
> so I think we should consider some careful micro-optimizations
> even if they don't add significant new features or do add some
> code duplication.
> 
> In user space, the library (iirc) assumes each ULP provides it's
> own dispatcher function. I'd consider duplicating and removing
> svc_generic_dispatcher() to simplify the pasta in svc_process(),
> again as a micro-optimization and for better code legibility.

Not sure you even have to duplicate it, just export the generic
dispatcher and let individual programs point to it, right?

> lockd's pc_func returns an RPC accept_stat, but the NFSD pc_func
> methods return an NFS status. The latter feels like a layering
> violation for the sake of reducing a small amount of code
> duplication. I'd rather see encoding of the NFS status handled in
> the NFS Reply encoders, since that is an XDR function, and because
> that logic seems slightly different for NFSv2, support for which
> we'd like to deprecate at some point.
>
> Note also that *statp in nfsd_dispatch is never explicitly set to
> rpc_success in the normal execution flow. It relies on the
> equivalence of rpc_success and nfs_ok, which is convenient, but
> confusing to read. It might be cleaner if *statp was made an enum
> to make it explicit what set of values go in that return variable.

OK.

--b.

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

* Re: [PATCH v2 00/27] NFSD operation monitoring tracepoints
  2020-09-25 14:36       ` Chuck Lever
@ 2020-09-25 15:00         ` Bruce Fields
  2020-09-25 15:05           ` Chuck Lever
  0 siblings, 1 reply; 43+ messages in thread
From: Bruce Fields @ 2020-09-25 15:00 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Bill Baker, Linux NFS Mailing List

On Fri, Sep 25, 2020 at 10:36:42AM -0400, Chuck Lever wrote:
> 
> 
> > On Sep 25, 2020, at 10:32 AM, Bruce Fields <bfields@fieldses.org> wrote:
> > 
> > On Fri, Sep 25, 2020 at 09:59:51AM -0400, Chuck Lever wrote:
> >> Thanks Bruce, for your time, attention, and comments!
> >> 
> >>> On Sep 24, 2020, at 5:36 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
> >>> 
> >>> On Mon, Sep 21, 2020 at 02:10:49PM -0400, Chuck Lever wrote:
> >>>> As I've been working on various server bugs, I've been adding
> >>>> tracepoints that record NFS operation arguments. Here's an updated
> >>>> snapshot of this work for your review and comment.
> >>>> 
> >>>> The idea here is to provide a degree of NFS traffic observability
> >>>> without needing network capture. Tracepoints are generally lighter-
> >>>> weight than full network capture, allowing effective capture-time
> >>>> data reduction:
> >>> 
> >>> I do wonder when tracepoints seem to duplicate information you could get
> >>> from network traces, so thanks for taking the time to explain this.  It
> >>> makes sense to me.
> >>> 
> >>> The patches look fine.  The only one I'm I'm on the fence about is the
> >>> last with the split up of the dispatch functions.  I'll ask some
> >>> questions there....
> >> 
> >> To be clear to everyone, this series is still "preview". I expect
> >> more churn in these patches, thus I don't consider the series ready
> >> to be merged by any stretch.
> > 
> > OK!
> > 
> > One thing I was wondering about: how would you limit tracing to a single
> > client, say if you wanted to see all DELEGRETURNs from a single client?
> > I guess you'd probably turn on a tracepoint in the receive code, look
> > for your client's IP address, then mask the task id to match later
> > nfs-level tracepoints.  Is there enough information in those tracepoints
> > (including network namespace) to uniquely identify a client?
> 
> Client IP address information is in the RPC layer trace data. The
> DELEGRETURN trace record includes client ID. So maybe not as
> straightforward as it could be.

I guess what I meant was "limit tracing to a single network endpoint",
not exactly limt to a single NFSv4 client....  So, we can do that as
long as all the relevant information is in rpc-layer tracepoints, and as
long as task id is a reliable way to match up trace points.

Is the network namespace in there anywhere?  It looks like there'd be no
way to distinguish clients in different namespaces if they had the same
address.

--b.

> 
> 
> > --b.
> > 
> >>>> - One or a handful of these can be enabled at a time
> >>>> - Each tracepoint records much less data per operation than capture
> >>>> - Extra capture-time filtering can reduce data amount even further
> >>>> - Some of these operations are infrequent enough that their
> >>>> tracepoint could be enabled persistently without a significant
> >>>> performance impact (for example, for security auditing)
> >>>> 
> >>>> The topic branch has been updated as well:
> >>>> 
> >>>> git://git.linux-nfs.org/projects/cel/cel-2.6.git nfsd-more-tracepoints
> >>>> 
> >>>> 
> >>>> Changes since RFC:
> >>>> * s/SPDK/SPDX and corrected the spelling of Christoph's surname
> >>>> * Fixed a build error noticed by <lkp@intel.com>
> >>>> * Introduced generic headers for VFS and NFS protocol display macros
> >>>> * nfsd4_compoundstatus now displays NFS4ERR codes symbolically
> >>>> * The svc_process tracepoint now displays the RPC procedure symbolically
> >>>> * NFSD dispatcher now displays procedure names and status codes symbolically
> >>>> * fh_verify tracepoint tentatively included; it adds a lot of noise, but perhaps not much value
> >>>> * Cleaned up the remaining PROC() macros in the server code
> >>>> * Removed trace_printk's that were introduced during the RFC series
> >>>> * Removed redundant nfsd4_close tracepoint
> >>>> 
> >>>> ---
> >>>> 
> >>>> Chuck Lever (27):
> >>>>     NFS: Move generic FS show macros to global header
> >>>>     NFS: Move NFS protocol display macros to global header
> >>>>     NFSD: Add SPDX header for fs/nfsd/trace.c
> >>>>     SUNRPC: Move the svc_xdr_recvfrom() tracepoint
> >>>>     SUNRPC: Add svc_xdr_authenticate tracepoint
> >>>>     lockd: Replace PROC() macro with open code
> >>>>     NFSACL: Replace PROC() macro with open code
> >>>>     SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
> >>>>     NFSD: Clean up the show_nf_may macro
> >>>>     NFSD: Remove extra "0x" in tracepoint format specifier
> >>>>     NFSD: Constify @fh argument of knfsd_fh_hash()
> >>>>     NFSD: Add tracepoint in nfsd_setattr()
> >>>>     NFSD: Add tracepoint for nfsd_access()
> >>>>     NFSD: nfsd_compound_status tracepoint should record XID
> >>>>     NFSD: Add client ID lifetime tracepoints
> >>>>     NFSD: Add tracepoints to report NFSv4 session state
> >>>>     NFSD: Add a tracepoint to report the current filehandle
> >>>>     NFSD: Add GETATTR tracepoint
> >>>>     NFSD: Add tracepoint in nfsd4_stateid_preprocess()
> >>>>     NFSD: Add tracepoint to report arguments to NFSv4 OPEN
> >>>>     NFSD: Add a tracepoint for DELEGRETURN
> >>>>     NFSD: Add a lookup tracepoint
> >>>>     NFSD: Add lock and locku tracepoints
> >>>>     NFSD: Add tracepoints to record the result of TEST_STATEID and FREE_STATEID
> >>>>     NFSD: Rename nfsd_ tracepoints to nfsd4_
> >>>>     NFSD: Add tracepoints in the NFS dispatcher
> >>>>     NFSD: Replace dprintk callsites in fs/nfsd/nfsfh.c
> >>>> 
> >>>> 
> >>>> fs/lockd/svc4proc.c           | 263 +++++++++--
> >>>> fs/lockd/svcproc.c            | 265 +++++++++--
> >>>> fs/nfs/callback_xdr.c         |   2 +
> >>>> fs/nfs/nfs4trace.h            | 387 ++--------------
> >>>> fs/nfs/nfstrace.h             | 113 +----
> >>>> fs/nfs/pnfs.h                 |   4 -
> >>>> fs/nfsd/nfs2acl.c             |  79 +++-
> >>>> fs/nfsd/nfs3acl.c             |  54 ++-
> >>>> fs/nfsd/nfs3proc.c            |  25 +
> >>>> fs/nfsd/nfs4callback.c        |  28 +-
> >>>> fs/nfsd/nfs4layouts.c         |  16 +-
> >>>> fs/nfsd/nfs4proc.c            |  43 +-
> >>>> fs/nfsd/nfs4state.c           | 100 ++--
> >>>> fs/nfsd/nfsd.h                |   1 +
> >>>> fs/nfsd/nfsfh.c               |  36 +-
> >>>> fs/nfsd/nfsfh.h               |   7 +-
> >>>> fs/nfsd/nfsproc.c             |  21 +
> >>>> fs/nfsd/nfssvc.c              | 198 +++++---
> >>>> fs/nfsd/trace.c               |   1 +
> >>>> fs/nfsd/trace.h               | 844 ++++++++++++++++++++++++++++++----
> >>>> fs/nfsd/vfs.c                 |  18 +-
> >>>> fs/nfsd/xdr4.h                |   3 +-
> >>>> include/linux/nfs4.h          |   4 +
> >>>> include/linux/sunrpc/svc.h    |   1 +
> >>>> include/trace/events/fs.h     |  30 ++
> >>>> include/trace/events/nfs.h    | 511 ++++++++++++++++++++
> >>>> include/trace/events/sunrpc.h |  33 +-
> >>>> include/uapi/linux/nfsacl.h   |   2 +
> >>>> net/sunrpc/svc_xprt.c         |   4 +-
> >>>> net/sunrpc/svcauth.c          |   5 +-
> >>>> 30 files changed, 2187 insertions(+), 911 deletions(-)
> >>>> create mode 100644 include/trace/events/nfs.h
> >>>> 
> >>>> --
> >>>> Chuck Lever
> >> 
> >> --
> >> Chuck Lever
> 
> --
> Chuck Lever
> 
> 

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

* Re: [PATCH v2 00/27] NFSD operation monitoring tracepoints
  2020-09-25 15:00         ` Bruce Fields
@ 2020-09-25 15:05           ` Chuck Lever
  2020-09-25 17:04             ` Chuck Lever
  0 siblings, 1 reply; 43+ messages in thread
From: Chuck Lever @ 2020-09-25 15:05 UTC (permalink / raw)
  To: Bruce Fields; +Cc: Bill Baker, Linux NFS Mailing List



> On Sep 25, 2020, at 11:00 AM, Bruce Fields <bfields@fieldses.org> wrote:
> 
> On Fri, Sep 25, 2020 at 10:36:42AM -0400, Chuck Lever wrote:
>> 
>> 
>>> On Sep 25, 2020, at 10:32 AM, Bruce Fields <bfields@fieldses.org> wrote:
>>> 
>>> On Fri, Sep 25, 2020 at 09:59:51AM -0400, Chuck Lever wrote:
>>>> Thanks Bruce, for your time, attention, and comments!
>>>> 
>>>>> On Sep 24, 2020, at 5:36 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
>>>>> 
>>>>> On Mon, Sep 21, 2020 at 02:10:49PM -0400, Chuck Lever wrote:
>>>>>> As I've been working on various server bugs, I've been adding
>>>>>> tracepoints that record NFS operation arguments. Here's an updated
>>>>>> snapshot of this work for your review and comment.
>>>>>> 
>>>>>> The idea here is to provide a degree of NFS traffic observability
>>>>>> without needing network capture. Tracepoints are generally lighter-
>>>>>> weight than full network capture, allowing effective capture-time
>>>>>> data reduction:
>>>>> 
>>>>> I do wonder when tracepoints seem to duplicate information you could get
>>>>> from network traces, so thanks for taking the time to explain this.  It
>>>>> makes sense to me.
>>>>> 
>>>>> The patches look fine.  The only one I'm I'm on the fence about is the
>>>>> last with the split up of the dispatch functions.  I'll ask some
>>>>> questions there....
>>>> 
>>>> To be clear to everyone, this series is still "preview". I expect
>>>> more churn in these patches, thus I don't consider the series ready
>>>> to be merged by any stretch.
>>> 
>>> OK!
>>> 
>>> One thing I was wondering about: how would you limit tracing to a single
>>> client, say if you wanted to see all DELEGRETURNs from a single client?
>>> I guess you'd probably turn on a tracepoint in the receive code, look
>>> for your client's IP address, then mask the task id to match later
>>> nfs-level tracepoints.  Is there enough information in those tracepoints
>>> (including network namespace) to uniquely identify a client?
>> 
>> Client IP address information is in the RPC layer trace data. The
>> DELEGRETURN trace record includes client ID. So maybe not as
>> straightforward as it could be.
> 
> I guess what I meant was "limit tracing to a single network endpoint",
> not exactly limt to a single NFSv4 client....  So, we can do that as
> long as all the relevant information is in rpc-layer tracepoints, and as
> long as task id is a reliable way to match up trace points.
> 
> Is the network namespace in there anywhere?  It looks like there'd be no
> way to distinguish clients in different namespaces if they had the same
> address.

The client ID has the boot verifier for the net namespace.

None of this helps NFSv3, though.


--
Chuck Lever




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

* Re: [PATCH v2 00/27] NFSD operation monitoring tracepoints
  2020-09-25 15:05           ` Chuck Lever
@ 2020-09-25 17:04             ` Chuck Lever
  2020-09-25 18:37               ` Bruce Fields
  0 siblings, 1 reply; 43+ messages in thread
From: Chuck Lever @ 2020-09-25 17:04 UTC (permalink / raw)
  To: Bruce Fields; +Cc: Bill Baker, Linux NFS Mailing List



> On Sep 25, 2020, at 11:05 AM, Chuck Lever <chuck.lever@oracle.com> wrote:
> 
> 
> 
>> On Sep 25, 2020, at 11:00 AM, Bruce Fields <bfields@fieldses.org> wrote:
>> 
>> On Fri, Sep 25, 2020 at 10:36:42AM -0400, Chuck Lever wrote:
>>> 
>>> 
>>>> On Sep 25, 2020, at 10:32 AM, Bruce Fields <bfields@fieldses.org> wrote:
>>>> 
>>>> On Fri, Sep 25, 2020 at 09:59:51AM -0400, Chuck Lever wrote:
>>>>> Thanks Bruce, for your time, attention, and comments!
>>>>> 
>>>>>> On Sep 24, 2020, at 5:36 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
>>>>>> 
>>>>>> On Mon, Sep 21, 2020 at 02:10:49PM -0400, Chuck Lever wrote:
>>>>>>> As I've been working on various server bugs, I've been adding
>>>>>>> tracepoints that record NFS operation arguments. Here's an updated
>>>>>>> snapshot of this work for your review and comment.
>>>>>>> 
>>>>>>> The idea here is to provide a degree of NFS traffic observability
>>>>>>> without needing network capture. Tracepoints are generally lighter-
>>>>>>> weight than full network capture, allowing effective capture-time
>>>>>>> data reduction:
>>>>>> 
>>>>>> I do wonder when tracepoints seem to duplicate information you could get
>>>>>> from network traces, so thanks for taking the time to explain this.  It
>>>>>> makes sense to me.
>>>>>> 
>>>>>> The patches look fine.  The only one I'm I'm on the fence about is the
>>>>>> last with the split up of the dispatch functions.  I'll ask some
>>>>>> questions there....
>>>>> 
>>>>> To be clear to everyone, this series is still "preview". I expect
>>>>> more churn in these patches, thus I don't consider the series ready
>>>>> to be merged by any stretch.
>>>> 
>>>> OK!
>>>> 
>>>> One thing I was wondering about: how would you limit tracing to a single
>>>> client, say if you wanted to see all DELEGRETURNs from a single client?
>>>> I guess you'd probably turn on a tracepoint in the receive code, look
>>>> for your client's IP address, then mask the task id to match later
>>>> nfs-level tracepoints.  Is there enough information in those tracepoints
>>>> (including network namespace) to uniquely identify a client?
>>> 
>>> Client IP address information is in the RPC layer trace data. The
>>> DELEGRETURN trace record includes client ID. So maybe not as
>>> straightforward as it could be.
>> 
>> I guess what I meant was "limit tracing to a single network endpoint",
>> not exactly limt to a single NFSv4 client....  So, we can do that as
>> long as all the relevant information is in rpc-layer tracepoints, and as
>> long as task id is a reliable way to match up trace points.
>> 
>> Is the network namespace in there anywhere?  It looks like there'd be no
>> way to distinguish clients in different namespaces if they had the same
>> address.
> 
> The client ID has the boot verifier for the net namespace.
> 
> None of this helps NFSv3, though.

It probably wouldn't be difficult to stuff the client IP address
and the boot verifier in the trace record for each procedure.

Do you think that would be sufficient?


--
Chuck Lever




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

* Re: [PATCH v2 00/27] NFSD operation monitoring tracepoints
  2020-09-25 17:04             ` Chuck Lever
@ 2020-09-25 18:37               ` Bruce Fields
  2020-09-25 18:41                 ` Chuck Lever
  0 siblings, 1 reply; 43+ messages in thread
From: Bruce Fields @ 2020-09-25 18:37 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Bill Baker, Linux NFS Mailing List

On Fri, Sep 25, 2020 at 01:04:55PM -0400, Chuck Lever wrote:
> > On Sep 25, 2020, at 11:05 AM, Chuck Lever <chuck.lever@oracle.com> wrote:
> >> On Sep 25, 2020, at 11:00 AM, Bruce Fields <bfields@fieldses.org> wrote:
> >> On Fri, Sep 25, 2020 at 10:36:42AM -0400, Chuck Lever wrote:
> >>>> One thing I was wondering about: how would you limit tracing to a single
> >>>> client, say if you wanted to see all DELEGRETURNs from a single client?
> >>>> I guess you'd probably turn on a tracepoint in the receive code, look
> >>>> for your client's IP address, then mask the task id to match later
> >>>> nfs-level tracepoints.  Is there enough information in those tracepoints
> >>>> (including network namespace) to uniquely identify a client?
> >>> 
> >>> Client IP address information is in the RPC layer trace data. The
> >>> DELEGRETURN trace record includes client ID. So maybe not as
> >>> straightforward as it could be.
> >> 
> >> I guess what I meant was "limit tracing to a single network endpoint",
> >> not exactly limt to a single NFSv4 client....  So, we can do that as
> >> long as all the relevant information is in rpc-layer tracepoints, and as
> >> long as task id is a reliable way to match up trace points.
> >> 
> >> Is the network namespace in there anywhere?  It looks like there'd be no
> >> way to distinguish clients in different namespaces if they had the same
> >> address.
> > 
> > The client ID has the boot verifier for the net namespace.
> > 
> > None of this helps NFSv3, though.
> 
> It probably wouldn't be difficult to stuff the client IP address
> and the boot verifier in the trace record for each procedure.
> 
> Do you think that would be sufficient?

Despite using 64 bits the boot verifier isn't even guaranteed to
uniquely identify a network namespace.  There should be something
better.  Digging around....  ns->inum, I think?

I don't know if it (or ports or addresses) needs to be in every trace
record.  Maybe just once somewhere in one of the rpc layer tracepoints,
and then we can use the nfsd task id to connect it with other
tracepoints if necessary.  Does that make sense?

--b.

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

* Re: [PATCH v2 00/27] NFSD operation monitoring tracepoints
  2020-09-25 18:37               ` Bruce Fields
@ 2020-09-25 18:41                 ` Chuck Lever
  0 siblings, 0 replies; 43+ messages in thread
From: Chuck Lever @ 2020-09-25 18:41 UTC (permalink / raw)
  To: Bruce Fields; +Cc: Bill Baker, Linux NFS Mailing List



> On Sep 25, 2020, at 2:37 PM, Bruce Fields <bfields@fieldses.org> wrote:
> 
> On Fri, Sep 25, 2020 at 01:04:55PM -0400, Chuck Lever wrote:
>>> On Sep 25, 2020, at 11:05 AM, Chuck Lever <chuck.lever@oracle.com> wrote:
>>>> On Sep 25, 2020, at 11:00 AM, Bruce Fields <bfields@fieldses.org> wrote:
>>>> On Fri, Sep 25, 2020 at 10:36:42AM -0400, Chuck Lever wrote:
>>>>>> One thing I was wondering about: how would you limit tracing to a single
>>>>>> client, say if you wanted to see all DELEGRETURNs from a single client?
>>>>>> I guess you'd probably turn on a tracepoint in the receive code, look
>>>>>> for your client's IP address, then mask the task id to match later
>>>>>> nfs-level tracepoints.  Is there enough information in those tracepoints
>>>>>> (including network namespace) to uniquely identify a client?
>>>>> 
>>>>> Client IP address information is in the RPC layer trace data. The
>>>>> DELEGRETURN trace record includes client ID. So maybe not as
>>>>> straightforward as it could be.
>>>> 
>>>> I guess what I meant was "limit tracing to a single network endpoint",
>>>> not exactly limt to a single NFSv4 client....  So, we can do that as
>>>> long as all the relevant information is in rpc-layer tracepoints, and as
>>>> long as task id is a reliable way to match up trace points.
>>>> 
>>>> Is the network namespace in there anywhere?  It looks like there'd be no
>>>> way to distinguish clients in different namespaces if they had the same
>>>> address.
>>> 
>>> The client ID has the boot verifier for the net namespace.
>>> 
>>> None of this helps NFSv3, though.
>> 
>> It probably wouldn't be difficult to stuff the client IP address
>> and the boot verifier in the trace record for each procedure.
>> 
>> Do you think that would be sufficient?
> 
> Despite using 64 bits the boot verifier isn't even guaranteed to
> uniquely identify a network namespace.  There should be something
> better.  Digging around....  ns->inum, I think?

Could use that, but NFSD already uses the boot verifier everywhere.
I'll have a look.


> I don't know if it (or ports or addresses) needs to be in every trace
> record.  Maybe just once somewhere in one of the rpc layer tracepoints,
> and then we can use the nfsd task id to connect it with other
> tracepoints if necessary.  Does that make sense?

If you want to do filtering during capture, you want to have this
kind of information available in each record so the generic trace
utilities can find it.

We don't have to display it in every record that is output by
trace-cmd report, though.


--
Chuck Lever




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

end of thread, other threads:[~2020-09-25 18:44 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-21 18:10 [PATCH v2 00/27] NFSD operation monitoring tracepoints Chuck Lever
2020-09-21 18:10 ` [PATCH v2 01/27] NFS: Move generic FS show macros to global header Chuck Lever
2020-09-21 18:11 ` [PATCH v2 02/27] NFS: Move NFS protocol display " Chuck Lever
2020-09-21 18:11 ` [PATCH v2 03/27] NFSD: Add SPDX header for fs/nfsd/trace.c Chuck Lever
2020-09-21 18:11 ` [PATCH v2 04/27] SUNRPC: Move the svc_xdr_recvfrom() tracepoint Chuck Lever
2020-09-21 18:11 ` [PATCH v2 05/27] SUNRPC: Add svc_xdr_authenticate tracepoint Chuck Lever
2020-09-21 18:11 ` [PATCH v2 06/27] lockd: Replace PROC() macro with open code Chuck Lever
2020-09-21 18:11 ` [PATCH v2 07/27] NFSACL: " Chuck Lever
2020-09-21 18:11 ` [PATCH v2 08/27] SUNRPC: Make trace_svc_process() display the RPC procedure symbolically Chuck Lever
2020-09-21 18:11 ` [PATCH v2 09/27] NFSD: Clean up the show_nf_may macro Chuck Lever
2020-09-21 18:11 ` [PATCH v2 10/27] NFSD: Remove extra "0x" in tracepoint format specifier Chuck Lever
2020-09-21 18:11 ` [PATCH v2 11/27] NFSD: Constify @fh argument of knfsd_fh_hash() Chuck Lever
2020-09-21 18:11 ` [PATCH v2 12/27] NFSD: Add tracepoint in nfsd_setattr() Chuck Lever
2020-09-21 18:11 ` [PATCH v2 13/27] NFSD: Add tracepoint for nfsd_access() Chuck Lever
2020-09-21 18:12 ` [PATCH v2 14/27] NFSD: nfsd_compound_status tracepoint should record XID Chuck Lever
2020-09-21 18:12 ` [PATCH v2 15/27] NFSD: Add client ID lifetime tracepoints Chuck Lever
2020-09-21 18:12 ` [PATCH v2 16/27] NFSD: Add tracepoints to report NFSv4 session state Chuck Lever
2020-09-21 18:12 ` [PATCH v2 17/27] NFSD: Add a tracepoint to report the current filehandle Chuck Lever
2020-09-21 18:12 ` [PATCH v2 18/27] NFSD: Add GETATTR tracepoint Chuck Lever
2020-09-21 18:12 ` [PATCH v2 19/27] NFSD: Add tracepoint in nfsd4_stateid_preprocess() Chuck Lever
2020-09-21 18:12 ` [PATCH v2 20/27] NFSD: Add tracepoint to report arguments to NFSv4 OPEN Chuck Lever
2020-09-21 18:12 ` [PATCH v2 21/27] NFSD: Add a tracepoint for DELEGRETURN Chuck Lever
2020-09-21 18:12 ` [PATCH v2 22/27] NFSD: Add a lookup tracepoint Chuck Lever
2020-09-21 18:12 ` [PATCH v2 23/27] NFSD: Add lock and locku tracepoints Chuck Lever
2020-09-21 18:12 ` [PATCH v2 24/27] NFSD: Add tracepoints to record the result of TEST_STATEID and FREE_STATEID Chuck Lever
2020-09-21 18:13 ` [PATCH v2 25/27] NFSD: Rename nfsd_ tracepoints to nfsd4_ Chuck Lever
2020-09-21 18:13 ` [PATCH v2 26/27] NFSD: Add tracepoints in the NFS dispatcher Chuck Lever
2020-09-24 23:45   ` J. Bruce Fields
2020-09-25 13:59     ` Chuck Lever
2020-09-25 14:17       ` Bruce Fields
2020-09-25 14:21         ` Chuck Lever
2020-09-25 14:18       ` Chuck Lever
2020-09-25 14:47       ` Bruce Fields
2020-09-21 18:13 ` [PATCH v2 27/27] NFSD: Replace dprintk callsites in fs/nfsd/nfsfh.c Chuck Lever
2020-09-24 21:36 ` [PATCH v2 00/27] NFSD operation monitoring tracepoints J. Bruce Fields
2020-09-25 13:59   ` Chuck Lever
2020-09-25 14:32     ` Bruce Fields
2020-09-25 14:36       ` Chuck Lever
2020-09-25 15:00         ` Bruce Fields
2020-09-25 15:05           ` Chuck Lever
2020-09-25 17:04             ` Chuck Lever
2020-09-25 18:37               ` Bruce Fields
2020-09-25 18:41                 ` Chuck Lever

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).