[PATCH] xfs: export buffer cache usage via stats

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch introduces new fields to per-mount and global stats,
and export them to user space.

@page_alloc	-- number of pages allocated from buddy to buffer cache
@page_free	-- number of pages freed to buddy from buffer cache
@kbb_alloc	-- number of BBs allocated from kmalloc slab to buffer cache
@kbb_free	-- number of BBs freed to kmalloc slab from buffer cache
@vbb_alloc	-- number of BBs allocated from vmalloc system to buffer cache
@vbb_free	-- number of BBs freed to vmalloc system from buffer cache

By looking at above stats fields, user space can easily know the buffer
cache usage.

Signed-off-by: Wengang Wang <wen.gang.wang@xxxxxxxxxx>
---
 fs/xfs/xfs_buf.c   | 15 +++++++++++----
 fs/xfs/xfs_stats.c | 16 ++++++++++++++++
 fs/xfs/xfs_stats.h |  8 ++++++++
 3 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 1a2b3f06fa71..db3cb94eabee 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -113,12 +113,17 @@ xfs_buf_free(
 	if (!xfs_buftarg_is_mem(bp->b_target) && size >= PAGE_SIZE)
 		mm_account_reclaimed_pages(howmany(size, PAGE_SHIFT));
 
-	if (is_vmalloc_addr(bp->b_addr))
+	if (is_vmalloc_addr(bp->b_addr)) {
 		vfree(bp->b_addr);
-	else if (bp->b_flags & _XBF_KMEM)
+		XFS_STATS_ADD(bp->b_mount, xs_buf_vbb_free, bp->b_length);
+	} else if (bp->b_flags & _XBF_KMEM) {
 		kfree(bp->b_addr);
-	else
+		XFS_STATS_ADD(bp->b_mount, xs_buf_kbb_free, bp->b_length);
+	} else {
 		folio_put(virt_to_folio(bp->b_addr));
+		XFS_STATS_ADD(bp->b_mount, xs_buf_page_free,
+			      BBTOB(bp->b_length) >> PAGE_SHIFT);
+	}
 
 	call_rcu(&bp->b_rcu, xfs_buf_free_callback);
 }
@@ -147,6 +152,7 @@ xfs_buf_alloc_kmem(
 		return -ENOMEM;
 	}
 	bp->b_flags |= _XBF_KMEM;
+	XFS_STATS_ADD(bp->b_mount, xs_buf_kbb_alloc, bp->b_length);
 	trace_xfs_buf_backing_kmem(bp, _RET_IP_);
 	return 0;
 }
@@ -232,6 +238,7 @@ xfs_buf_alloc_backing_mem(
 	}
 	bp->b_addr = folio_address(folio);
 	trace_xfs_buf_backing_folio(bp, _RET_IP_);
+	XFS_STATS_ADD(bp->b_mount, xs_buf_page_alloc, size >> PAGE_SHIFT);
 	return 0;
 
 fallback:
@@ -244,7 +251,7 @@ xfs_buf_alloc_backing_mem(
 		XFS_STATS_INC(bp->b_mount, xb_page_retries);
 		memalloc_retry_wait(gfp_mask);
 	}
-
+	XFS_STATS_ADD(bp->b_mount, xs_buf_vbb_alloc, bp->b_length);
 	trace_xfs_buf_backing_vmalloc(bp, _RET_IP_);
 	return 0;
 }
diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c
index 35c7fb3ba324..a0f6813dc782 100644
--- a/fs/xfs/xfs_stats.c
+++ b/fs/xfs/xfs_stats.c
@@ -24,6 +24,12 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
 	uint64_t	xs_write_bytes = 0;
 	uint64_t	xs_read_bytes = 0;
 	uint64_t	defer_relog = 0;
+	uint64_t	pg_alloc = 0;
+	uint64_t	pg_free = 0;
+	uint64_t	kbb_alloc = 0;
+	uint64_t	kbb_free = 0;
+	uint64_t	vbb_alloc = 0;
+	uint64_t	vbb_free = 0;
 
 	static const struct xstats_entry {
 		char	*desc;
@@ -77,6 +83,12 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
 		xs_write_bytes += per_cpu_ptr(stats, i)->s.xs_write_bytes;
 		xs_read_bytes += per_cpu_ptr(stats, i)->s.xs_read_bytes;
 		defer_relog += per_cpu_ptr(stats, i)->s.defer_relog;
+		pg_alloc += per_cpu_ptr(stats, i)->s.xs_buf_page_alloc;
+		pg_free += per_cpu_ptr(stats, i)->s.xs_buf_page_free;
+		kbb_alloc += per_cpu_ptr(stats, i)->s.xs_buf_kbb_alloc;
+		kbb_free += per_cpu_ptr(stats, i)->s.xs_buf_kbb_free;
+		vbb_alloc += per_cpu_ptr(stats, i)->s.xs_buf_vbb_alloc;
+		vbb_free += per_cpu_ptr(stats, i)->s.xs_buf_vbb_free;
 	}
 
 	len += scnprintf(buf + len, PATH_MAX-len, "xpc %llu %llu %llu\n",
@@ -89,6 +101,10 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
 #else
 		0);
 #endif
+	len += scnprintf(buf + len, PATH_MAX-len,
+			 "cache %llu %llu %llu %llu %llu %llu\n",
+			 pg_alloc, pg_free, kbb_alloc, kbb_free,
+			 vbb_alloc, vbb_free);
 
 	return len;
 }
diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h
index 15ba1abcf253..5e186880d8d0 100644
--- a/fs/xfs/xfs_stats.h
+++ b/fs/xfs/xfs_stats.h
@@ -143,6 +143,14 @@ struct __xfsstats {
 	uint64_t		xs_write_bytes;
 	uint64_t		xs_read_bytes;
 	uint64_t		defer_relog;
+
+	/* number of pages/bbs allocated/freed in buffer cache */
+	uint64_t		xs_buf_page_alloc;
+	uint64_t		xs_buf_page_free;
+	uint64_t		xs_buf_kbb_alloc;
+	uint64_t		xs_buf_kbb_free;
+	uint64_t		xs_buf_vbb_alloc;
+	uint64_t		xs_buf_vbb_free;
 };
 
 #define	xfsstats_offset(f)	(offsetof(struct __xfsstats, f)/sizeof(uint32_t))
-- 
2.39.5 (Apple Git-154)





[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux