|
@@ -62,6 +62,17 @@ DEFINE_PER_CPU(int, numa_node);
|
|
|
EXPORT_PER_CPU_SYMBOL(numa_node);
|
|
|
#endif
|
|
|
|
|
|
+#ifdef CONFIG_HAVE_MEMORYLESS_NODES
|
|
|
+/*
|
|
|
+ * N.B., Do NOT reference the '_numa_mem_' per cpu variable directly.
|
|
|
+ * It will not be defined when CONFIG_HAVE_MEMORYLESS_NODES is not defined.
|
|
|
+ * Use the accessor functions set_numa_mem(), numa_mem_id() and cpu_to_mem()
|
|
|
+ * defined in <linux/topology.h>.
|
|
|
+ */
|
|
|
+DEFINE_PER_CPU(int, _numa_mem_); /* Kernel "local memory" node */
|
|
|
+EXPORT_PER_CPU_SYMBOL(_numa_mem_);
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* Array of node states.
|
|
|
*/
|
|
@@ -2861,6 +2872,24 @@ static void build_zonelist_cache(pg_data_t *pgdat)
|
|
|
zlc->z_to_n[z - zonelist->_zonerefs] = zonelist_node_idx(z);
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_HAVE_MEMORYLESS_NODES
|
|
|
+/*
|
|
|
+ * Return node id of node used for "local" allocations.
|
|
|
+ * I.e., first node id of first zone in arg node's generic zonelist.
|
|
|
+ * Used for initializing percpu 'numa_mem', which is used primarily
|
|
|
+ * for kernel allocations, so use GFP_KERNEL flags to locate zonelist.
|
|
|
+ */
|
|
|
+int local_memory_node(int node)
|
|
|
+{
|
|
|
+ struct zone *zone;
|
|
|
+
|
|
|
+ (void)first_zones_zonelist(node_zonelist(node, GFP_KERNEL),
|
|
|
+ gfp_zone(GFP_KERNEL),
|
|
|
+ NULL,
|
|
|
+ &zone);
|
|
|
+ return zone->node;
|
|
|
+}
|
|
|
+#endif
|
|
|
|
|
|
#else /* CONFIG_NUMA */
|
|
|
|
|
@@ -2975,9 +3004,23 @@ static __init_refok int __build_all_zonelists(void *data)
|
|
|
* needs the percpu allocator in order to allocate its pagesets
|
|
|
* (a chicken-egg dilemma).
|
|
|
*/
|
|
|
- for_each_possible_cpu(cpu)
|
|
|
+ for_each_possible_cpu(cpu) {
|
|
|
setup_pageset(&per_cpu(boot_pageset, cpu), 0);
|
|
|
|
|
|
+#ifdef CONFIG_HAVE_MEMORYLESS_NODES
|
|
|
+ /*
|
|
|
+ * We now know the "local memory node" for each node--
|
|
|
+ * i.e., the node of the first zone in the generic zonelist.
|
|
|
+ * Set up numa_mem percpu variable for on-line cpus. During
|
|
|
+ * boot, only the boot cpu should be on-line; we'll init the
|
|
|
+ * secondary cpus' numa_mem as they come on-line. During
|
|
|
+ * node/memory hotplug, we'll fixup all on-line cpus.
|
|
|
+ */
|
|
|
+ if (cpu_online(cpu))
|
|
|
+ set_cpu_numa_mem(cpu, local_memory_node(cpu_to_node(cpu)));
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|