aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2015-08-05 05:23:53 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-08-07 03:57:38 -0400
commit7cde4910a5adcab62506eff49f4500053464fc8a (patch)
treee08f7692b733f4e9b57973d95ecda50795c0d981
parent854508c0d0bbcf2f80fa1f79af5cb9ce219b2e9c (diff)
s390/numa: make core to node mapping data dynamic
The core to node mapping data consumes about 2 KB bss data. To save memory for the non-NUMA case, make the data dynamic. In addition change the "core_to_node" array from "int" to "s32" which saves 1 KB also for the NUMA case. Suggested-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/numa/mode_emu.c68
1 files changed, 41 insertions, 27 deletions
diff --git a/arch/s390/numa/mode_emu.c b/arch/s390/numa/mode_emu.c
index 646cd94cff2f..7de4e2f780d7 100644
--- a/arch/s390/numa/mode_emu.c
+++ b/arch/s390/numa/mode_emu.c
@@ -23,6 +23,7 @@
23#include <linux/memblock.h> 23#include <linux/memblock.h>
24#include <linux/node.h> 24#include <linux/node.h>
25#include <linux/memory.h> 25#include <linux/memory.h>
26#include <linux/slab.h>
26#include <asm/smp.h> 27#include <asm/smp.h>
27#include <asm/topology.h> 28#include <asm/topology.h>
28#include "numa_mode.h" 29#include "numa_mode.h"
@@ -56,26 +57,24 @@ static unsigned long emu_size;
56 * Node to core pinning information updates are protected by 57 * Node to core pinning information updates are protected by
57 * "sched_domains_mutex". 58 * "sched_domains_mutex".
58 */ 59 */
59/* Pinned core to node mapping */ 60static struct {
60static int cores_to_node_id[CONFIG_NR_CPUS]; 61 s32 to_node_id[CONFIG_NR_CPUS]; /* Pinned core to node mapping */
61/* Total number of pinned cores */ 62 int total; /* Total number of pinned cores */
62static int cores_total; 63 int per_node_target; /* Cores per node without extra cores */
63/* Number of cores per node without extra cores */ 64 int per_node[MAX_NUMNODES]; /* Number of cores pinned to node */
64static int cores_per_node_target; 65} *emu_cores;
65/* Number of cores pinned to node */
66static int cores_per_node[MAX_NUMNODES];
67 66
68/* 67/*
69 * Pin a core to a node 68 * Pin a core to a node
70 */ 69 */
71static void pin_core_to_node(int core_id, int node_id) 70static void pin_core_to_node(int core_id, int node_id)
72{ 71{
73 if (cores_to_node_id[core_id] == NODE_ID_FREE) { 72 if (emu_cores->to_node_id[core_id] == NODE_ID_FREE) {
74 cores_per_node[node_id]++; 73 emu_cores->per_node[node_id]++;
75 cores_to_node_id[core_id] = node_id; 74 emu_cores->to_node_id[core_id] = node_id;
76 cores_total++; 75 emu_cores->total++;
77 } else { 76 } else {
78 WARN_ON(cores_to_node_id[core_id] != node_id); 77 WARN_ON(emu_cores->to_node_id[core_id] != node_id);
79 } 78 }
80} 79}
81 80
@@ -84,7 +83,7 @@ static void pin_core_to_node(int core_id, int node_id)
84 */ 83 */
85static int cores_pinned(struct toptree *node) 84static int cores_pinned(struct toptree *node)
86{ 85{
87 return cores_per_node[node->id]; 86 return emu_cores->per_node[node->id];
88} 87}
89 88
90/* 89/*
@@ -92,7 +91,7 @@ static int cores_pinned(struct toptree *node)
92 */ 91 */
93static int core_pinned_to_node_id(struct toptree *core) 92static int core_pinned_to_node_id(struct toptree *core)
94{ 93{
95 return cores_to_node_id[core->id]; 94 return emu_cores->to_node_id[core->id];
96} 95}
97 96
98/* 97/*
@@ -174,14 +173,15 @@ static void toptree_unify_tree(struct toptree *tree)
174 173
175/* 174/*
176 * Find the best/nearest node for a given core and ensure that no node 175 * Find the best/nearest node for a given core and ensure that no node
177 * gets more than "cores_per_node_target + extra" cores. 176 * gets more than "emu_cores->per_node_target + extra" cores.
178 */ 177 */
179static struct toptree *node_for_core(struct toptree *numa, struct toptree *core, 178static struct toptree *node_for_core(struct toptree *numa, struct toptree *core,
180 int extra) 179 int extra)
181{ 180{
182 struct toptree *node, *node_best = NULL; 181 struct toptree *node, *node_best = NULL;
183 int dist_cur, dist_best; 182 int dist_cur, dist_best, cores_target;
184 183
184 cores_target = emu_cores->per_node_target + extra;
185 dist_best = DIST_MAX; 185 dist_best = DIST_MAX;
186 node_best = NULL; 186 node_best = NULL;
187 toptree_for_each(node, numa, NODE) { 187 toptree_for_each(node, numa, NODE) {
@@ -191,7 +191,7 @@ static struct toptree *node_for_core(struct toptree *numa, struct toptree *core,
191 break; 191 break;
192 } 192 }
193 /* Skip nodes that already have enough cores */ 193 /* Skip nodes that already have enough cores */
194 if (cores_pinned(node) >= cores_per_node_target + extra) 194 if (cores_pinned(node) >= cores_target)
195 continue; 195 continue;
196 dist_cur = dist_node_to_core(node, core); 196 dist_cur = dist_node_to_core(node, core);
197 if (dist_cur < dist_best) { 197 if (dist_cur < dist_best) {
@@ -225,11 +225,11 @@ static void toptree_to_numa_single(struct toptree *numa, struct toptree *phys,
225static void move_level_to_numa_node(struct toptree *node, struct toptree *phys, 225static void move_level_to_numa_node(struct toptree *node, struct toptree *phys,
226 enum toptree_level level, bool perfect) 226 enum toptree_level level, bool perfect)
227{ 227{
228 int cores_free, cores_target = emu_cores->per_node_target;
228 struct toptree *cur, *tmp; 229 struct toptree *cur, *tmp;
229 int cores_free;
230 230
231 toptree_for_each_safe(cur, tmp, phys, level) { 231 toptree_for_each_safe(cur, tmp, phys, level) {
232 cores_free = cores_per_node_target - toptree_count(node, CORE); 232 cores_free = cores_target - toptree_count(node, CORE);
233 if (perfect) { 233 if (perfect) {
234 if (cores_free == toptree_count(cur, CORE)) 234 if (cores_free == toptree_count(cur, CORE))
235 toptree_move(cur, node); 235 toptree_move(cur, node);
@@ -292,6 +292,20 @@ fail:
292} 292}
293 293
294/* 294/*
295 * Allocate and initialize core to node mapping
296 */
297static void create_core_to_node_map(void)
298{
299 int i;
300
301 emu_cores = kzalloc(sizeof(*emu_cores), GFP_KERNEL);
302 if (emu_cores == NULL)
303 panic("Could not allocate cores to node memory");
304 for (i = 0; i < ARRAY_SIZE(emu_cores->to_node_id); i++)
305 emu_cores->to_node_id[i] = NODE_ID_FREE;
306}
307
308/*
295 * Move cores from physical topology into NUMA target topology 309 * Move cores from physical topology into NUMA target topology
296 * and try to keep as much of the physical topology as possible. 310 * and try to keep as much of the physical topology as possible.
297 */ 311 */
@@ -299,8 +313,10 @@ static struct toptree *toptree_to_numa(struct toptree *phys)
299{ 313{
300 static int first = 1; 314 static int first = 1;
301 struct toptree *numa; 315 struct toptree *numa;
316 int cores_total;
302 317
303 cores_per_node_target = (cores_total + cores_free(phys)) / emu_nodes; 318 cores_total = emu_cores->total + cores_free(phys);
319 emu_cores->per_node_target = cores_total / emu_nodes;
304 numa = toptree_new(TOPTREE_ID_NUMA, emu_nodes); 320 numa = toptree_new(TOPTREE_ID_NUMA, emu_nodes);
305 if (first) { 321 if (first) {
306 toptree_to_numa_first(numa, phys); 322 toptree_to_numa_first(numa, phys);
@@ -386,8 +402,8 @@ static void print_node_to_core_map(void)
386 printk(KERN_DEBUG "NUMA node to core mapping\n"); 402 printk(KERN_DEBUG "NUMA node to core mapping\n");
387 for (nid = 0; nid < emu_nodes; nid++) { 403 for (nid = 0; nid < emu_nodes; nid++) {
388 printk(KERN_DEBUG " node %3d: ", nid); 404 printk(KERN_DEBUG " node %3d: ", nid);
389 for (cid = 0; cid < ARRAY_SIZE(cores_to_node_id); cid++) { 405 for (cid = 0; cid < ARRAY_SIZE(emu_cores->to_node_id); cid++) {
390 if (cores_to_node_id[cid] == nid) 406 if (emu_cores->to_node_id[cid] == nid)
391 printk(KERN_CONT "%d ", cid); 407 printk(KERN_CONT "%d ", cid);
392 } 408 }
393 printk(KERN_CONT "\n"); 409 printk(KERN_CONT "\n");
@@ -404,6 +420,8 @@ static void emu_update_cpu_topology(void)
404{ 420{
405 struct toptree *phys, *numa; 421 struct toptree *phys, *numa;
406 422
423 if (emu_cores == NULL)
424 create_core_to_node_map();
407 phys = toptree_from_topology(); 425 phys = toptree_from_topology();
408 numa = toptree_to_numa(phys); 426 numa = toptree_to_numa(phys);
409 toptree_free(phys); 427 toptree_free(phys);
@@ -443,12 +461,8 @@ static int emu_setup_nodes_adjust(int nodes)
443 */ 461 */
444static void emu_setup(void) 462static void emu_setup(void)
445{ 463{
446 int i;
447
448 emu_size = emu_setup_size_adjust(emu_size); 464 emu_size = emu_setup_size_adjust(emu_size);
449 emu_nodes = emu_setup_nodes_adjust(emu_nodes); 465 emu_nodes = emu_setup_nodes_adjust(emu_nodes);
450 for (i = 0; i < ARRAY_SIZE(cores_to_node_id); i++)
451 cores_to_node_id[i] = NODE_ID_FREE;
452 pr_info("Creating %d nodes with memory stripe size %ld MB\n", 466 pr_info("Creating %d nodes with memory stripe size %ld MB\n",
453 emu_nodes, emu_size >> 20); 467 emu_nodes, emu_size >> 20);
454} 468}