[PATCH v6 02/14] mm: shmem: shmem_getattr(): set blksize to highest supported THP order
From: Luiz Capitulino
Date: Thu Jul 23 2026 - 21:35:28 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>
Acked-by: Zi Yan <ziy@xxxxxxxxxx>
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 5071177059a9..19534e21b61f 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1287,6 +1287,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;
/* Fast-path hint; recalc under info->lock corrects any stale read. */
if (data_race(info->alloced - info->swapped != inode->i_mapping->nrpages))
@@ -1303,8 +1304,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.55.0