Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a4bf31d authored by Jeff Layton's avatar Jeff Layton Committed by Trond Myklebust
Browse files

nfs: add new tracepoint for pnfs_update_layout



pnfs_update_layout is really the "nexus" of layout handling. If it
returns NULL then we end up going through the MDS. This patch adds
some tracepoints to that function that allow us to determine the
cause when we end up going through the MDS unexpectedly.

Signed-off-by: default avatarJeff Layton <jeff.layton@primarydata.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 9759b0fb
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
@@ -1442,6 +1442,62 @@ DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutcommit);
DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutreturn);
DEFINE_NFS4_INODE_EVENT(nfs4_layoutreturn_on_close);

#define show_pnfs_update_layout_reason(reason)				\
	__print_symbolic(reason,					\
		{ PNFS_UPDATE_LAYOUT_UNKNOWN, "unknown" },		\
		{ PNFS_UPDATE_LAYOUT_NO_PNFS, "no pnfs" },		\
		{ PNFS_UPDATE_LAYOUT_RD_ZEROLEN, "read+zerolen" },	\
		{ PNFS_UPDATE_LAYOUT_MDSTHRESH, "mdsthresh" },		\
		{ PNFS_UPDATE_LAYOUT_NOMEM, "nomem" },			\
		{ PNFS_UPDATE_LAYOUT_BULK_RECALL, "bulk recall" },	\
		{ PNFS_UPDATE_LAYOUT_IO_TEST_FAIL, "io test fail" },	\
		{ PNFS_UPDATE_LAYOUT_FOUND_CACHED, "found cached" },	\
		{ PNFS_UPDATE_LAYOUT_RETURN, "layoutreturn" },		\
		{ PNFS_UPDATE_LAYOUT_BLOCKED, "layouts blocked" },	\
		{ PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET, "sent layoutget" })

TRACE_EVENT(pnfs_update_layout,
		TP_PROTO(struct inode *inode,
			loff_t pos,
			u64 count,
			enum pnfs_iomode iomode,
			struct pnfs_layout_segment *lseg,
			enum pnfs_update_layout_reason reason
		),
		TP_ARGS(inode, pos, count, iomode, lseg, reason),
		TP_STRUCT__entry(
			__field(dev_t, dev)
			__field(u64, fileid)
			__field(u32, fhandle)
			__field(loff_t, pos)
			__field(u64, count)
			__field(enum pnfs_iomode, iomode)
			__field(struct pnfs_layout_segment *, lseg)
			__field(enum pnfs_update_layout_reason, reason)
		),
		TP_fast_assign(
			__entry->dev = inode->i_sb->s_dev;
			__entry->fileid = NFS_FILEID(inode);
			__entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
			__entry->pos = pos;
			__entry->count = count;
			__entry->iomode = iomode;
			__entry->lseg = lseg;
			__entry->reason = reason;
		),
		TP_printk(
			"fileid=%02x:%02x:%llu fhandle=0x%08x "
			"iomode=%s pos=%llu count=%llu lseg=%p (%s)",
			MAJOR(__entry->dev), MINOR(__entry->dev),
			(unsigned long long)__entry->fileid,
			__entry->fhandle,
			show_pnfs_iomode(__entry->iomode),
			(unsigned long long)__entry->pos,
			(unsigned long long)__entry->count, __entry->lseg,
			show_pnfs_update_layout_reason(__entry->reason)
		)
);

#endif /* CONFIG_NFS_V4_1 */

