On 9/8/26 8:50 PM, Kiryl Shutsemau wrote:
From: "Kiryl Shutsemau (Meta)" <[email protected]>
__madvise_collapse() turns THP off before each MADV_COLLAPSE, both to keep
khugepaged out of the range and to prove MADV_COLLAPSE ignores the setting.
It clears the global controls only, which is no longer enough. A per-order
control overrides them, and -s, which makes the cases fault in folios of
one order, leaves that order's control at "always". khugepaged then
collapses the very range the case is working on, and the case fails on a
collapse that was interfered with rather than refused.
Right. So I think the correct fix tag is b7f16963efe7 ("mm/khugepaged:
run khugepaged for all orders"), because before this commit, khugepaged
would not try to collapse this range since it only checked whether the
PMD order was suitable for collapse.
Clear the per-order controls too, setting them to "inherit" rather than
"never": khugepaged honours the global never and stays out, while
MADV_COLLAPSE on shmem still finds an order to build.
Fixes: 9f0704eae8a4 ("selftests/mm/khugepaged: enlighten for multi-size THP")
Assisted-by: LLM
Signed-off-by: Kiryl Shutsemau (Meta) <[email protected]>
---
tools/testing/selftests/mm/khugepaged.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/mm/khugepaged.c
b/tools/testing/selftests/mm/khugepaged.c
index 398430c33872..e9bc8fe8a1f8 100644
--- a/tools/testing/selftests/mm/khugepaged.c
+++ b/tools/testing/selftests/mm/khugepaged.c
@@ -533,8 +533,8 @@ static bool is_anon(struct mem_ops *ops)
static void __madvise_collapse(const char *msg, char *p, int nr_hpages,
struct mem_ops *ops, bool expect)
{
- int ret;
struct thp_settings settings = *thp_current_settings();
+ int ret, i;
ksft_print_msg("%s...", msg);
@@ -547,9 +547,16 @@ static void __madvise_collapse(const char *msg, char *p, int nr_hpages,
/*
* Prevent khugepaged interference and tests that MADV_COLLAPSE
* ignores /sys/kernel/mm/transparent_hugepage/enabled
+ *
+ * "inherit" rather than "never" so that MADV_COLLAPSE on shmem still
+ * finds an order to build.
*/
settings.thp_enabled = THP_NEVER;
settings.shmem_enabled = SHMEM_NEVER;
+ for (i = 0; i < NR_ORDERS; i++) {
+ settings.hugepages[i].enabled = THP_INHERIT;
+ settings.shmem_hugepages[i].enabled = SHMEM_INHERIT;
+ }
This looks like a workaround to me. Shouldn't we fix this in shmem
instead? Since MADV_COLLAPSE is supposed to ignore the THP setting, the
fix should be something like this?
diff --git a/mm/shmem.c b/mm/shmem.c
index c92ed17dbc4a..e0c0901c34a4 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2050,7 +2050,7 @@ unsigned long shmem_allowable_huge_orders(struct
inode *inode,
global_orders = shmem_huge_global_enabled(inode, index, write_end,
shmem_huge_force,
vma, vm_flags);
/* Tmpfs huge pages allocation */
- if (!vma || !vma_is_anon_shmem(vma))
+ if (!vma || !vma_is_anon_shmem(vma) || shmem_huge_force)
return global_orders;
/*