[PATCH v5 02/14] mm: shmem: shmem_getattr(): set blksize to highest supported THP order
From: Luiz Capitulino
Date: Fri May 29 2026 - 11:20:57 EST
Today, shmem_getattr() sets stat->blksize to PMD size whenever
shmem_huge_global_enabled() returns non-zero. While this works fine
for the normal THP-enabled case as explained by Baolin in [1], this
has two problems:
1. Theoretically, when shmem is configured for within_size, this
could set blksize to PMD size even though the allocation may
be a smaller mTHP order
2. A future commit will allow shmem THP support to be enabled
even when the CPU doesn't support PMD-sized pages. We should
not allow blksize to be set to PMD size in this case
In order to fix #1 and prepare for #2, this commit sets blksize
to the size of the highest supported order returned by
shmem_huge_global_enabled().
[1] https://lore.kernel.org/linux-mm/6591a74c-7ef9-4614-9ae9-cb2fbed86ebf@xxxxxxxxxxxxxxxxx/
Suggested-by: Baolin Wang <baolin.wang@xxxxxxxxxxxxxxxxx>
Signed-off-by: Luiz Capitulino <luizcap@xxxxxxxxxx>
---
mm/shmem.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index 3b5dc21b323c..88bc0c292f1a 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1286,6 +1286,7 @@ static int shmem_getattr(struct mnt_idmap *idmap,
{
struct inode *inode = path->dentry->d_inode;
struct shmem_inode_info *info = SHMEM_I(inode);
+ unsigned int orders;
if (info->alloced - info->swapped != inode->i_mapping->nrpages)
shmem_recalc_inode(inode, 0, 0);
@@ -1301,8 +1302,9 @@ static int shmem_getattr(struct mnt_idmap *idmap,
STATX_ATTR_NODUMP);
generic_fillattr(idmap, request_mask, inode, stat);
- if (shmem_huge_global_enabled(inode, 0, 0, false, NULL, 0))
- stat->blksize = HPAGE_PMD_SIZE;
+ orders = shmem_huge_global_enabled(inode, 0, 0, false, NULL, 0);
+ if (orders)
+ stat->blksize = PAGE_SIZE << highest_order(orders);
if (request_mask & STATX_BTIME) {
stat->result_mask |= STATX_BTIME;
--
2.54.0