Skip to content

Commit c2ff2b7

Browse files
rppthdeller
authored andcommitted
parisc/mm: preallocate fixmap page tables at init
Christoph Biedl reported early OOM on recent kernels: swapper: page allocation failure: order:0, mode:0x100(__GFP_ZERO), nodemask=(null) CPU: 0 PID: 0 Comm: swapper Not tainted 6.3.0-rc4+ #16 Hardware name: 9000/785/C3600 Backtrace: [<10408594>] show_stack+0x48/0x5c [<10e152d8>] dump_stack_lvl+0x48/0x64 [<10e15318>] dump_stack+0x24/0x34 [<105cf7f8>] warn_alloc+0x10c/0x1c8 [<105d068c>] __alloc_pages+0xbbc/0xcf8 [<105d0e4c>] __get_free_pages+0x28/0x78 [<105ad10c>] __pte_alloc_kernel+0x30/0x98 [<10406934>] set_fixmap+0xec/0xf4 [<10411ad4>] patch_map.constprop.0+0xa8/0xdc [<10411bb0>] __patch_text_multiple+0xa8/0x208 [<10411d78>] patch_text+0x30/0x48 [<1041246c>] arch_jump_label_transform+0x90/0xcc [<1056f734>] jump_label_update+0xd4/0x184 [<1056fc9c>] static_key_enable_cpuslocked+0xc0/0x110 [<1056fd08>] static_key_enable+0x1c/0x2c [<1011362c>] init_mem_debugging_and_hardening+0xdc/0xf8 [<1010141c>] start_kernel+0x5f0/0xa98 [<10105da8>] start_parisc+0xb8/0xe4 Mem-Info: active_anon:0 inactive_anon:0 isolated_anon:0 active_file:0 inactive_file:0 isolated_file:0 unevictable:0 dirty:0 writeback:0 slab_reclaimable:0 slab_unreclaimable:0 mapped:0 shmem:0 pagetables:0 sec_pagetables:0 bounce:0 kernel_misc_reclaimable:0 free:0 free_pcp:0 free_cma:0 Node 0 active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB mapped:0kB dirty:0kB writeback:0kB shmem:0kB +writeback_tmp:0kB kernel_stack:0kB pagetables:0kB sec_pagetables:0kB all_unreclaimable? no Normal free:0kB boost:0kB min:0kB low:0kB high:0kB reserved_highatomic:0KB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB +present:1048576kB managed:1039360kB mlocked:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB lowmem_reserve[]: 0 0 Normal: 0*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 0kB 0 total pagecache pages 0 pages in swap cache Free swap = 0kB Total swap = 0kB 262144 pages RAM 0 pages HighMem/MovableOnly 2304 pages reserved Backtrace: [<10411d78>] patch_text+0x30/0x48 [<1041246c>] arch_jump_label_transform+0x90/0xcc [<1056f734>] jump_label_update+0xd4/0x184 [<1056fc9c>] static_key_enable_cpuslocked+0xc0/0x110 [<1056fd08>] static_key_enable+0x1c/0x2c [<1011362c>] init_mem_debugging_and_hardening+0xdc/0xf8 [<1010141c>] start_kernel+0x5f0/0xa98 [<10105da8>] start_parisc+0xb8/0xe4 Kernel Fault: Code=15 (Data TLB miss fault) at addr 0f7fe3c0 CPU: 0 PID: 0 Comm: swapper Not tainted 6.3.0-rc4+ #16 Hardware name: 9000/785/C3600 This happens because patching static key code temporarily maps it via fixmap and if it happens before page allocator is initialized set_fixmap() cannot allocate memory using pte_alloc_kernel(). Make sure that fixmap page tables are preallocated early so that pte_offset_kernel() in set_fixmap() never resorts to pte allocation. Signed-off-by: Mike Rapoport (IBM) <[email protected]> Acked-by: Vlastimil Babka <[email protected]> Signed-off-by: Helge Deller <[email protected]> Tested-by: Christoph Biedl <[email protected]> Tested-by: John David Anglin <[email protected]> Cc: <[email protected]> # v6.4+
1 parent 5d0c230 commit c2ff2b7

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

arch/parisc/mm/fixmap.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ void notrace set_fixmap(enum fixed_addresses idx, phys_addr_t phys)
1919
pmd_t *pmd = pmd_offset(pud, vaddr);
2020
pte_t *pte;
2121

22-
if (pmd_none(*pmd))
23-
pte = pte_alloc_kernel(pmd, vaddr);
24-
2522
pte = pte_offset_kernel(pmd, vaddr);
2623
set_pte_at(&init_mm, vaddr, pte, __mk_pte(phys, PAGE_KERNEL_RWX));
2724
flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE);

arch/parisc/mm/init.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,39 @@ static void __init gateway_init(void)
669669
PAGE_SIZE, PAGE_GATEWAY, 1);
670670
}
671671

672+
static void __init fixmap_init(void)
673+
{
674+
unsigned long addr = FIXMAP_START;
675+
unsigned long end = FIXMAP_START + FIXMAP_SIZE;
676+
pgd_t *pgd = pgd_offset_k(addr);
677+
p4d_t *p4d = p4d_offset(pgd, addr);
678+
pud_t *pud = pud_offset(p4d, addr);
679+
pmd_t *pmd;
680+
681+
BUILD_BUG_ON(FIXMAP_SIZE > PMD_SIZE);
682+
683+
#if CONFIG_PGTABLE_LEVELS == 3
684+
if (pud_none(*pud)) {
685+
pmd = memblock_alloc(PAGE_SIZE << PMD_TABLE_ORDER,
686+
PAGE_SIZE << PMD_TABLE_ORDER);
687+
if (!pmd)
688+
panic("fixmap: pmd allocation failed.\n");
689+
pud_populate(NULL, pud, pmd);
690+
}
691+
#endif
692+
693+
pmd = pmd_offset(pud, addr);
694+
do {
695+
pte_t *pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
696+
if (!pte)
697+
panic("fixmap: pte allocation failed.\n");
698+
699+
pmd_populate_kernel(&init_mm, pmd, pte);
700+
701+
addr += PAGE_SIZE;
702+
} while (addr < end);
703+
}
704+
672705
static void __init parisc_bootmem_free(void)
673706
{
674707
unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0, };
@@ -683,6 +716,7 @@ void __init paging_init(void)
683716
setup_bootmem();
684717
pagetable_init();
685718
gateway_init();
719+
fixmap_init();
686720
flush_cache_all_local(); /* start with known state */
687721
flush_tlb_all_local(NULL);
688722

0 commit comments

Comments
 (0)