powerpc: prefer memblock APIs returning virtual address
authorMike Rapoport <rppt@linux.ibm.com>
Fri, 8 Mar 2019 00:30:48 +0000 (16:30 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Mar 2019 02:32:03 +0000 (18:32 -0800)
Patch series "memblock: simplify several early memory allocation", v4.

These patches simplify some of the early memory allocations by replacing
usage of older memblock APIs with newer and shinier ones.

Quite a few places in the arch/ code allocated memory using a memblock
API that returns a physical address of the allocated area, then
converted this physical address to a virtual one and then used memset(0)
to clear the allocated range.

More recent memblock APIs do all the three steps in one call and their
usage simplifies the code.

It's important to note that regardless of API used, the core allocation
is nearly identical for any set of memblock allocators: first it tries
to find a free memory with all the constraints specified by the caller
and then falls back to the allocation with some or all constraints
disabled.

The first three patches perform the conversion of call sites that have
exact requirements for the node and the possible memory range.

The fourth patch is a bit one-off as it simplifies openrisc's
implementation of pte_alloc_one_kernel(), and not only the memblock
usage.

The fifth patch takes care of simpler cases when the allocation can be
satisfied with a simple call to memblock_alloc().

The sixth patch removes one-liner wrappers for memblock_alloc on arm and
unicore32, as suggested by Christoph.

This patch (of 6):

There are a several places that allocate memory using memblock APIs that
return a physical address, convert the returned address to the virtual
address and frequently also memset(0) the allocated range.

Update these places to use memblock allocators already returning a
virtual address.  Use memblock functions that clear the allocated memory
instead of calling memset(0) where appropriate.

The calls to memblock_alloc_base() that were not followed by memset(0)
are replaced with memblock_alloc_try_nid_raw().  Since the latter does
not panic() when the allocation fails, the appropriate panic() calls are
added to the call sites.

Link: http://lkml.kernel.org/r/1546248566-14910-2-git-send-email-rppt@linux.ibm.com
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Guan Xuetao <gxt@pku.edu.cn>
Cc: Greentime Hu <green.hu@gmail.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Jonas Bonn <jonas@southpole.se>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Mark Salter <msalter@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Rich Felker <dalias@libc.org>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
Cc: Stafford Horne <shorne@gmail.com>
Cc: Vincent Chen <deanbo422@gmail.com>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/pgtable-book3e.c
arch/powerpc/mm/pgtable-book3s64.c
arch/powerpc/mm/pgtable-radix.c
arch/powerpc/platforms/pasemi/iommu.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/dart_iommu.c

index b8480127793dbc8f261e2254822336764741dacc..8c890c6557edea1c1335d3df1fab94685e06ec42 100644 (file)
@@ -28,7 +28,7 @@
 static void *__init alloc_paca_data(unsigned long size, unsigned long align,
                                unsigned long limit, int cpu)
 {
-       unsigned long pa;
+       void *ptr;
        int nid;
 
        /*
@@ -43,17 +43,15 @@ static void *__init alloc_paca_data(unsigned long size, unsigned long align,
                nid = early_cpu_to_node(cpu);
        }
 
-       pa = memblock_alloc_base_nid(size, align, limit, nid, MEMBLOCK_NONE);
-       if (!pa) {
-               pa = memblock_alloc_base(size, align, limit);
-               if (!pa)
-                       panic("cannot allocate paca data");
-       }
+       ptr = memblock_alloc_try_nid(size, align, MEMBLOCK_LOW_LIMIT,
+                                    limit, nid);
+       if (!ptr)
+               panic("cannot allocate paca data");
 
        if (cpu == boot_cpuid)
                memblock_set_bottom_up(false);
 
-       return __va(pa);
+       return ptr;
 }
 
 #ifdef CONFIG_PPC_PSERIES
@@ -119,7 +117,6 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, unsigned long limit)
        }
 
        s = alloc_paca_data(sizeof(*s), L1_CACHE_BYTES, limit, cpu);
-       memset(s, 0, sizeof(*s));
 
        s->persistent = cpu_to_be32(SLB_NUM_BOLTED);
        s->buffer_length = cpu_to_be32(sizeof(*s));
@@ -223,7 +220,6 @@ void __init allocate_paca(int cpu)
        paca = alloc_paca_data(sizeof(struct paca_struct), L1_CACHE_BYTES,
                                limit, cpu);
        paca_ptrs[cpu] = paca;
-       memset(paca, 0, sizeof(struct paca_struct));
 
        initialise_paca(paca, cpu);
 #ifdef CONFIG_PPC_PSERIES
index 236c1151a3a77057013313ed5da588673f5f3419..5de413ae3cd67034d1377732116e4f0ab6198fd6 100644 (file)
@@ -933,8 +933,9 @@ static void __ref init_fallback_flush(void)
         * hardware prefetch runoff. We don't have a recipe for load patterns to
         * reliably avoid the prefetcher.
         */
-       l1d_flush_fallback_area = __va(memblock_alloc_base(l1d_size * 2, l1d_size, limit));
-       memset(l1d_flush_fallback_area, 0, l1d_size * 2);
+       l1d_flush_fallback_area = memblock_alloc_try_nid(l1d_size * 2,
+                                               l1d_size, MEMBLOCK_LOW_LIMIT,
+                                               limit, NUMA_NO_NODE);
 
        for_each_possible_cpu(cpu) {
                struct paca_struct *paca = paca_ptrs[cpu];
index 0cc7fbc3bd1c76d3b786979332a059d303726555..bc6be44913d44959ff16a868f9050524389548bb 100644 (file)
@@ -908,9 +908,9 @@ static void __init htab_initialize(void)
 #ifdef CONFIG_DEBUG_PAGEALLOC
        if (debug_pagealloc_enabled()) {
                linear_map_hash_count = memblock_end_of_DRAM() >> PAGE_SHIFT;
-               linear_map_hash_slots = __va(memblock_alloc_base(
-                               linear_map_hash_count, 1, ppc64_rma_size));
-               memset(linear_map_hash_slots, 0, linear_map_hash_count);
+               linear_map_hash_slots = memblock_alloc_try_nid(
+                               linear_map_hash_count, 1, MEMBLOCK_LOW_LIMIT,
+                               ppc64_rma_size, NUMA_NO_NODE);
        }
 #endif /* CONFIG_DEBUG_PAGEALLOC */
 
index e0ccf36714b2330e2d93ff38d9ab443222a30b7e..53cbc7dc2df293e43e158d08b3b3cb2c3d804c89 100644 (file)
@@ -57,12 +57,8 @@ void vmemmap_remove_mapping(unsigned long start,
 
 static __ref void *early_alloc_pgtable(unsigned long size)
 {
-       void *pt;
-
-       pt = __va(memblock_alloc_base(size, size, __pa(MAX_DMA_ADDRESS)));
-       memset(pt, 0, size);
-
-       return pt;
+       return memblock_alloc_try_nid(size, size, MEMBLOCK_LOW_LIMIT,
+                                     __pa(MAX_DMA_ADDRESS), NUMA_NO_NODE);
 }
 
 /*
index e7da590c7a786f5325f17f7e1abc6cb112bebf80..92a3e4c39540ced19d68b65573ff2c572d93dbf9 100644 (file)
@@ -195,11 +195,8 @@ void __init mmu_partition_table_init(void)
        unsigned long ptcr;
 
        BUILD_BUG_ON_MSG((PATB_SIZE_SHIFT > 36), "Partition table size too large.");
-       partition_tb = __va(memblock_alloc_base(patb_size, patb_size,
-                                               MEMBLOCK_ALLOC_ANYWHERE));
-
        /* Initialize the Partition Table with no entries */
-       memset((void *)partition_tb, 0, patb_size);
+       partition_tb = memblock_alloc(patb_size, patb_size);
 
        /*
         * update partition table control register,
index dced3cd241c2920d68ae1cda6919a4195e840a85..e377684ac6ad40b960ada944e32015290053ffcf 100644 (file)
@@ -51,26 +51,15 @@ static int native_register_process_table(unsigned long base, unsigned long pg_sz
 static __ref void *early_alloc_pgtable(unsigned long size, int nid,
                        unsigned long region_start, unsigned long region_end)
 {
-       unsigned long pa = 0;
-       void *pt;
+       phys_addr_t min_addr = MEMBLOCK_LOW_LIMIT;
+       phys_addr_t max_addr = MEMBLOCK_ALLOC_ANYWHERE;
 
-       if (region_start || region_end) /* has region hint */
-               pa = memblock_alloc_range(size, size, region_start, region_end,
-                                               MEMBLOCK_NONE);
-       else if (nid != -1) /* has node hint */
-               pa = memblock_alloc_base_nid(size, size,
-                                               MEMBLOCK_ALLOC_ANYWHERE,
-                                               nid, MEMBLOCK_NONE);
+       if (region_start)
+               min_addr = region_start;
+       if (region_end)
+               max_addr = region_end;
 
-       if (!pa)
-               pa = memblock_alloc_base(size, size, MEMBLOCK_ALLOC_ANYWHERE);
-
-       BUG_ON(!pa);
-
-       pt = __va(pa);
-       memset(pt, 0, size);
-
-       return pt;
+       return memblock_alloc_try_nid(size, size, min_addr, max_addr, nid);
 }
 
 static int early_map_kernel_page(unsigned long ea, unsigned long pa,
index f2971522fb4aa842cb9128b5c7ccc46c6e8d47a5..f62930f839cad3d7d57a4abf3a545af9696ae483 100644 (file)
@@ -208,7 +208,9 @@ static int __init iob_init(struct device_node *dn)
        pr_debug(" -> %s\n", __func__);
 
        /* For 2G space, 8x64 pages (2^21 bytes) is max total l2 size */
-       iob_l2_base = (u32 *)__va(memblock_alloc_base(1UL<<21, 1UL<<21, 0x80000000));
+       iob_l2_base = memblock_alloc_try_nid_raw(1UL << 21, 1UL << 21,
+                                       MEMBLOCK_LOW_LIMIT, 0x80000000,
+                                       NUMA_NO_NODE);
 
        pr_info("IOBMAP L2 allocated at: %p\n", iob_l2_base);
 
@@ -269,4 +271,3 @@ void __init iommu_init_early_pasemi(void)
        pasemi_pci_controller_ops.dma_bus_setup = pci_dma_bus_setup_pasemi;
        set_pci_dma_ops(&dma_iommu_ops);
 }
-
index 41f62ca27c63563b8ef00db4cdd9af0bbb69628f..e4f0dfd4ae33458f6a4a9450b3df9c42c55a26c1 100644 (file)
@@ -130,8 +130,13 @@ static void __init fwnmi_init(void)
         * It will be used in real mode mce handler, hence it needs to be
         * below RMA.
         */
-       mce_data_buf = __va(memblock_alloc_base(RTAS_ERROR_LOG_MAX * nr_cpus,
-                                       RTAS_ERROR_LOG_MAX, ppc64_rma_size));
+       mce_data_buf = memblock_alloc_try_nid_raw(RTAS_ERROR_LOG_MAX * nr_cpus,
+                                       RTAS_ERROR_LOG_MAX, MEMBLOCK_LOW_LIMIT,
+                                       ppc64_rma_size, NUMA_NO_NODE);
+       if (!mce_data_buf)
+               panic("Failed to allocate %d bytes below %pa for MCE buffer\n",
+                     RTAS_ERROR_LOG_MAX * nr_cpus, &ppc64_rma_size);
+
        for_each_possible_cpu(i) {
                paca_ptrs[i]->mce_data_buf = mce_data_buf +
                                                (RTAS_ERROR_LOG_MAX * i);
@@ -140,8 +145,13 @@ static void __init fwnmi_init(void)
 #ifdef CONFIG_PPC_BOOK3S_64
        /* Allocate per cpu slb area to save old slb contents during MCE */
        size = sizeof(struct slb_entry) * mmu_slb_size * nr_cpus;
-       slb_ptr = __va(memblock_alloc_base(size, sizeof(struct slb_entry),
-                                          ppc64_rma_size));
+       slb_ptr = memblock_alloc_try_nid_raw(size, sizeof(struct slb_entry),
+                                       MEMBLOCK_LOW_LIMIT, ppc64_rma_size,
+                                       NUMA_NO_NODE);
+       if (!slb_ptr)
+               panic("Failed to allocate %zu bytes below %pa for slb area\n",
+                     size, &ppc64_rma_size);
+
        for_each_possible_cpu(i)
                paca_ptrs[i]->mce_faulty_slbs = slb_ptr + (mmu_slb_size * i);
 #endif
index a5b40d1460f1a007df88ff75e63356778d76345d..25bc25fe0d93f3f41354f7ea876aa698c3055e3b 100644 (file)
@@ -251,8 +251,11 @@ static void allocate_dart(void)
         * 16MB (1 << 24) alignment. We allocate a full 16Mb chuck since we
         * will blow up an entire large page anyway in the kernel mapping.
         */
-       dart_tablebase = __va(memblock_alloc_base(1UL<<24,
-                                                 1UL<<24, 0x80000000L));
+       dart_tablebase = memblock_alloc_try_nid_raw(SZ_16M, SZ_16M,
+                                       MEMBLOCK_LOW_LIMIT, SZ_2G,
+                                       NUMA_NO_NODE);
+       if (!dart_tablebase)
+               panic("Failed to allocate 16MB below 2GB for DART table\n");
 
        /* There is no point scanning the DART space for leaks*/
        kmemleak_no_scan((void *)dart_tablebase);