Re: [linus:master] [atomic] 80047d84ee: WARNING:at_include/linux/instrumented.h:#__split_huge_pmd_locked
From: Sasha Levin
Date: Tue Nov 03 2026 - 08:22:08 EST
On Tue, Nov 03, 2026 at 01:26:47PM +0100, Peter Zijlstra wrote:
> The below 'fixes' it, but the question is of course, WTF are we using an
> on-stack pmd value for set_pmd().
The split fills in the new PTE table before installing it, and uses a
temporary pmd on the stack so pte_offset_map() can find the table:
pgtable = pgtable_trans_huge_withdraw(mm, pmd);
pmd_populate(mm, &_pmd, pgtable);
pte = pte_offset_map(&_pmd, haddr);
__split_huge_zero_page_pmd() does the same thing.
I tried the typedef change. It works, but gcc ends up realigning the
stack in a lot of pte/pmd code (126 more functions with Arnd's version
in a small config, 204 with yours), including handle_mm_fault(). Just
aligning the two locals seems simpler:
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index bd44d58e86845..b8faa6df9bb14 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3132,7 +3132,7 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma,
{
struct mm_struct *mm = vma->vm_mm;
pgtable_t pgtable;
- pmd_t _pmd, old_pmd;
+ pmd_t _pmd __aligned(sizeof(pmd_t)), old_pmd;
unsigned long addr;
pte_t *pte;
int i;
@@ -3180,7 +3180,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
struct folio *folio;
struct page *page;
pgtable_t pgtable;
- pmd_t old_pmd, _pmd;
+ pmd_t old_pmd, _pmd __aligned(sizeof(pmd_t));
bool soft_dirty, uffd_wp = false, young = false, write = false;
bool anon_exclusive = false, dirty = false;
unsigned long addr;
Tested in qemu, the warning is gone. I can send it properly if this
works for you.
--
Thanks,
Sasha