[PATCH v4 10/16] WIP: fs: hugetlbfs: Refactor subpool getters and integrate with hugetlb_subpool API
Ackerley Tng via B4 Relay <[email protected]> Wed, 22 Jul 2026 16:41:18 -0700
| Newsgroups | org.kernel.vger.cgroups,org.kernel.feeds.b4-sent,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <20260722-hugetlb-alloc-failure-fixes-v4-10-88e8b81970dc@google.com> |
From: Ackerley Tng <[email protected]> Refactor the direct field accesses to spool->max_hpages, spool->min_hpages, and calculate subpool properties using getters inside mm/hugetlb_subpool.c. This will allow the definition of struct hugepage_subpool to be encapsulated and private to mm/hugetlb_subpool.c Signed-off-by: Ackerley Tng <[email protected]> --- fs/hugetlbfs/inode.c | 28 +++++++++------------------- mm/hugetlb_subpool.c | 39 ++++++++++++++++++++++++++++++++++++++- mm/hugetlb_subpool.h | 4 ++++ 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 86c21f8272470..b424afdedb3ee 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -1060,7 +1060,6 @@ static int hugetlbfs_show_options(struct seq_file *m, struct dentry *root) struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(root->d_sb); struct hugepage_subpool *spool = sbinfo->spool; unsigned long hpage_size = huge_page_size(sbinfo->hstate); - unsigned hpage_shift = huge_page_shift(sbinfo->hstate); char mod; if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID)) @@ -1082,12 +1081,13 @@ static int hugetlbfs_show_options(struct seq_file *m, struct dentry *root) } seq_printf(m, ",pagesize=%lu%c", hpage_size, mod); if (spool) { - if (spool->max_hpages != -1) - seq_printf(m, ",size=%llu", - (unsigned long long)spool->max_hpages << hpage_shift); - if (spool->min_hpages != -1) - seq_printf(m, ",min_size=%llu", - (unsigned long long)spool->min_hpages << hpage_shift); + unsigned long long max_size = hugepage_subpool_max_size(spool); + unsigned long long min_size = hugepage_subpool_min_size(spool); + + if (max_size != -1ULL) + seq_printf(m, ",size=%llu", max_size); + if (min_size != -1ULL) + seq_printf(m, ",min_size=%llu", min_size); } return 0; } @@ -1106,18 +1106,8 @@ static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf) /* If no limits set, just report 0 or -1 for max/free/used * blocks, like simple_statfs() */ if (sbinfo->spool) { - long free_pages; - - spin_lock_irq(&sbinfo->spool->lock); - buf->f_blocks = sbinfo->spool->max_hpages; - if (sbinfo->spool->max_hpages == -1) { - free_pages = -1; - } else { - free_pages = sbinfo->spool->max_hpages - - sbinfo->spool->used_hpages; - } - buf->f_bavail = buf->f_bfree = free_pages; - spin_unlock_irq(&sbinfo->spool->lock); + buf->f_blocks = hugepage_subpool_max_hpages(sbinfo->spool); + buf->f_bavail = buf->f_bfree = hugepage_subpool_free_hpages(sbinfo->spool); buf->f_files = sbinfo->max_inodes; buf->f_ffree = sbinfo->free_inodes; } diff --git a/mm/hugetlb_subpool.c b/mm/hugetlb_subpool.c index 6184860ed7374..ac0f9057b4921 100644 --- a/mm/hugetlb_subpool.c +++ b/mm/hugetlb_subpool.c @@ -12,7 +12,6 @@ #endif #include <linux/spinlock.h> #include <linux/bug.h> - #include "hugetlb_subpool.h" static inline bool subpool_is_free(struct hugepage_subpool *spool) @@ -38,6 +37,44 @@ static inline void unlock_or_release_subpool(struct hugepage_subpool *spool, } } +long hugepage_subpool_free_hpages(struct hugepage_subpool *spool) +{ + long free_pages; + + spin_lock_irq(&spool->lock); + if (spool->max_hpages == -1) + free_pages = -1; + else + free_pages = spool->max_hpages - spool->used_hpages; + spin_unlock_irq(&spool->lock); + + return free_pages; +} + +static unsigned int hugepage_subpool_hpage_shift(struct hugepage_subpool *spool) +{ + return huge_page_shift(spool->hstate); +} + +unsigned long long hugepage_subpool_max_size(struct hugepage_subpool *spool) +{ + if (spool->max_hpages == -1) + return -1ULL; + return (unsigned long long)spool->max_hpages << hugepage_subpool_hpage_shift(spool); +} + +unsigned long long hugepage_subpool_min_size(struct hugepage_subpool *spool) +{ + if (spool->min_hpages == -1) + return -1ULL; + return (unsigned long long)spool->min_hpages << hugepage_subpool_hpage_shift(spool); +} + +long hugepage_subpool_max_hpages(struct hugepage_subpool *spool) +{ + return spool->max_hpages; +} + struct hugepage_subpool *hugepage_new_subpool(struct hstate *h, long max_hpages, long min_hpages) { diff --git a/mm/hugetlb_subpool.h b/mm/hugetlb_subpool.h index be1f1cf012c9c..41d22239f2c3e 100644 --- a/mm/hugetlb_subpool.h +++ b/mm/hugetlb_subpool.h @@ -13,5 +13,9 @@ struct hugepage_subpool *hugepage_new_subpool(struct hstate *h, long max_hpages, void hugepage_put_subpool(struct hugepage_subpool *spool); long hugepage_subpool_get_pages(struct hugepage_subpool *spool, long delta); long hugepage_subpool_put_pages(struct hugepage_subpool *spool, long delta); +long hugepage_subpool_free_hpages(struct hugepage_subpool *spool); +long hugepage_subpool_max_hpages(struct hugepage_subpool *spool); +unsigned long long hugepage_subpool_max_size(struct hugepage_subpool *spool); +unsigned long long hugepage_subpool_min_size(struct hugepage_subpool *spool); #endif /* _MM_HUGETLB_SUBPOOL_H */ -- 2.55.0.229.g6434b31f56-goog