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

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
Loading
Loading
Loading
Loading
+12 −33
Original line number Diff line number Diff line
@@ -60,44 +60,12 @@
#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;
+33 −0
Original line number Diff line number Diff line
@@ -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 */
};
+69 −0
Original line number Diff line number Diff line
@@ -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,