[PATCH 2/2] xfs: count folio alloc'd xfs_buf items in NR_KERNEL_MISC_RECLAIMABLE
Eric Sandeen <[email protected]>
| Newsgroups | org.kernel.vger.linux-xfs,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
xfs_buf allocations via xfs_buf_alloc_folio are actually reclaimable, but are not accounted for as such. NR_KERNEL_MISC_RECLAIMABLE seems made for this purpose, although AFAICT there are no users today. To achieve this, add a new flag _XBF_PAGES to track what we have allocated this way, increment the NR_KERNEL_MISC_RECLAIMABLE count when we do, and then do the reverse when they are freed. These allocations now show up under nr_kernel_misc_reclaimable in /proc/vmstat when allocations are active, which in turn makes MemAvailable more accurate in /proc/meminfo. Signed-off-by: Eric Sandeen <[email protected]> --- fs/xfs/xfs_buf.c | 16 +++++++++++++--- fs/xfs/xfs_buf.h | 2 ++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 2e00a33ebb62..0a853ec361d0 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -114,8 +114,15 @@ xfs_buf_free( vfree(bp->b_addr); else if (bp->b_flags & _XBF_KMEM) kfree(bp->b_addr); - else if (bp->b_addr) - folio_put(virt_to_folio(bp->b_addr)); + else if (bp->b_addr) { + struct folio *folio = virt_to_folio(bp->b_addr); + + if (bp->b_flags & _XBF_PAGES) + mod_node_page_state(folio_pgdat(folio), + NR_KERNEL_MISC_RECLAIMABLE, + -folio_nr_pages(folio)); + folio_put(folio); + } call_rcu(&bp->b_rcu, xfs_buf_free_callback); } @@ -132,6 +139,9 @@ xfs_buf_alloc_folio( if (!folio) return -ENOMEM; bp->b_addr = folio_address(folio); + bp->b_flags |= _XBF_PAGES; + mod_node_page_state(folio_pgdat(folio), NR_KERNEL_MISC_RECLAIMABLE, + folio_nr_pages(folio)); trace_xfs_buf_backing_folio(bp, _RET_IP_); return 0; } @@ -427,7 +437,7 @@ xfs_buf_find_lock( return -ENOENT; } ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0); - bp->b_flags &= _XBF_KMEM; + bp->b_flags &= (_XBF_PAGES | _XBF_KMEM); bp->b_ops = NULL; } return 0; diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 79cc9c3f0254..ba7bfafe67b6 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -38,6 +38,7 @@ struct xfs_buf; #define _XBF_LOGRECOVERY (1u << 18)/* log recovery buffer */ /* flags used only internally */ +#define _XBF_PAGES (1u << 20)/* backed by folio/page allocator */ #define _XBF_KMEM (1u << 21)/* backed by heap memory */ #define _XBF_DELWRI_Q (1u << 22)/* buffer on a delwri queue */ @@ -62,6 +63,7 @@ typedef unsigned int xfs_buf_flags_t; { XBF_STALE, "STALE" }, \ { XBF_WRITE_FAIL, "WRITE_FAIL" }, \ { _XBF_LOGRECOVERY, "LOG_RECOVERY" }, \ + { _XBF_PAGES, "PAGES" }, \ { _XBF_KMEM, "KMEM" }, \ { _XBF_DELWRI_Q, "DELWRI_Q" }, \ /* The following interface flags should never be set */ \ -- 2.55.0