]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm/sparsemem: enable vmem_altmap support in vmemmap_populate_basepages()
authorAnshuman Khandual <anshuman.khandual@arm.com>
Fri, 7 Aug 2020 06:23:19 +0000 (23:23 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Aug 2020 18:33:27 +0000 (11:33 -0700)
Patch series "arm64: Enable vmemmap mapping from device memory", v4.

This series enables vmemmap backing memory allocation from device memory
ranges on arm64.  But before that, it enables vmemmap_populate_basepages()
and vmemmap_alloc_block_buf() to accommodate struct vmem_altmap based
alocation requests.

This patch (of 3):

vmemmap_populate_basepages() is used across platforms to allocate backing
memory for vmemmap mapping.  This is used as a standard default choice or
as a fallback when intended huge pages allocation fails.  This just
creates entire vmemmap mapping with base pages (PAGE_SIZE).

On arm64 platforms, vmemmap_populate_basepages() is called instead of the
platform specific vmemmap_populate() when ARM64_SWAPPER_USES_SECTION_MAPS
is not enabled as in case for ARM64_16K_PAGES and ARM64_64K_PAGES configs.

At present vmemmap_populate_basepages() does not support allocating from
driver defined struct vmem_altmap while trying to create vmemmap mapping
for a device memory range.  It prevents ARM64_16K_PAGES and
ARM64_64K_PAGES configs on arm64 from supporting device memory with
vmemap_altmap request.

This enables vmem_altmap support in vmemmap_populate_basepages() unlocking
device memory allocation for vmemap mapping on arm64 platforms with 16K or
64K base page configs.

Each architecture should evaluate and decide on subscribing device memory
based base page allocation through vmemmap_populate_basepages().  Hence
lets keep it disabled on all archs in order to preserve the existing
semantics.  A subsequent patch enables it on arm64.

Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Tested-by: Jia He <justin.he@arm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Acked-by: Will Deacon <will@kernel.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Mike Rapoport <rppt@linux.ibm.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Hsin-Yi Wang <hsinyi@chromium.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Steve Capper <steve.capper@arm.com>
Cc: Yu Zhao <yuzhao@google.com>
Link: http://lkml.kernel.org/r/1594004178-8861-1-git-send-email-anshuman.khandual@arm.com
Link: http://lkml.kernel.org/r/1594004178-8861-2-git-send-email-anshuman.khandual@arm.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/arm64/mm/mmu.c
arch/ia64/mm/discontig.c
arch/riscv/mm/init.c
arch/x86/mm/init_64.c
include/linux/mm.h
mm/sparse-vmemmap.c

index cafefb147a5ecd0c8fcd343884d12e77b768c355..a32ddd021fe9844b8b8f2d8f401e457abee8900a 100644 (file)
@@ -1070,7 +1070,7 @@ static void free_empty_tables(unsigned long addr, unsigned long end,
 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
                struct vmem_altmap *altmap)
 {
-       return vmemmap_populate_basepages(start, end, node);
+       return vmemmap_populate_basepages(start, end, node, NULL);
 }
 #else  /* !ARM64_SWAPPER_USES_SECTION_MAPS */
 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
index 37f8b6875ac902c0cdce4f83eed1df2b01e66387..2ba2127335a7abc99fe3b018691ed6db1feda0b0 100644 (file)
@@ -655,7 +655,7 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat)
 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
                struct vmem_altmap *altmap)
 {
-       return vmemmap_populate_basepages(start, end, node);
+       return vmemmap_populate_basepages(start, end, node, NULL);
 }
 
 void vmemmap_free(unsigned long start, unsigned long end,
index 79e9d55bdf1ac41a14e52e17ae06e94cc05f6259..416e520d07d393779d3318bce68edbb7b433b5e9 100644 (file)
@@ -554,6 +554,6 @@ void __init paging_init(void)
 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
                               struct vmem_altmap *altmap)
 {
-       return vmemmap_populate_basepages(start, end, node);
+       return vmemmap_populate_basepages(start, end, node, NULL);
 }
 #endif
