aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-07-03 19:11:00 -0400
committerTejun Heo <tj@kernel.org>2009-07-03 19:11:00 -0400
commita530b7958612bafe2027e21359083dba84f0b3b4 (patch)
treefecbfc0d23b7702a903e8b2539e04e6086ba4404 /include
parent2f39e637ea240efb74cf807d31c93a71a0b89174 (diff)
percpu: teach large page allocator about NUMA
Large page first chunk allocator is primarily used for NUMA machines; however, its NUMA handling is extremely simplistic. Regardless of their proximity, each cpu is put into separate large page just to return most of the allocated space back wasting large amount of vmalloc space and increasing cache footprint. This patch teachs NUMA details to large page allocator. Given processor proximity information, pcpu_lpage_build_unit_map() will find fitting cpu -> unit mapping in which cpus in LOCAL_DISTANCE share the same large page and not too much virtual address space is wasted. This greatly reduces the unit and thus chunk size and wastes much less address space for the first chunk. For example, on 4/4 NUMA machine, the original code occupied 16MB of virtual space for the first chunk while the new code only uses 4MB - one 2MB page for each node. [ Impact: much better space efficiency on NUMA machines ] Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Jan Beulich <JBeulich@novell.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: David Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/linux/percpu.h24
1 files changed, 22 insertions, 2 deletions
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index 1e0e8878dc2a..8ce91af4aa19 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -62,6 +62,7 @@ extern const int *pcpu_unit_map;
62typedef void * (*pcpu_fc_alloc_fn_t)(unsigned int cpu, size_t size); 62typedef void * (*pcpu_fc_alloc_fn_t)(unsigned int cpu, size_t size);
63typedef void (*pcpu_fc_free_fn_t)(void *ptr, size_t size); 63typedef void (*pcpu_fc_free_fn_t)(void *ptr, size_t size);
64typedef void (*pcpu_fc_populate_pte_fn_t)(unsigned long addr); 64typedef void (*pcpu_fc_populate_pte_fn_t)(unsigned long addr);
65typedef int (pcpu_fc_cpu_distance_fn_t)(unsigned int from, unsigned int to);
65typedef void (*pcpu_fc_map_fn_t)(void *ptr, size_t size, void *addr); 66typedef void (*pcpu_fc_map_fn_t)(void *ptr, size_t size, void *addr);
66 67
67extern size_t __init pcpu_setup_first_chunk( 68extern size_t __init pcpu_setup_first_chunk(
@@ -80,18 +81,37 @@ extern ssize_t __init pcpu_4k_first_chunk(
80 pcpu_fc_populate_pte_fn_t populate_pte_fn); 81 pcpu_fc_populate_pte_fn_t populate_pte_fn);
81 82
82#ifdef CONFIG_NEED_MULTIPLE_NODES 83#ifdef CONFIG_NEED_MULTIPLE_NODES
84extern int __init pcpu_lpage_build_unit_map(
85 size_t static_size, size_t reserved_size,
86 ssize_t *dyn_sizep, size_t *unit_sizep,
87 size_t lpage_size, int *unit_map,
88 pcpu_fc_cpu_distance_fn_t cpu_distance_fn);
89
83extern ssize_t __init pcpu_lpage_first_chunk( 90extern ssize_t __init pcpu_lpage_first_chunk(
84 size_t static_size, size_t reserved_size, 91 size_t static_size, size_t reserved_size,
85 ssize_t dyn_size, size_t lpage_size, 92 size_t dyn_size, size_t unit_size,
93 size_t lpage_size, const int *unit_map,
94 int nr_units,
86 pcpu_fc_alloc_fn_t alloc_fn, 95 pcpu_fc_alloc_fn_t alloc_fn,
87 pcpu_fc_free_fn_t free_fn, 96 pcpu_fc_free_fn_t free_fn,
88 pcpu_fc_map_fn_t map_fn); 97 pcpu_fc_map_fn_t map_fn);
89 98
90extern void *pcpu_lpage_remapped(void *kaddr); 99extern void *pcpu_lpage_remapped(void *kaddr);
91#else 100#else
101static inline int pcpu_lpage_build_unit_map(
102 size_t static_size, size_t reserved_size,
103 ssize_t *dyn_sizep, size_t *unit_sizep,
104 size_t lpage_size, int *unit_map,
105 pcpu_fc_cpu_distance_fn_t cpu_distance_fn)
106{
107 return -EINVAL;
108}
109
92static inline ssize_t __init pcpu_lpage_first_chunk( 110static inline ssize_t __init pcpu_lpage_first_chunk(
93 size_t static_size, size_t reserved_size, 111 size_t static_size, size_t reserved_size,
94 ssize_t dyn_size, size_t lpage_size, 112 size_t dyn_size, size_t unit_size,
113 size_t lpage_size, const int *unit_map,
114 int nr_units,
95 pcpu_fc_alloc_fn_t alloc_fn, 115 pcpu_fc_alloc_fn_t alloc_fn,
96 pcpu_fc_free_fn_t free_fn, 116 pcpu_fc_free_fn_t free_fn,
97 pcpu_fc_map_fn_t map_fn) 117 pcpu_fc_map_fn_t map_fn)