alpha: switch from DISCONTIGMEM to SPARSEMEM
authorMike Rapoport <rppt@linux.ibm.com>
Tue, 15 Dec 2020 03:09:28 +0000 (19:09 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 15 Dec 2020 20:13:42 +0000 (12:13 -0800)
Patch series "arch, mm: deprecate DISCONTIGMEM", v2.

It's been a while since DISCONTIGMEM is generally considered deprecated,
but it is still used by four architectures.  This set replaces
DISCONTIGMEM with a different way to handle holes in the memory map and
marks DISCONTIGMEM configuration as BROKEN in Kconfigs of these
architectures with the intention to completely remove it in several
releases.

While for 64-bit alpha and ia64 the switch to SPARSEMEM is quite obvious
and was a matter of moving some bits around, for smaller 32-bit arc and
m68k SPARSEMEM is not necessarily the best thing to do.

On 32-bit machines SPARSEMEM would require large sections to make section
index fit in the page flags, but larger sections mean that more memory is
wasted for unused memory map.

Besides, pfn_to_page() and page_to_pfn() become less efficient, at least
on arc.

So I've decided to generalize arm's approach for freeing of unused parts
of the memory map with FLATMEM and enable it for both arc and m68k.  The
details are in the description of patches 10 (arc) and 13 (m68k).

This patch (of 13):

Enable SPARSEMEM support on alpha and deprecate DISCONTIGMEM.

The required changes are mostly around moving duplicated definitions of
page access and address conversion macros to a common place and making sure
they are available for all memory models.

The DISCONTINGMEM support is marked as BROKEN an will be removed in a
couple of releases.

Link: https://lkml.kernel.org/r/20201101170454.9567-1-rppt@kernel.org
Link: https://lkml.kernel.org/r/20201101170454.9567-2-rppt@kernel.org
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Greg Ungerer <gerg@linux-m68k.org>
Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Meelis Roos <mroos@linux.ee>
Cc: Michael Schmitz <schmitzmic@gmail.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/alpha/Kconfig
arch/alpha/include/asm/mmzone.h
arch/alpha/include/asm/page.h
arch/alpha/include/asm/pgtable.h
arch/alpha/include/asm/sparsemem.h [new file with mode: 0644]
arch/alpha/kernel/setup.c

index d6e9fc7..aedf5c2 100644 (file)
@@ -40,6 +40,7 @@ config ALPHA
        select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67
        select MMU_GATHER_NO_RANGE
        select SET_FS
+       select SPARSEMEM_EXTREME if SPARSEMEM
        help
          The Alpha is a 64-bit general-purpose processor designed and
          marketed by the Digital Equipment Corporation of blessed memory,
@@ -551,12 +552,19 @@ config NR_CPUS
 
 config ARCH_DISCONTIGMEM_ENABLE
        bool "Discontiguous Memory Support"
+       depends on BROKEN
        help
          Say Y to support efficient handling of discontiguous physical memory,
          for architectures which are either NUMA (Non-Uniform Memory Access)
          or have huge holes in the physical address space for other reasons.
          See <file:Documentation/vm/numa.rst> for more.
 
+config ARCH_SPARSEMEM_ENABLE
+       bool "Sparse Memory Support"
+       help
+         Say Y to support efficient handling of discontiguous physical memory,
+         for systems that have huge holes in the physical address space.
+
 config NUMA
        bool "NUMA Support (EXPERIMENTAL)"
        depends on DISCONTIGMEM && BROKEN
index 9b521c8..8664460 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef _ASM_MMZONE_H_
 #define _ASM_MMZONE_H_
 
+#ifdef CONFIG_DISCONTIGMEM
+
 #include <asm/smp.h>
 
 /*
@@ -45,8 +47,6 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
 }
 #endif
 
-#ifdef CONFIG_DISCONTIGMEM
-
 /*
  * Following are macros that each numa implementation must define.
  */
@@ -68,11 +68,6 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
 /* XXX: FIXME -- nyc */
 #define kern_addr_valid(kaddr) (0)
 
-#define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-
-#define pmd_page(pmd)          (pfn_to_page(pmd_val(pmd) >> 32))
-#define pte_pfn(pte)           (pte_val(pte) >> 32)
-
 #define mk_pte(page, pgprot)                                                \
 ({                                                                          \
        pte_t pte;                                                           \
@@ -95,16 +90,11 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
        __xx;                                                           \
 })
 
-#define page_to_pa(page)                                               \
-       (page_to_pfn(page) << PAGE_SHIFT)
-
 #define pfn_to_nid(pfn)                pa_to_nid(((u64)(pfn) << PAGE_SHIFT))
 #define pfn_valid(pfn)                                                 \
        (((pfn) - node_start_pfn(pfn_to_nid(pfn))) <                    \
         node_spanned_pages(pfn_to_nid(pfn)))                                   \
 
-#define virt_addr_valid(kaddr) pfn_valid((__pa(kaddr) >> PAGE_SHIFT))
-
 #endif /* CONFIG_DISCONTIGMEM */
 
 #endif /* _ASM_MMZONE_H_ */
index e241bd8..268f99b 100644 (file)
@@ -83,12 +83,13 @@ typedef struct page *pgtable_t;
 
 #define __pa(x)                        ((unsigned long) (x) - PAGE_OFFSET)
 #define __va(x)                        ((void *)((unsigned long) (x) + PAGE_OFFSET))
-#ifndef CONFIG_DISCONTIGMEM
+
 #define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_addr_valid(kaddr) pfn_valid((__pa(kaddr) >> PAGE_SHIFT))
 
+#ifdef CONFIG_FLATMEM
 #define pfn_valid(pfn)         ((pfn) < max_mapnr)
-#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
-#endif /* CONFIG_DISCONTIGMEM */
+#endif /* CONFIG_FLATMEM */
 
 #include <asm-generic/memory_model.h>
 #include <asm-generic/getorder.h>
index 660b14c..8d856c6 100644 (file)
@@ -203,10 +203,10 @@ extern unsigned long __zero_page(void);
  * Conversion functions:  convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
-#ifndef CONFIG_DISCONTIGMEM
-#define page_to_pa(page)       (((page) - mem_map) << PAGE_SHIFT)
-
+#define page_to_pa(page)       (page_to_pfn(page) << PAGE_SHIFT)
 #define pte_pfn(pte)   (pte_val(pte) >> 32)
+
+#ifndef CONFIG_DISCONTIGMEM
 #define pte_page(pte)  pfn_to_page(pte_pfn(pte))
 #define mk_pte(page, pgprot)                                           \
 ({                                                                     \
@@ -236,10 +236,8 @@ pmd_page_vaddr(pmd_t pmd)
        return ((pmd_val(pmd) & _PFN_MASK) >> (32-PAGE_SHIFT)) + PAGE_OFFSET;
 }
 
-#ifndef CONFIG_DISCONTIGMEM
-#define pmd_page(pmd)  (mem_map + ((pmd_val(pmd) & _PFN_MASK) >> 32))
-#define pud_page(pud)  (mem_map + ((pud_val(pud) & _PFN_MASK) >> 32))
-#endif
+#define pmd_page(pmd)  (pfn_to_page(pmd_val(pmd) >> 32))
+#define pud_page(pud)  (pfn_to_page(pud_val(pud) >> 32))
 
 extern inline unsigned long pud_page_vaddr(pud_t pgd)
 { return PAGE_OFFSET + ((pud_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
diff --git a/arch/alpha/include/asm/sparsemem.h b/arch/alpha/include/asm/sparsemem.h
new file mode 100644 (file)
index 0000000..a0820fd
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ALPHA_SPARSEMEM_H
+#define _ASM_ALPHA_SPARSEMEM_H
+
+#ifdef CONFIG_SPARSEMEM
+
+#define SECTION_SIZE_BITS      27
+
+/*
+ * According to "Alpha Architecture Reference Manual" physical
+ * addresses are at most 48 bits.
+ * https://download.majix.org/dec/alpha_arch_ref.pdf
+ */
+#define MAX_PHYSMEM_BITS       48
+
+#endif /* CONFIG_SPARSEMEM */
+
+#endif /* _ASM_ALPHA_SPARSEMEM_H */
index 916e42d..03dda3b 100644 (file)
@@ -648,6 +648,7 @@ setup_arch(char **cmdline_p)
        /* Find our memory.  */
        setup_memory(kernel_end);
        memblock_set_bottom_up(true);
+       sparse_init();
 
        /* First guess at cpu cache sizes.  Do this before init_arch.  */
        determine_cpu_caches(cpu->type);