diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 08b349931ebc..431214b941ac 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -57,6 +57,22 @@ | |||
57 | #include <asm/div64.h> | 57 | #include <asm/div64.h> |
58 | #include "internal.h" | 58 | #include "internal.h" |
59 | 59 | ||
60 | #ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID | ||
61 | DEFINE_PER_CPU(int, numa_node); | ||
62 | EXPORT_PER_CPU_SYMBOL(numa_node); | ||
63 | #endif | ||
64 | |||
65 | #ifdef CONFIG_HAVE_MEMORYLESS_NODES | ||
66 | /* | ||
67 | * N.B., Do NOT reference the '_numa_mem_' per cpu variable directly. | ||
68 | * It will not be defined when CONFIG_HAVE_MEMORYLESS_NODES is not defined. | ||
69 | * Use the accessor functions set_numa_mem(), numa_mem_id() and cpu_to_mem() | ||
70 | * defined in <linux/topology.h>. | ||
71 | */ | ||
72 | DEFINE_PER_CPU(int, _numa_mem_); /* Kernel "local memory" node */ | ||
73 | EXPORT_PER_CPU_SYMBOL(_numa_mem_); | ||
74 | #endif | ||
75 | |||
60 | /* | 76 | /* |
61 | * Array of node states. | 77 | * Array of node states. |
62 | */ | 78 | */ |
@@ -2856,6 +2872,24 @@ static void build_zonelist_cache(pg_data_t *pgdat) | |||
2856 | zlc->z_to_n[z - zonelist->_zonerefs] = zonelist_node_idx(z); | 2872 | zlc->z_to_n[z - zonelist->_zonerefs] = zonelist_node_idx(z); |
2857 | } | 2873 | } |
2858 | 2874 | ||
2875 | #ifdef CONFIG_HAVE_MEMORYLESS_NODES | ||
2876 | /* | ||
2877 | * Return node id of node used for "local" allocations. | ||
2878 | * I.e., first node id of first zone in arg node's generic zonelist. | ||
2879 | * Used for initializing percpu 'numa_mem', which is used primarily | ||
2880 | * for kernel allocations, so use GFP_KERNEL flags to locate zonelist. | ||
2881 | */ | ||
2882 | int local_memory_node(int node) | ||
2883 | { | ||
2884 | struct zone *zone; | ||
2885 | |||
2886 | (void)first_zones_zonelist(node_zonelist(node, GFP_KERNEL), | ||
2887 | gfp_zone(GFP_KERNEL), | ||
2888 | NULL, | ||
2889 | &zone); | ||
2890 | return zone->node; | ||
2891 | } | ||
2892 | #endif | ||
2859 | 2893 | ||
2860 | #else /* CONFIG_NUMA */ | 2894 | #else /* CONFIG_NUMA */ |
2861 | 2895 | ||
@@ -2970,9 +3004,23 @@ static __init_refok int __build_all_zonelists(void *data) | |||
2970 | * needs the percpu allocator in order to allocate its pagesets | 3004 | * needs the percpu allocator in order to allocate its pagesets |
2971 | * (a chicken-egg dilemma). | 3005 | * (a chicken-egg dilemma). |
2972 | */ | 3006 | */ |
2973 | for_each_possible_cpu(cpu) | 3007 | for_each_possible_cpu(cpu) { |
2974 | setup_pageset(&per_cpu(boot_pageset, cpu), 0); | 3008 | setup_pageset(&per_cpu(boot_pageset, cpu), 0); |
2975 | 3009 | ||
3010 | #ifdef CONFIG_HAVE_MEMORYLESS_NODES | ||
3011 | /* | ||
3012 | * We now know the "local memory node" for each node-- | ||
3013 | * i.e., the node of the first zone in the generic zonelist. | ||
3014 | * Set up numa_mem percpu variable for on-line cpus. During | ||
3015 | * boot, only the boot cpu should be on-line; we'll init the | ||
3016 | * secondary cpus' numa_mem as they come on-line. During | ||
3017 | * node/memory hotplug, we'll fixup all on-line cpus. | ||
3018 | */ | ||
3019 | if (cpu_online(cpu)) | ||
3020 | set_cpu_numa_mem(cpu, local_memory_node(cpu_to_node(cpu))); | ||
3021 | #endif | ||
3022 | } | ||
3023 | |||
2976 | return 0; | 3024 | return 0; |
2977 | } | 3025 | } |
2978 | 3026 | ||