nfs: add new nfs_direct_req tracepoint events
authorJeff Layton <jlayton@kernel.org>
Fri, 22 Jul 2022 18:12:18 +0000 (14:12 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Sat, 23 Jul 2022 19:28:59 +0000 (15:28 -0400)
Add some new tracepoints to the DIO write code.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/direct.c
fs/nfs/internal.h
fs/nfs/nfstrace.h

index 4eb2a8380a28e063cd49baaee55e980b3fe307d5..ad40e81857ee442fe75b2ce2c6a03fefd2f7c59f 100644 (file)
 #include "iostat.h"
 #include "pnfs.h"
 #include "fscache.h"
+#include "nfstrace.h"
 
 #define NFSDBG_FACILITY                NFSDBG_VFS
 
 static struct kmem_cache *nfs_direct_cachep;
 
-struct nfs_direct_req {
-       struct kref             kref;           /* release manager */
-
-       /* I/O parameters */
-       struct nfs_open_context *ctx;           /* file open context info */
-       struct nfs_lock_context *l_ctx;         /* Lock context info */
-       struct kiocb *          iocb;           /* controlling i/o request */
-       struct inode *          inode;          /* target file of i/o */
-
-       /* completion state */
-       atomic_t                io_count;       /* i/os we're waiting for */
-       spinlock_t              lock;           /* protect completion state */
-
-       loff_t                  io_start;       /* Start offset for I/O */
-       ssize_t                 count,          /* bytes actually processed */
-                               max_count,      /* max expected count */
-                               bytes_left,     /* bytes left to be sent */
-                               error;          /* any reported error */
-       struct completion       completion;     /* wait for i/o completion */
-
-       /* commit state */
-       struct nfs_mds_commit_info mds_cinfo;   /* Storage for cinfo */
-       struct pnfs_ds_commit_info ds_cinfo;    /* Storage for cinfo */
-       struct work_struct      work;
-       int                     flags;
-       /* for write */
-#define NFS_ODIRECT_DO_COMMIT          (1)     /* an unstable reply was received */
-#define NFS_ODIRECT_RESCHED_WRITES     (2)     /* write verification failed */
-       /* for read */
-#define NFS_ODIRECT_SHOULD_DIRTY       (3)     /* dirty user-space page after read */
-#define NFS_ODIRECT_DONE               INT_MAX /* write verification failed */
-};
-
 static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops;
 static const struct nfs_commit_completion_ops nfs_direct_commit_completion_ops;
 static void nfs_direct_write_complete(struct nfs_direct_req *dreq);
@@ -595,6 +563,8 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
        struct nfs_page *req;
        int status = data->task.tk_status;
 
+       trace_nfs_direct_commit_complete(dreq);
+
        if (status < 0) {
                /* Errors in commit are fatal */
                dreq->error = status;
@@ -631,6 +601,8 @@ static void nfs_direct_resched_write(struct nfs_commit_info *cinfo,
 {
        struct nfs_direct_req *dreq = cinfo->dreq;
 
+       trace_nfs_direct_resched_write(dreq);
+
        spin_lock(&dreq->lock);
        if (dreq->flags != NFS_ODIRECT_DONE)
                dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
@@ -695,6 +667,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)
 
 static void nfs_direct_write_complete(struct nfs_direct_req *dreq)
 {
+       trace_nfs_direct_write_complete(dreq);
        queue_work(nfsiod_workqueue, &dreq->work); /* Calls nfs_direct_write_schedule_work */
 }
 
@@ -705,6 +678,8 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
        struct nfs_page *req = nfs_list_entry(hdr->pages.next);
        int flags = NFS_ODIRECT_DONE;
 
+       trace_nfs_direct_write_completion(dreq);
+
        nfs_init_cinfo_from_dreq(&cinfo, dreq);
 
        spin_lock(&dreq->lock);
@@ -759,6 +734,8 @@ static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr)
 {
        struct nfs_direct_req *dreq = hdr->dreq;
 
+       trace_nfs_direct_write_reschedule_io(dreq);
+
        spin_lock(&dreq->lock);
        if (dreq->error == 0) {
                dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
@@ -799,6 +776,8 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
        size_t requested_bytes = 0;
        size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE);
 
+       trace_nfs_direct_write_schedule_iovec(dreq);
+
        nfs_pageio_init_write(&desc, inode, ioflags, false,
                              &nfs_direct_write_completion_ops);
        desc.pg_dreq = dreq;
index af6d261241ff769f05f4bb445a11c4fe34d94e9c..0cabc7f07d9aa2ef654f3577ef87b739f8277fdf 100644 (file)
@@ -877,3 +877,36 @@ static inline void nfs_set_port(struct sockaddr *sap, int *port,
 
        rpc_set_port(sap, *port);
 }
+
+struct nfs_direct_req {
+       struct kref             kref;           /* release manager */
+
+       /* I/O parameters */
+       struct nfs_open_context *ctx;           /* file open context info */
+       struct nfs_lock_context *l_ctx;         /* Lock context info */
+       struct kiocb *          iocb;           /* controlling i/o request */
+       struct inode *          inode;          /* target file of i/o */
+
+       /* completion state */
+       atomic_t                io_count;       /* i/os we're waiting for */
+       spinlock_t              lock;           /* protect completion state */
+
+       loff_t                  io_start;       /* Start offset for I/O */
+       ssize_t                 count,          /* bytes actually processed */
+                               max_count,      /* max expected count */
+                               bytes_left,     /* bytes left to be sent */
+                               error;          /* any reported error */
+       struct completion       completion;     /* wait for i/o completion */
+
+       /* commit state */
+       struct nfs_mds_commit_info mds_cinfo;   /* Storage for cinfo */
+       struct pnfs_ds_commit_info ds_cinfo;    /* Storage for cinfo */
+       struct work_struct      work;
+       int                     flags;
+       /* for write */
+#define NFS_ODIRECT_DO_COMMIT          (1)     /* an unstable reply was received */
+#define NFS_ODIRECT_RESCHED_WRITES     (2)     /* write verification failed */
+       /* for read */
+#define NFS_ODIRECT_SHOULD_DIRTY       (3)     /* dirty user-space page after read */
+#define NFS_ODIRECT_DONE               INT_MAX /* write verification failed */
+};
index 012bd733986221e00eeaf2952b1ad066b1653704..65388e4a0cd7f8ca684a6e48e01a6a5b0e02b181 100644 (file)
@@ -1576,6 +1576,75 @@ TRACE_EVENT(nfs_commit_done,
                )
 );
 
+#define nfs_show_direct_req_flags(v) \
+       __print_flags(v, "|", \
+                       { NFS_ODIRECT_DO_COMMIT, "DO_COMMIT" }, \
+                       { NFS_ODIRECT_RESCHED_WRITES, "RESCHED_WRITES" }, \
+                       { NFS_ODIRECT_SHOULD_DIRTY, "SHOULD DIRTY" }, \
+                       { NFS_ODIRECT_DONE, "DONE" } )
+
+DECLARE_EVENT_CLASS(nfs_direct_req_class,
+               TP_PROTO(
+                       const struct nfs_direct_req *dreq
+               ),
+
+               TP_ARGS(dreq),
+
+               TP_STRUCT__entry(
+                       __field(const struct nfs_direct_req *, dreq)
+                       __field(dev_t, dev)
+                       __field(u64, fileid)
+                       __field(u32, fhandle)
+                       __field(int, ref)
+                       __field(loff_t, io_start)
+                       __field(ssize_t, count)
+                       __field(ssize_t, bytes_left)
+                       __field(ssize_t, error)
+                       __field(int, flags)
+               ),
+
+               TP_fast_assign(
+                       const struct inode *inode = dreq->inode;
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+                       const struct nfs_fh *fh = &nfsi->fh;
+
+                       __entry->dreq = dreq;
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->fileid = nfsi->fileid;
+                       __entry->fhandle = nfs_fhandle_hash(fh);
+                       __entry->ref = kref_read(&dreq->kref);
+                       __entry->io_start = dreq->io_start;
+                       __entry->count = dreq->count;
+                       __entry->bytes_left = dreq->bytes_left;
+                       __entry->error = dreq->error;
+                       __entry->flags = dreq->flags;
+               ),
+
+               TP_printk(
+                       "dreq=%p fileid=%02x:%02x:%llu fhandle=0x%08x ref=%d "
+                       "io_start=%lld count=%zd bytes_left=%zd error=%zd flags=%s",
+                       __entry->dreq, MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle, __entry->ref,
+                       __entry->io_start, __entry->count, __entry->bytes_left,
+                       __entry->error, nfs_show_direct_req_flags(__entry->flags)
+               )
+);
+
+#define DEFINE_NFS_DIRECT_REQ_EVENT(name) \
+       DEFINE_EVENT(nfs_direct_req_class, name, \
+                       TP_PROTO( \
+                               const struct nfs_direct_req *dreq \
+                       ), \
+                       TP_ARGS(dreq))
+
+DEFINE_NFS_DIRECT_REQ_EVENT(nfs_direct_commit_complete);
+DEFINE_NFS_DIRECT_REQ_EVENT(nfs_direct_resched_write);
+DEFINE_NFS_DIRECT_REQ_EVENT(nfs_direct_write_complete);
+DEFINE_NFS_DIRECT_REQ_EVENT(nfs_direct_write_completion);
+DEFINE_NFS_DIRECT_REQ_EVENT(nfs_direct_write_schedule_iovec);
+DEFINE_NFS_DIRECT_REQ_EVENT(nfs_direct_write_reschedule_io);
+
 TRACE_EVENT(nfs_fh_to_dentry,
                TP_PROTO(
                        const struct super_block *sb,