]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/s390/numa/mode_emu.c
Merge branch 'for-4.8/core' of git://git.kernel.dk/linux-block
[karo-tx-linux.git] / arch / s390 / numa / mode_emu.c
index 828d0695d0d4a703e22164bc2b6576c18bc4032a..fbc394e16b2cc60f7e8a733d4788566357d55cae 100644 (file)
@@ -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;
        }