lkml.org 
[lkml]   [2023]   [Jul]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3/3] LoongArch: mm: Add unified function populate_kernel_pte
    Date
    Function pcpu_populate_pte and fixmap_pte are similar, they populate
    one page from kernel address space. And there is confusion between
    pgd and p4d in function fixmap_pte, such as pgd_none always returns
    zero. This patch adds unified function populate_kernel_pte and replaces
    pcpu_populate_pte and fixmap_pte.

    Signed-off-by: Bibo Mao <maobibo@loongson.cn>
    ---
    arch/loongarch/include/asm/pgalloc.h | 1 +
    arch/loongarch/kernel/numa.c | 40 +--------------------
    arch/loongarch/mm/init.c | 52 ++++++++++++++++------------
    3 files changed, 32 insertions(+), 61 deletions(-)

    diff --git a/arch/loongarch/include/asm/pgalloc.h b/arch/loongarch/include/asm/pgalloc.h
    index af1d1e4a6965..ca17b573dba6 100644
    --- a/arch/loongarch/include/asm/pgalloc.h
    +++ b/arch/loongarch/include/asm/pgalloc.h
    @@ -91,4 +91,5 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)

    #endif /* __PAGETABLE_PUD_FOLDED */

    +extern pte_t * __init populate_kernel_pte(unsigned long addr);
    #endif /* _ASM_PGALLOC_H */
    diff --git a/arch/loongarch/kernel/numa.c b/arch/loongarch/kernel/numa.c
    index 778e1c20bfb0..24a693b76873 100644
    --- a/arch/loongarch/kernel/numa.c
    +++ b/arch/loongarch/kernel/numa.c
    @@ -67,46 +67,8 @@ static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)

    void __init pcpu_populate_pte(unsigned long addr)
    {
    - pgd_t *pgd = pgd_offset_k(addr);
    - p4d_t *p4d = p4d_offset(pgd, addr);
    - pud_t *pud;
    - pmd_t *pmd;
    -
    - if (p4d_none(*p4d)) {
    - pud = memblock_alloc_raw(PAGE_SIZE, PAGE_SIZE);
    - if (!pud)
    - goto err_alloc;
    - p4d_populate(&init_mm, p4d, pud);
    -#ifndef __PAGETABLE_PUD_FOLDED
    - pud_init(pud);
    -#endif
    - }
    -
    - pud = pud_offset(p4d, addr);
    - if (pud_none(*pud)) {
    - pmd = memblock_alloc_raw(PAGE_SIZE, PAGE_SIZE);
    - if (!pmd)
    - goto err_alloc;
    - pud_populate(&init_mm, pud, pmd);
    -#ifndef __PAGETABLE_PMD_FOLDED
    - pmd_init(pmd);
    -#endif
    - }
    -
    - pmd = pmd_offset(pud, addr);
    - if (!pmd_present(*pmd)) {
    - pte_t *pte;
    -
    - pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
    - if (!pte)
    - goto err_alloc;
    - pmd_populate_kernel(&init_mm, pmd, pte);
    - }
    -
    + populate_kernel_pte(addr);
    return;
    -
    -err_alloc:
    - panic("%s: Failed to allocate memory\n", __func__);
    }

    void __init setup_per_cpu_areas(void)
    diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
    index 3b7d8129570b..6cd2948373ae 100644
    --- a/arch/loongarch/mm/init.c
    +++ b/arch/loongarch/mm/init.c
    @@ -191,46 +191,49 @@ void vmemmap_free(unsigned long start, unsigned long end, struct vmem_altmap *al
    #endif
    #endif

    -static pte_t *fixmap_pte(unsigned long addr)
    +pte_t * __init populate_kernel_pte(unsigned long addr)
    {
    - pgd_t *pgd;
    - p4d_t *p4d;
    + pgd_t *pgd = pgd_offset_k(addr);
    + p4d_t *p4d = p4d_offset(pgd, addr);
    pud_t *pud;
    pmd_t *pmd;

    - pgd = pgd_offset_k(addr);
    - p4d = p4d_offset(pgd, addr);
    -
    - if (pgd_none(*pgd)) {
    - pud_t *new __maybe_unused;
    -
    - new = memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
    - pgd_populate(&init_mm, pgd, new);
    + if (p4d_none(*p4d)) {
    + pud = memblock_alloc_raw(PAGE_SIZE, PAGE_SIZE);
    + if (!pud)
    + goto err_alloc;
    + p4d_populate(&init_mm, p4d, pud);
    #ifndef __PAGETABLE_PUD_FOLDED
    - pud_init(new);
    + pud_init(pud);
    #endif
    }

    pud = pud_offset(p4d, addr);
    if (pud_none(*pud)) {
    - pmd_t *new __maybe_unused;
    -
    - new = memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
    - pud_populate(&init_mm, pud, new);
    + pmd = memblock_alloc_raw(PAGE_SIZE, PAGE_SIZE);
    + if (!pmd)
    + goto err_alloc;
    + pud_populate(&init_mm, pud, pmd);
    #ifndef __PAGETABLE_PMD_FOLDED
    - pmd_init(new);
    + pmd_init(pmd);
    #endif
    }

    pmd = pmd_offset(pud, addr);
    - if (pmd_none(*pmd)) {
    - pte_t *new __maybe_unused;
    + if (!pmd_present(*pmd)) {
    + pte_t *pte;

    - new = memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
    - pmd_populate_kernel(&init_mm, pmd, new);
    + pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
    + if (!pte)
    + goto err_alloc;
    + pmd_populate_kernel(&init_mm, pmd, pte);
    }

    return pte_offset_kernel(pmd, addr);
    +
    +err_alloc:
    + panic("%s: Failed to allocate memory\n", __func__);
    + return NULL;
    }

    void __init __set_fixmap(enum fixed_addresses idx,
    @@ -241,7 +244,12 @@ void __init __set_fixmap(enum fixed_addresses idx,

    BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses);

    - ptep = fixmap_pte(addr);
    + /*
    + * Now only FIX_EARLYCON_MEM_BASE fixed map is used
    + * __set_fixmap must be called before mem_init since function
    + * populate_kernel_pte allocates memory with memblock_alloc method.
    + */
    + ptep = populate_kernel_pte(addr);
    if (!pte_none(*ptep)) {
    pte_ERROR(*ptep);
    return;
    --
    2.27.0
    \
     
     \ /
      Last update: 2023-07-12 05:16    [W:5.361 / U:0.892 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site