index 3f4e29a78f2ba7ebba66e71302900961eded060a..1acc5627b21c229ad4eab08a427ef428adc020fa 100644 (file)
@@ -1545,7 +1545,7 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start,
                        vmemmap_verify((pte_t *)pmd, node, addr, next);
                        continue;
                }
-               if (vmemmap_populate_basepages(addr, next, node))
+               if (vmemmap_populate_basepages(addr, next, node, NULL))
                        return -ENOMEM;
        }
        return 0;
@@ -1557,7 +1557,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
        int err;
 
        if (end - start < PAGES_PER_SECTION * sizeof(struct page))
-               err = vmemmap_populate_basepages(start, end, node);
+               err = vmemmap_populate_basepages(start, end, node, NULL);
        else if (boot_cpu_has(X86_FEATURE_PSE))
                err = vmemmap_populate_hugepages(start, end, node, altmap);
        else if (altmap) {
@@ -1565,7 +1565,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
                                __func__);
                err = -ENOMEM;
        } else
-               err = vmemmap_populate_basepages(start, end, node);
+               err = vmemmap_populate_basepages(start, end, node, NULL);
        if (!err)
                sync_global_pgds(start, end - 1);
        return err;
index 1c34705503953219d6cf221daf75bd8ebbb84050..a7ff98738126b121e979429136cb1d90a321c0c7 100644 (file)
@@ -2978,14 +2978,15 @@ pgd_t *vmemmap_pgd_populate(unsigned long addr, int node);
 p4d_t *vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node);
 pud_t *vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node);
 pmd_t *vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node);
-pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node);
+pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node,
+                           struct vmem_altmap *altmap);
 void *vmemmap_alloc_block(unsigned long size, int node);
 struct vmem_altmap;
 void *vmemmap_alloc_block_buf(unsigned long size, int node);
 void *altmap_alloc_block_buf(unsigned long size, struct vmem_altmap *altmap);
 void vmemmap_verify(pte_t *, int, unsigned long, unsigned long);
 int vmemmap_populate_basepages(unsigned long start, unsigned long end,
-                              int node);
+                              int node, struct vmem_altmap *altmap);
 int vmemmap_populate(unsigned long start, unsigned long end, int node,
                struct vmem_altmap *altmap);
 void vmemmap_populate_print_last(void);
index 0db7738d76e9b0b2875aa74469a2b6fbf9587096..ceed10dec31e87d40f6a23b45c8f2d91213cd696 100644 (file)
@@ -139,12 +139,18 @@ void __meminit vmemmap_verify(pte_t *pte, int node,
                        start, end - 1);
 }
 
-pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node)
+pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node,
+                                      struct vmem_altmap *altmap)
 {
        pte_t *pte = pte_offset_kernel(pmd, addr);
        if (pte_none(*pte)) {
                pte_t entry;
-               void *p = vmemmap_alloc_block_buf(PAGE_SIZE, node);
+               void *p;
+
+               if (altmap)
+                       p = altmap_alloc_block_buf(PAGE_SIZE, altmap);
+               else
+                       p = vmemmap_alloc_block_buf(PAGE_SIZE, node);
                if (!p)
                        return NULL;
                entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL);
@@ -212,8 +218,8 @@ pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node)
        return pgd;
 }
 
-int __meminit vmemmap_populate_basepages(unsigned long start,
-                                        unsigned long end, int node)
+int __meminit vmemmap_populate_basepages(unsigned long start, unsigned long end,
+                                        int node, struct vmem_altmap *altmap)
 {
        unsigned long addr = start;
        pgd_t *pgd;
@@ -235,7 +241,7 @@ int __meminit vmemmap_populate_basepages(unsigned long start,
                pmd = vmemmap_pmd_populate(pud, addr, node);
                if (!pmd)
                        return -ENOMEM;
-               pte = vmemmap_pte_populate(pmd, addr, node);
+               pte = vmemmap_pte_populate(pmd, addr, node, altmap);
                if (!pte)
                        return -ENOMEM;
                vmemmap_verify(pte, node, addr, addr + PAGE_SIZE);