]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
LoongArch: Introduce the numa_memblks conversion
authorHuacai Chen <chenhuacai@loongson.cn>
Fri, 30 May 2025 13:45:43 +0000 (21:45 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Fri, 30 May 2025 13:45:43 +0000 (21:45 +0800)
Commit 87482708210ff3333a ("mm: introduce numa_memblks") has moved
numa_memblks from x86 to the generic code, but LoongArch was left out
of this conversion.

This patch introduces the generic numa_memblks for LoongArch.

In detail:
1. Enable NUMA_MEMBLKS (but disable NUMA_EMU) in Kconfig;
2. Use generic definition for numa_memblk and numa_meminfo;
3. Use generic implementation for numa_add_memblk() and its friends;
4. Use generic implementation for numa_set_distance() and its friends;
5. Use generic implementation for memory_add_physaddr_to_nid() and its
   friends.

Note: Disable NUMA_EMU because it needs more efforts and no obvious
demand now.

Tested-by: Binbin Zhou <zhoubinbin@loongson.cn>
Signed-off-by: Yuquan Wang <wangyuquan1236@phytium.com.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/Kconfig
arch/loongarch/include/asm/numa.h
arch/loongarch/include/asm/sparsemem.h
arch/loongarch/include/asm/topology.h
arch/loongarch/kernel/acpi.c
arch/loongarch/kernel/numa.c
arch/loongarch/mm/init.c
mm/Kconfig

index 0c356de91bc43f4a3060328d72019792eb679313..4b19f93379a15336e0d13626accf57a5884306a3 100644 (file)
@@ -189,6 +189,7 @@ config LOONGARCH
        select MODULES_USE_ELF_RELA if MODULES
        select NEED_PER_CPU_EMBED_FIRST_CHUNK
        select NEED_PER_CPU_PAGE_FIRST_CHUNK
+       select NUMA_MEMBLKS if NUMA
        select OF
        select OF_EARLY_FLATTREE
        select PCI
index b5f9de9f102e444bcb4e563bddc704f52f3a940e..bbf9f70bd25f45bf7edd042092890dfa5b066490 100644 (file)
@@ -22,20 +22,6 @@ extern int numa_off;
 extern s16 __cpuid_to_node[CONFIG_NR_CPUS];
 extern nodemask_t numa_nodes_parsed __initdata;
 
-struct numa_memblk {
-       u64                     start;
-       u64                     end;
-       int                     nid;
-};
-
-#define NR_NODE_MEMBLKS                (MAX_NUMNODES*2)
-struct numa_meminfo {
-       int                     nr_blks;
-       struct numa_memblk      blk[NR_NODE_MEMBLKS];
-};
-
-extern int __init numa_add_memblk(int nodeid, u64 start, u64 end);
-
 extern void __init early_numa_add_cpu(int cpuid, s16 node);
 extern void numa_add_cpu(unsigned int cpu);
 extern void numa_remove_cpu(unsigned int cpu);
index 8d4af6aff8a8f1e149f59b4a9b34b80bf7197db2..4501efac1a87611a81a4e5ecc082e8c29a3e2c46 100644 (file)
 #define VMEMMAP_SIZE   0       /* 1, For FLATMEM; 2, For SPARSEMEM without VMEMMAP. */
 #endif
 
-#ifdef CONFIG_MEMORY_HOTPLUG
-int memory_add_physaddr_to_nid(u64 addr);
-#define memory_add_physaddr_to_nid memory_add_physaddr_to_nid
-#endif
-
 #define INIT_MEMBLOCK_RESERVED_REGIONS (INIT_MEMBLOCK_REGIONS + NR_CPUS)
 
 #endif /* _LOONGARCH_SPARSEMEM_H */
index ab206678e47f490b7c2f392559ca69eb22bcd2f1..f06e7ff25bb7cbe14d79e91ee97b1afd78f13b44 100644 (file)
@@ -19,11 +19,8 @@ extern int pcibus_to_node(struct pci_bus *);
 
 #define cpumask_of_pcibus(bus) (cpu_online_mask)
 
-extern unsigned char node_distances[MAX_NUMNODES][MAX_NUMNODES];
-
-void numa_set_distance(int from, int to, int distance);
-
-#define node_distance(from, to)        (node_distances[(from)][(to)])
+int __node_distance(int from, int to);
+#define node_distance(from, to) __node_distance(from, to)
 
 #else
 #define pcibus_to_node(bus)    0
index fba4bb93e1bd3563d3e9cfeabafa1599da0d1370..a54cd6fd37964b5599a49066cabd7cfea47f54d5 100644 (file)
@@ -244,17 +244,6 @@ fdt_earlycon:
 
 #ifdef CONFIG_ACPI_NUMA
 
-void __init numa_set_distance(int from, int to, int distance)
-{
-       if ((u8)distance != distance || (from == to && distance != LOCAL_DISTANCE)) {
-               pr_warn_once("Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
-                               from, to, distance);
-               return;
-       }
-
-       node_distances[from][to] = distance;
-}
-
 /* Callback for Proximity Domain -> CPUID mapping */
 void __init
 acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
index 30a72fd528c0e7f99a1ddf8bd050f8815eb15f4d..d6e73e8f9c0b66554c10e6533742dc4e1d94ef8a 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/mmzone.h>
 #include <linux/export.h>
 #include <linux/nodemask.h>
+#include <linux/numa_memblks.h>
 #include <linux/swap.h>
 #include <linux/memblock.h>
 #include <linux/pfn.h>
 #include <asm/time.h>
 
 int numa_off;
-unsigned char node_distances[MAX_NUMNODES][MAX_NUMNODES];
-EXPORT_SYMBOL(node_distances);
-
-static struct numa_meminfo numa_meminfo;
 cpumask_t cpus_on_node[MAX_NUMNODES];
 cpumask_t phys_cpus_on_node[MAX_NUMNODES];
 EXPORT_SYMBOL(cpus_on_node);
@@ -43,8 +40,6 @@ s16 __cpuid_to_node[CONFIG_NR_CPUS] = {
 };
 EXPORT_SYMBOL(__cpuid_to_node);
 
-nodemask_t numa_nodes_parsed __initdata;
-
 #ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA
 unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
 EXPORT_SYMBOL(__per_cpu_offset);
@@ -145,48 +140,6 @@ void numa_remove_cpu(unsigned int cpu)
        cpumask_clear_cpu(cpu, &cpus_on_node[nid]);
 }
 
