s390/topology: add drawer scheduling domain level
The z13 machine added a fourth level to the cpu topology information. The new top level is called drawer. A drawer contains two books, which used to be the top level. Adding this additional scheduling domain did show performance improvements for some workloads of up to 8%, while there don't seem to be any workloads impacted in a negative way. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:

committed by
Martin Schwidefsky

parent
a62247e1f5
commit
adac0f1e8c
@@ -34,7 +34,8 @@
|
||||
#define DIST_CORE 1
|
||||
#define DIST_MC 2
|
||||
#define DIST_BOOK 3
|
||||
#define DIST_MAX 4
|
||||
#define DIST_DRAWER 4
|
||||
#define DIST_MAX 5
|
||||
|
||||
/* Node distance reported to common code */
|
||||
#define EMU_NODE_DIST 10
|
||||
@@ -43,7 +44,7 @@
|
||||
#define NODE_ID_FREE -1
|
||||
|
||||
/* Different levels of toptree */
|
||||
enum toptree_level {CORE, MC, BOOK, NODE, TOPOLOGY};
|
||||
enum toptree_level {CORE, MC, BOOK, DRAWER, NODE, TOPOLOGY};
|
||||
|
||||
/* The two toptree IDs */
|
||||
enum {TOPTREE_ID_PHYS, TOPTREE_ID_NUMA};
|
||||
@@ -113,6 +114,14 @@ static int cores_free(struct toptree *tree)
|
||||
* Return node of core
|
||||
*/
|
||||
static struct toptree *core_node(struct toptree *core)
|
||||
{
|
||||
return core->parent->parent->parent->parent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return drawer of core
|
||||
*/
|
||||
static struct toptree *core_drawer(struct toptree *core)
|
||||
{
|
||||
return core->parent->parent->parent;
|
||||
}
|
||||
@@ -138,6 +147,8 @@ static struct toptree *core_mc(struct toptree *core)
|
||||
*/
|
||||
static int dist_core_to_core(struct toptree *core1, struct toptree *core2)
|
||||
{
|
||||
if (core_drawer(core1)->id != core_drawer(core2)->id)
|
||||
return DIST_DRAWER;
|
||||
if (core_book(core1)->id != core_book(core2)->id)
|
||||
return DIST_BOOK;
|
||||
if (core_mc(core1)->id != core_mc(core2)->id)
|
||||
@@ -262,6 +273,8 @@ static void toptree_to_numa_first(struct toptree *numa, struct toptree *phys)
|
||||
struct toptree *core;
|
||||
|
||||
/* Always try to move perfectly fitting structures first */
|
||||
move_level_to_numa(numa, phys, DRAWER, true);
|
||||
move_level_to_numa(numa, phys, DRAWER, false);
|
||||
move_level_to_numa(numa, phys, BOOK, true);
|
||||
move_level_to_numa(numa, phys, BOOK, false);
|
||||
move_level_to_numa(numa, phys, MC, true);
|
||||
@@ -335,7 +348,7 @@ static struct toptree *toptree_to_numa(struct toptree *phys)
|
||||
*/
|
||||
static struct toptree *toptree_from_topology(void)
|
||||
{
|
||||
struct toptree *phys, *node, *book, *mc, *core;
|
||||
struct toptree *phys, *node, *drawer, *book, *mc, *core;
|
||||
struct cpu_topology_s390 *top;
|
||||
int cpu;
|
||||
|
||||
@@ -344,10 +357,11 @@ static struct toptree *toptree_from_topology(void)
|
||||
for_each_online_cpu(cpu) {
|
||||
top = &per_cpu(cpu_topology, cpu);
|
||||
node = toptree_get_child(phys, 0);
|
||||
book = toptree_get_child(node, top->book_id);
|
||||
drawer = toptree_get_child(node, top->drawer_id);
|
||||
book = toptree_get_child(drawer, top->book_id);
|
||||
mc = toptree_get_child(book, top->socket_id);
|
||||
core = toptree_get_child(mc, top->core_id);
|
||||
if (!book || !mc || !core)
|
||||
if (!drawer || !book || !mc || !core)
|
||||
panic("NUMA emulation could not allocate memory");
|
||||
cpumask_set_cpu(cpu, &core->mask);
|
||||
toptree_update_mask(mc);
|
||||
@@ -368,6 +382,7 @@ static void topology_add_core(struct toptree *core)
|
||||
cpumask_copy(&top->thread_mask, &core->mask);
|
||||
cpumask_copy(&top->core_mask, &core_mc(core)->mask);
|
||||
cpumask_copy(&top->book_mask, &core_book(core)->mask);
|
||||
cpumask_copy(&top->drawer_mask, &core_drawer(core)->mask);
|
||||
cpumask_set_cpu(cpu, &node_to_cpumask_map[core_node(core)->id]);
|
||||
top->node_id = core_node(core)->id;
|
||||
}
|
||||
|
Reference in New Issue
Block a user