Commit 47553dd6 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Carlos Maiolino
Browse files

xfs: remove metafile inodes from the active inode stat



The active inode (or active vnode until recently) stat can get much larger
than expected on file systems with a lot of metafile inodes like zoned
file systems on SMR hard disks with 10.000s of rtg rmap inodes.

Remove all metafile inodes from the active counter to make it more useful
to track actual workloads and add a separate counter for active metafile
inodes.

This fixes xfs/177 on SMR hard drives.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarCarlos Maiolino <cem@kernel.org>
parent 03a6d6c4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -268,6 +268,10 @@ xfs_inode_from_disk(
	}
	if (xfs_is_reflink_inode(ip))
		xfs_ifork_init_cow(ip);
	if (xfs_is_metadir_inode(ip)) {
		XFS_STATS_DEC(ip->i_mount, xs_inodes_active);
		XFS_STATS_INC(ip->i_mount, xs_inodes_meta);
	}
	return 0;

out_destroy_data_fork:
+5 −0
Original line number Diff line number Diff line
@@ -61,6 +61,9 @@ xfs_metafile_set_iflag(
	ip->i_diflags2 |= XFS_DIFLAG2_METADATA;
	ip->i_metatype = metafile_type;
	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);

	XFS_STATS_DEC(ip->i_mount, xs_inodes_active);
	XFS_STATS_INC(ip->i_mount, xs_inodes_meta);
}

/* Clear the metadata directory inode flag. */
@@ -74,6 +77,8 @@ xfs_metafile_clear_iflag(

	ip->i_diflags2 &= ~XFS_DIFLAG2_METADATA;
	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
	XFS_STATS_INC(ip->i_mount, xs_inodes_active);
	XFS_STATS_DEC(ip->i_mount, xs_inodes_meta);
}

/*
+4 −1
Original line number Diff line number Diff line
@@ -172,6 +172,9 @@ __xfs_inode_free(
	/* asserts to verify all state is correct here */
	ASSERT(atomic_read(&ip->i_pincount) == 0);
	ASSERT(!ip->i_itemp || list_empty(&ip->i_itemp->ili_item.li_bio_list));
	if (xfs_is_metadir_inode(ip))
		XFS_STATS_DEC(ip->i_mount, xs_inodes_meta);
	else
		XFS_STATS_DEC(ip->i_mount, xs_inodes_active);

	call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback);
+8 −3
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
		{ "rtrefcntbt",		xfsstats_offset(xs_qm_dqreclaims)},
		/* we print both series of quota information together */
		{ "qm",			xfsstats_offset(xs_gc_read_calls)},
		{ "zoned",		xfsstats_offset(__pad1)},
		{ "zoned",		xfsstats_offset(xs_inodes_meta)},
		{ "metafile",		xfsstats_offset(xs_xstrat_bytes)},
	};

	/* Loop over all stats groups */
@@ -99,16 +100,20 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)

void xfs_stats_clearall(struct xfsstats __percpu *stats)
{
	uint32_t	xs_inodes_active, xs_inodes_meta;
	int		c;
	uint32_t	xs_inodes_active;

	xfs_notice(NULL, "Clearing xfsstats");
	for_each_possible_cpu(c) {
		preempt_disable();
		/* save xs_inodes_active, it's a universal truth! */
		/*
		 * Save the active / meta inode counters, as they are stateful.
		 */
		xs_inodes_active = per_cpu_ptr(stats, c)->s.xs_inodes_active;
		xs_inodes_meta = per_cpu_ptr(stats, c)->s.xs_inodes_meta;
		memset(per_cpu_ptr(stats, c), 0, sizeof(*stats));
		per_cpu_ptr(stats, c)->s.xs_inodes_active = xs_inodes_active;
		per_cpu_ptr(stats, c)->s.xs_inodes_meta = xs_inodes_meta;
		preempt_enable();
	}
}
+2 −1
Original line number Diff line number Diff line
@@ -142,7 +142,8 @@ struct __xfsstats {
	uint32_t		xs_gc_read_calls;
	uint32_t		xs_gc_write_calls;
	uint32_t		xs_gc_zone_reset_calls;
	uint32_t		__pad1;
/* Metafile counters */
	uint32_t		xs_inodes_meta;
/* Extra precision counters */
	uint64_t		xs_xstrat_bytes;
	uint64_t		xs_write_bytes;