-static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
-                                    struct numa_meminfo *mi)
-{
-       /* ignore zero length blks */
-       if (start == end)
-               return 0;
-
-       /* whine about and ignore invalid blks */
-       if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
-               pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
-                          nid, start, end - 1);
-               return 0;
-       }
-
-       if (mi->nr_blks >= NR_NODE_MEMBLKS) {
-               pr_err("NUMA: too many memblk ranges\n");
-               return -EINVAL;
-       }
-
-       mi->blk[mi->nr_blks].start = PFN_ALIGN(start);
-       mi->blk[mi->nr_blks].end = PFN_ALIGN(end - PAGE_SIZE + 1);
-       mi->blk[mi->nr_blks].nid = nid;
-       mi->nr_blks++;
-       return 0;
-}
-
-/**
- * numa_add_memblk - Add one numa_memblk to numa_meminfo
- * @nid: NUMA node ID of the new memblk
- * @start: Start address of the new memblk
- * @end: End address of the new memblk
- *
- * Add a new memblk to the default numa_meminfo.
- *
- * RETURNS:
- * 0 on success, -errno on failure.
- */
-int __init numa_add_memblk(int nid, u64 start, u64 end)
-{
-       return numa_add_memblk_to(nid, start, end, &numa_meminfo);
-}
-
 static void __init node_mem_init(unsigned int node)
 {
        unsigned long start_pfn, end_pfn;
@@ -205,18 +158,6 @@ static void __init node_mem_init(unsigned int node)
 
 #ifdef CONFIG_ACPI_NUMA
 
-static void __init add_node_intersection(u32 node, u64 start, u64 size, u32 type)
-{
-       static unsigned long num_physpages;
-
-       num_physpages += (size >> PAGE_SHIFT);
-       pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx Bytes\n",
-               node, type, start, size);
-       pr_info("       start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
-               start >> PAGE_SHIFT, (start + size) >> PAGE_SHIFT, num_physpages);
-       memblock_set_node(start, size, &memblock.memory, node);
-}
-
 /*
  * add_numamem_region
  *
@@ -228,28 +169,21 @@ static void __init add_node_intersection(u32 node, u64 start, u64 size, u32 type
  */
 static void __init add_numamem_region(u64 start, u64 end, u32 type)
 {
-       u32 i;
-       u64 ofs = start;
+       u32 node = pa_to_nid(start);
+       u64 size = end - start;
+       static unsigned long num_physpages;
 
        if (start >= end) {
                pr_debug("Invalid region: %016llx-%016llx\n", start, end);
                return;
        }
 
-       for (i = 0; i < numa_meminfo.nr_blks; i++) {
-               struct numa_memblk *mb = &numa_meminfo.blk[i];
-
-               if (ofs > mb->end)
-                       continue;
-
-               if (end > mb->end) {
-                       add_node_intersection(mb->nid, ofs, mb->end - ofs, type);
-                       ofs = mb->end;
-               } else {
-                       add_node_intersection(mb->nid, ofs, end - ofs, type);
-                       break;
-               }
-       }
+       num_physpages += (size >> PAGE_SHIFT);
+       pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx Bytes\n",
+               node, type, start, size);
+       pr_info("       start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
+               start >> PAGE_SHIFT, end >> PAGE_SHIFT, num_physpages);
+       memblock_set_node(start, size, &memblock.memory, node);
 }
 
 static void __init init_node_memblock(void)
