Skip to content

Commit ad2c814

Browse files
JoonsooKimtorvalds
authored andcommitted
topology: add support for node_to_mem_node() to determine the fallback node
Anton noticed (http://www.spinics.net/lists/linux-mm/msg67489.html) that on ppc LPARs with memoryless nodes, a large amount of memory was consumed by slabs and was marked unreclaimable. He tracked it down to slab deactivations in the SLUB core when we allocate remotely, leading to poor efficiency always when memoryless nodes are present. After much discussion, Joonsoo provided a few patches that help significantly. They don't resolve the problem altogether: - memory hotplug still needs testing, that is when a memoryless node becomes memory-ful, we want to dtrt - there are other reasons for going off-node than memoryless nodes, e.g., fully exhausted local nodes Neither case is resolved with this series, but I don't think that should block their acceptance, as they can be explored/resolved with follow-on patches. The series consists of: [1/3] topology: add support for node_to_mem_node() to determine the fallback node [2/3] slub: fallback to node_to_mem_node() node if allocating on memoryless node - Joonsoo's patches to cache the nearest node with memory for each NUMA node [3/3] Partial revert of 81c9886 (""kthread: ensure locality of task_struct allocations") - At Tejun's request, keep the knowledge of memoryless node fallback to the allocator core. This patch (of 3): We need to determine the fallback node in slub allocator if the allocation target node is memoryless node. Without it, the SLUB wrongly select the node which has no memory and can't use a partial slab, because of node mismatch. Introduced function, node_to_mem_node(X), will return a node Y with memory that has the nearest distance. If X is memoryless node, it will return nearest distance node, but, if X is normal node, it will return itself. We will use this function in following patch to determine the fallback node. Signed-off-by: Joonsoo Kim <[email protected]> Signed-off-by: Nishanth Aravamudan <[email protected]> Cc: David Rientjes <[email protected]> Cc: Han Pingtian <[email protected]> Cc: Pekka Enberg <[email protected]> Cc: Paul Mackerras <[email protected]> Cc: Benjamin Herrenschmidt <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Anton Blanchard <[email protected]> Cc: Christoph Lameter <[email protected]> Cc: Wanpeng Li <[email protected]> Cc: Tejun Heo <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent c9e1613 commit ad2c814

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

include/linux/topology.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,20 @@ static inline int numa_node_id(void)
119119
* Use the accessor functions set_numa_mem(), numa_mem_id() and cpu_to_mem().
120120
*/
121121
DECLARE_PER_CPU(int, _numa_mem_);
122+
extern int _node_numa_mem_[MAX_NUMNODES];
122123

123124
#ifndef set_numa_mem
124125
static inline void set_numa_mem(int node)
125126
{
126127
this_cpu_write(_numa_mem_, node);
128+
_node_numa_mem_[numa_node_id()] = node;
129+
}
130+
#endif
131+
132+
#ifndef node_to_mem_node
133+
static inline int node_to_mem_node(int node)
134+
{
135+
return _node_numa_mem_[node];
127136
}
128137
#endif
129138

@@ -146,6 +155,7 @@ static inline int cpu_to_mem(int cpu)
146155
static inline void set_cpu_numa_mem(int cpu, int node)
147156
{
148157
per_cpu(_numa_mem_, cpu) = node;
158+
_node_numa_mem_[cpu_to_node(cpu)] = node;
149159
}
150160
#endif
151161

@@ -159,6 +169,13 @@ static inline int numa_mem_id(void)
159169
}
160170
#endif
161171

172+
#ifndef node_to_mem_node
173+
static inline int node_to_mem_node(int node)
174+
{
175+
return node;
176+
}
177+
#endif
178+
162179
#ifndef cpu_to_mem
163180
static inline int cpu_to_mem(int cpu)
164181
{

mm/page_alloc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ EXPORT_PER_CPU_SYMBOL(numa_node);
8585
*/
8686
DEFINE_PER_CPU(int, _numa_mem_); /* Kernel "local memory" node */
8787
EXPORT_PER_CPU_SYMBOL(_numa_mem_);
88+
int _node_numa_mem_[MAX_NUMNODES];
8889
#endif
8990

9091
/*

0 commit comments

Comments
 (0)