#endif /* _TRACE_NFS4_H */
+32 −6
Original line number Diff line number Diff line
@@ -1520,14 +1520,23 @@ pnfs_update_layout(struct inode *ino,
	struct pnfs_layout_segment *lseg = NULL;
	bool first;

	if (!pnfs_enabled_sb(NFS_SERVER(ino)))
	if (!pnfs_enabled_sb(NFS_SERVER(ino))) {
		trace_pnfs_update_layout(ino, pos, count, iomode, lseg,
				 PNFS_UPDATE_LAYOUT_NO_PNFS);
		goto out;
	}

	if (iomode == IOMODE_READ && i_size_read(ino) == 0)
	if (iomode == IOMODE_READ && i_size_read(ino) == 0) {
		trace_pnfs_update_layout(ino, pos, count, iomode, lseg,
				 PNFS_UPDATE_LAYOUT_RD_ZEROLEN);
		goto out;
	}

	if (pnfs_within_mdsthreshold(ctx, ino, iomode))
	if (pnfs_within_mdsthreshold(ctx, ino, iomode)) {
		trace_pnfs_update_layout(ino, pos, count, iomode, lseg,
				 PNFS_UPDATE_LAYOUT_MDSTHRESH);
		goto out;
	}

lookup_again:
	first = false;
@@ -1535,19 +1544,26 @@ pnfs_update_layout(struct inode *ino,
	lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags);
	if (lo == NULL) {
		spin_unlock(&ino->i_lock);
		trace_pnfs_update_layout(ino, pos, count, iomode, lseg,
				 PNFS_UPDATE_LAYOUT_NOMEM);
		goto out;
	}

	/* Do we even need to bother with this? */
	if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) {
		trace_pnfs_update_layout(ino, pos, count, iomode, lseg,
				 PNFS_UPDATE_LAYOUT_BULK_RECALL);
		dprintk("%s matches recall, use MDS\n", __func__);
		goto out_unlock;
	}

	/* if LAYOUTGET already failed once we don't try again */
	if (pnfs_layout_io_test_failed(lo, iomode) &&
	    !pnfs_should_retry_layoutget(lo))
	    !pnfs_should_retry_layoutget(lo)) {
		trace_pnfs_update_layout(ino, pos, count, iomode, lseg,
				 PNFS_UPDATE_LAYOUT_IO_TEST_FAIL);
		goto out_unlock;
	}

	first = list_empty(&lo->plh_segs);
	if (first) {
@@ -1567,9 +1583,12 @@ pnfs_update_layout(struct inode *ino,
		 * already exists
		 */
		lseg = pnfs_find_lseg(lo, &arg);
		if (lseg)
		if (lseg) {
			trace_pnfs_update_layout(ino, pos, count, iomode, lseg,
					PNFS_UPDATE_LAYOUT_FOUND_CACHED);
			goto out_unlock;
		}
	}

	/*
	 * Because we free lsegs before sending LAYOUTRETURN, we need to wait
@@ -1585,11 +1604,16 @@ pnfs_update_layout(struct inode *ino,
			dprintk("%s retrying\n", __func__);
			goto lookup_again;
		}
		trace_pnfs_update_layout(ino, pos, count, iomode, lseg,
				PNFS_UPDATE_LAYOUT_RETURN);
		goto out_put_layout_hdr;
	}

	if (pnfs_layoutgets_blocked(lo))
	if (pnfs_layoutgets_blocked(lo)) {
		trace_pnfs_update_layout(ino, pos, count, iomode, lseg,
				PNFS_UPDATE_LAYOUT_BLOCKED);
		goto out_unlock;
	}
	atomic_inc(&lo->plh_outstanding);
	spin_unlock(&ino->i_lock);

@@ -1614,6 +1638,8 @@ pnfs_update_layout(struct inode *ino,
	lseg = send_layoutget(lo, ctx, &arg, gfp_flags);
	pnfs_clear_retry_layoutget(lo);
	atomic_dec(&lo->plh_outstanding);
	trace_pnfs_update_layout(ino, pos, count, iomode, lseg,
				 PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET);
out_put_layout_hdr:
	if (first)
		pnfs_clear_first_layoutget(lo);
+14 −0
Original line number Diff line number Diff line
@@ -592,4 +592,18 @@ enum data_content4 {
	NFS4_CONTENT_HOLE		= 1,
};

enum pnfs_update_layout_reason {
	PNFS_UPDATE_LAYOUT_UNKNOWN = 0,
	PNFS_UPDATE_LAYOUT_NO_PNFS,
	PNFS_UPDATE_LAYOUT_RD_ZEROLEN,
	PNFS_UPDATE_LAYOUT_MDSTHRESH,
	PNFS_UPDATE_LAYOUT_NOMEM,
	PNFS_UPDATE_LAYOUT_BULK_RECALL,
	PNFS_UPDATE_LAYOUT_IO_TEST_FAIL,
	PNFS_UPDATE_LAYOUT_FOUND_CACHED,
	PNFS_UPDATE_LAYOUT_RETURN,
	PNFS_UPDATE_LAYOUT_BLOCKED,
	PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET,
};

#endif