Commit 8efc4bbe authored by Jeff Layton's avatar Jeff Layton Committed by Trond Myklebust

nfs: add new nfs_direct_req tracepoint events

Add some new tracepoints to the DIO write code.
Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent ba8ec7a6
...@@ -60,44 +60,12 @@ ...@@ -60,44 +60,12 @@
#include "iostat.h" #include "iostat.h"
#include "pnfs.h" #include "pnfs.h"
#include "fscache.h" #include "fscache.h"
#include "nfstrace.h"
#define NFSDBG_FACILITY NFSDBG_VFS #define NFSDBG_FACILITY NFSDBG_VFS
static struct kmem_cache *nfs_direct_cachep; 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_pgio_completion_ops nfs_direct_write_completion_ops;
static const struct nfs_commit_completion_ops nfs_direct_commit_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); 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) ...@@ -595,6 +563,8 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
struct nfs_page *req; struct nfs_page *req;
int status = data->task.tk_status; int status = data->task.tk_status;
trace_nfs_direct_commit_complete(dreq);
if (status < 0) { if (status < 0) {
/* Errors in commit are fatal */ /* Errors in commit are fatal */
dreq->error = status; dreq->error = status;
...@@ -631,6 +601,8 @@ static void nfs_direct_resched_write(struct nfs_commit_info *cinfo, ...@@ -631,6 +601,8 @@ static void nfs_direct_resched_write(struct nfs_commit_info *cinfo,
{ {
struct nfs_direct_req *dreq = cinfo->dreq; struct nfs_direct_req *dreq = cinfo->dreq;
trace_nfs_direct_resched_write(dreq);
spin_lock(&dreq->lock); spin_lock(&dreq->lock);
if (dreq->flags != NFS_ODIRECT_DONE) if (dreq->flags != NFS_ODIRECT_DONE)
dreq->flags = NFS_ODIRECT_RESCHED_WRITES; dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
...@@ -695,6 +667,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work) ...@@ -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) 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 */ 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) ...@@ -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); struct nfs_page *req = nfs_list_entry(hdr->pages.next);
int flags = NFS_ODIRECT_DONE; int flags = NFS_ODIRECT_DONE;
trace_nfs_direct_write_completion(dreq);
nfs_init_cinfo_from_dreq(&cinfo, dreq); nfs_init_cinfo_from_dreq(&cinfo, dreq);
spin_lock(&dreq->lock); spin_lock(&dreq->lock);
...@@ -759,6 +734,8 @@ static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr) ...@@ -759,6 +734,8 @@ static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr)
{ {
struct nfs_direct_req *dreq = hdr->dreq; struct nfs_direct_req *dreq = hdr->dreq;
trace_nfs_direct_write_reschedule_io(dreq);
spin_lock(&dreq->lock); spin_lock(&dreq->lock);
if (dreq->error == 0) { if (dreq->error == 0) {
dreq->flags = NFS_ODIRECT_RESCHED_WRITES; dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
...@@ -799,6 +776,8 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, ...@@ -799,6 +776,8 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
size_t requested_bytes = 0; size_t requested_bytes = 0;
size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE); 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_pageio_init_write(&desc, inode, ioflags, false,
&nfs_direct_write_completion_ops); &nfs_direct_write_completion_ops);
desc.pg_dreq = dreq; desc.pg_dreq = dreq;
......
...@@ -877,3 +877,36 @@ static inline void nfs_set_port(struct sockaddr *sap, int *port, ...@@ -877,3 +877,36 @@ static inline void nfs_set_port(struct sockaddr *sap, int *port,
rpc_set_port(sap, *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 */
};
...@@ -1576,6 +1576,75 @@ TRACE_EVENT(nfs_commit_done, ...@@ -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, TRACE_EVENT(nfs_fh_to_dentry,
TP_PROTO( TP_PROTO(
const struct super_block *sb, const struct super_block *sb,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment