powerpc/mm/book3s: Split radix and hash MAX_PHYSMEM limit
authorAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Mon, 8 Jun 2020 07:09:04 +0000 (12:39 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 15 Sep 2020 12:13:22 +0000 (22:13 +1000)
MAX_PHYSMEM #define is used along with sparsemem to determine the SECTION_SHIFT
value. Powerpc also uses the same value to limit the max memory enabled on the
system. With 4K PAGE_SIZE and hash translation mode, we want to limit the max
memory enabled to 64TB due to page table size restrictions. However, with
radix translation, we don't have these restrictions. Hence split the radix
and hash MA_PHYSMEM limit and use different limit for each of them.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200608070904.387440-4-aneesh.kumar@linux.ibm.com
arch/powerpc/include/asm/book3s/64/hash-4k.h
arch/powerpc/include/asm/book3s/64/hash-64k.h
arch/powerpc/include/asm/book3s/64/mmu-hash.h
arch/powerpc/include/asm/book3s/64/mmu.h
arch/powerpc/include/asm/book3s/64/pgtable.h
arch/powerpc/include/asm/book3s/64/radix.h
arch/powerpc/kernel/prom.c
arch/powerpc/mm/book3s64/slb.c

index b3ca542f871ecdf190bc5e578aef15403b39eb35..b6ac4f86c87b44b619681a2c7909c4a3fa7f0f0b 100644 (file)
 #define REGION_SHIFT           (40)
 #define H_KERN_MAP_SIZE                (ASM_CONST(1) << REGION_SHIFT)
 
+/*
+ * Limits the linear mapping range
+ */
+#define H_MAX_PHYSMEM_BITS     46
+
 /*
  * Define the address range of the kernel non-linear virtual area (61TB)
  */
index f20de1149ebe6e7940d9fa19b839018d18a5627d..338e62fbea0bb1dc30f984d4168c853689315e03 100644 (file)
@@ -7,6 +7,19 @@
 #define H_PUD_INDEX_SIZE  10  // size: 8B << 10 = 8KB, maps 2^10 x 16GB = 16TB
 #define H_PGD_INDEX_SIZE   8  // size: 8B <<  8 = 2KB, maps 2^8  x 16TB =  4PB
 
+/*
+ * If we store section details in page->flags we can't increase the MAX_PHYSMEM_BITS
+ * if we increase SECTIONS_WIDTH we will not store node details in page->flags and
+ * page_to_nid does a page->section->node lookup
+ * Hence only increase for VMEMMAP. Further depending on SPARSEMEM_EXTREME reduce
+ * memory requirements with large number of sections.
+ * 51 bits is the max physical real address on POWER9
+ */
+#if defined(CONFIG_SPARSEMEM_VMEMMAP) && defined(CONFIG_SPARSEMEM_EXTREME)
+#define H_MAX_PHYSMEM_BITS     51
+#else
+#define H_MAX_PHYSMEM_BITS     46
+#endif
 
 /*
  * Each context is 512TB size. SLB miss for first context/default context
index 93d18da5e7ecab3992ad0ad3df64b3eefceaf618..683a9c7d1b030e6e8d4380a5581eb2e99b5d6e94 100644 (file)
@@ -577,8 +577,8 @@ extern void slb_set_size(u16 size);
  * For vmalloc and memmap, we use just one context with 512TB. With 64 byte
  * struct page size, we need ony 32 TB in memmap for 2PB (51 bits (MAX_PHYSMEM_BITS)).
  */
-#if (MAX_PHYSMEM_BITS > MAX_EA_BITS_PER_CONTEXT)
-#define MAX_KERNEL_CTX_CNT     (1UL << (MAX_PHYSMEM_BITS - MAX_EA_BITS_PER_CONTEXT))
+#if (H_MAX_PHYSMEM_BITS > MAX_EA_BITS_PER_CONTEXT)
+#define MAX_KERNEL_CTX_CNT     (1UL << (H_MAX_PHYSMEM_BITS - MAX_EA_BITS_PER_CONTEXT))
 #else
 #define MAX_KERNEL_CTX_CNT     1
 #endif
index b392384a3b15089c04eef26f61a73cd7cfef33bf..ddc414ab3c4d5e329d59cd442f8045d9928c6199 100644 (file)
@@ -27,21 +27,6 @@ struct mmu_psize_def {
 extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
 #endif /* __ASSEMBLY__ */
 
-/*
- * If we store section details in page->flags we can't increase the MAX_PHYSMEM_BITS
- * if we increase SECTIONS_WIDTH we will not store node details in page->flags and
- * page_to_nid does a page->section->node lookup
- * Hence only increase for VMEMMAP. Further depending on SPARSEMEM_EXTREME reduce
- * memory requirements with large number of sections.
- * 51 bits is the max physical real address on POWER9
- */
-#if defined(CONFIG_SPARSEMEM_VMEMMAP) && defined(CONFIG_SPARSEMEM_EXTREME) &&  \
-       defined(CONFIG_PPC_64K_PAGES)
-#define MAX_PHYSMEM_BITS 51
-#else
-#define MAX_PHYSMEM_BITS 46
-#endif
-
 /* 64-bit classic hash table MMU */
 #include <asm/book3s/64/mmu-hash.h>
 
index 495fc0ccb45318404567b474d44528824477ff33..76880c7066fa7888eb571bd293dfc7d57efb4677 100644 (file)
@@ -294,6 +294,13 @@ extern unsigned long pci_io_base;
 #include <asm/book3s/64/hash.h>
 #include <asm/book3s/64/radix.h>
 
+#if H_MAX_PHYSMEM_BITS > R_MAX_PHYSMEM_BITS
+#define  MAX_PHYSMEM_BITS      H_MAX_PHYSMEM_BITS
+#else
+#define  MAX_PHYSMEM_BITS      R_MAX_PHYSMEM_BITS
+#endif
+
+
 #ifdef CONFIG_PPC_64K_PAGES
 #include <asm/book3s/64/pgtable-64k.h>
 #else
index 0cba794c4fb88028d5fa0976975249e41cc48db5..c7813dc628fc93aa6fbf273c0d69cf8b5c3ae7b8 100644 (file)
  * +------------------------------+  Kernel linear (0xc.....)
  */
 
+
+/*
+ * If we store section details in page->flags we can't increase the MAX_PHYSMEM_BITS
+ * if we increase SECTIONS_WIDTH we will not store node details in page->flags and
+ * page_to_nid does a page->section->node lookup
+ * Hence only increase for VMEMMAP. Further depending on SPARSEMEM_EXTREME reduce
+ * memory requirements with large number of sections.
+ * 51 bits is the max physical real address on POWER9
+ */
+
+#if defined(CONFIG_SPARSEMEM_VMEMMAP) && defined(CONFIG_SPARSEMEM_EXTREME)
+#define R_MAX_PHYSMEM_BITS     51
+#else
+#define R_MAX_PHYSMEM_BITS     46
+#endif
+
 #define RADIX_KERN_VIRT_START  ASM_CONST(0xc008000000000000)
 /*
  * 49 =  MAX_EA_BITS_PER_CONTEXT (hash specific). To make sure we pick
index d8a2fb87ba0c48500496e8a9b9b4919276b2618b..c1545f22c077dff95f41e0dcaf7952682942543a 100644 (file)
@@ -776,6 +776,11 @@ void __init early_init_devtree(void *params)
        limit = ALIGN(memory_limit ?: memblock_phys_mem_size(), PAGE_SIZE);
        memblock_enforce_memory_limit(limit);
 
+#if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_4K_PAGES)
+       if (!early_radix_enabled())
+               memblock_cap_memory_range(0, 1UL << (H_MAX_PHYSMEM_BITS));
+#endif
+
        memblock_allow_resize();
        memblock_dump_all();
 
index 156c38f8951148ed0f395e4e529507186585888c..c30fcbfa0e326031656f517d066b653a0b86c122 100644 (file)
@@ -765,8 +765,8 @@ static long slb_allocate_kernel(unsigned long ea, unsigned long id)
 
        if (id == LINEAR_MAP_REGION_ID) {
 
-               /* We only support upto MAX_PHYSMEM_BITS */
-               if ((ea & EA_MASK) > (1UL << MAX_PHYSMEM_BITS))
+               /* We only support upto H_MAX_PHYSMEM_BITS */
+               if ((ea & EA_MASK) > (1UL << H_MAX_PHYSMEM_BITS))
                        return -EFAULT;
 
                flags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_linear_psize].sllp;