@@ -291,24 +225,6 @@ static void __init init_node_memblock(void)
        }
 }
 
-static void __init numa_default_distance(void)
-{
-       int row, col;
-
-       for (row = 0; row < MAX_NUMNODES; row++)
-               for (col = 0; col < MAX_NUMNODES; col++) {
-                       if (col == row)
-                               node_distances[row][col] = LOCAL_DISTANCE;
-                       else
-                               /* We assume that one node per package here!
-                                *
-                                * A SLIT should be used for multiple nodes
-                                * per package to override default setting.
-                                */
-                               node_distances[row][col] = REMOTE_DISTANCE;
-       }
-}
-
 /*
  * fake_numa_init() - For Non-ACPI systems
  * Return: 0 on success, -errno on failure.
@@ -333,11 +249,11 @@ int __init init_numa_memory(void)
        for (i = 0; i < NR_CPUS; i++)
                set_cpuid_to_node(i, NUMA_NO_NODE);
 
-       numa_default_distance();
+       numa_reset_distance();
        nodes_clear(numa_nodes_parsed);
        nodes_clear(node_possible_map);
        nodes_clear(node_online_map);
-       memset(&numa_meminfo, 0, sizeof(numa_meminfo));
+       WARN_ON(memblock_clear_hotplug(0, PHYS_ADDR_MAX));
 
        /* Parse SRAT and SLIT if provided by firmware. */
        ret = acpi_disabled ? fake_numa_init() : acpi_numa_init();
index 06f11d9e4ec113f545bf7e583ef7f671f01f0608..c3e4586a7975783b7eadbd6883c849d6446f8c8f 100644 (file)
@@ -106,14 +106,6 @@ void arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
                page += vmem_altmap_offset(altmap);
        __remove_pages(start_pfn, nr_pages, altmap);
 }
-
-#ifdef CONFIG_NUMA
-int memory_add_physaddr_to_nid(u64 start)
-{
-       return pa_to_nid(start);
-}
-EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
-#endif
 #endif
 
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
index e113f713b49387b6714672802de8addf2e2f693e..1472ce8a87849123114f20b7079be1b8cfe2a880 100644 (file)
@@ -1317,6 +1317,7 @@ config NUMA_MEMBLKS
 config NUMA_EMU
        bool "NUMA emulation"
        depends on NUMA_MEMBLKS
+       depends on X86 || GENERIC_ARCH_NUMA
        help
          Enable NUMA emulation. A flat machine will be split
          into virtual nodes when booted with "numa=fake=N", where N is the