[PATCH] sched: introduce child field in sched_domain
authorSiddha, Suresh B <suresh.b.siddha@intel.com>
Tue, 3 Oct 2006 08:14:08 +0000 (01:14 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 3 Oct 2006 15:04:06 +0000 (08:04 -0700)
Introduce the child field in sched_domain struct and use it in
sched_balance_self().

We will also use this field in cleaning up the sched group cpu_power
setup(done in a different patch) code.

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
Acked-by: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Paul Jackson <pj@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
include/asm-i386/topology.h
include/asm-ia64/topology.h
include/asm-mips/mach-ip27/topology.h
include/asm-powerpc/topology.h
include/asm-x86_64/topology.h
include/linux/sched.h
include/linux/topology.h
kernel/sched.c

index 6adbd9b..978d095 100644 (file)
@@ -74,6 +74,7 @@ static inline int node_to_first_cpu(int node)
 #define SD_NODE_INIT (struct sched_domain) {           \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 8,                    \
        .max_interval           = 32,                   \
index 937c212..a6e3856 100644 (file)
@@ -59,6 +59,7 @@ void build_cpu_to_node_map(void);
 #define SD_CPU_INIT (struct sched_domain) {            \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 1,                    \
        .max_interval           = 4,                    \
@@ -84,6 +85,7 @@ void build_cpu_to_node_map(void);
 #define SD_NODE_INIT (struct sched_domain) {           \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 8,                    \
        .max_interval           = 8*(min(num_online_cpus(), 32)), \
index 59d26b5..a13b715 100644 (file)
@@ -22,6 +22,7 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
 #define SD_NODE_INIT (struct sched_domain) {           \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 8,                    \
        .max_interval           = 32,                   \
index bbc3844..8f7ee16 100644 (file)
@@ -43,6 +43,7 @@ extern int pcibus_to_node(struct pci_bus *bus);
 #define SD_NODE_INIT (struct sched_domain) {           \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 8,                    \
        .max_interval           = 32,                   \
index 6e7a2e9..5c8f492 100644 (file)
@@ -31,6 +31,7 @@ extern int __node_distance(int, int);
 #define SD_NODE_INIT (struct sched_domain) {           \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 8,                    \
        .max_interval           = 32,                   \
index 3853023..8e26c90 100644 (file)
@@ -644,6 +644,7 @@ struct sched_group {
 struct sched_domain {
        /* These fields must be setup */
        struct sched_domain *parent;    /* top domain must be null terminated */
+       struct sched_domain *child;     /* bottom domain must be null terminated */
        struct sched_group *groups;     /* the balancing groups of the domain */
        cpumask_t span;                 /* span of all CPUs in this domain */
        unsigned long min_interval;     /* Minimum balance interval ms */
index ec1eca8..486bec2 100644 (file)
@@ -89,6 +89,7 @@
 #define SD_SIBLING_INIT (struct sched_domain) {                \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 1,                    \
        .max_interval           = 2,                    \
 #define SD_CPU_INIT (struct sched_domain) {            \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 1,                    \
        .max_interval           = 4,                    \
 #define SD_ALLNODES_INIT (struct sched_domain) {       \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 64,                   \
        .max_interval           = 64*num_online_cpus(), \
index 6d7bf55..0feeacb 100644 (file)
@@ -1286,21 +1286,29 @@ static int sched_balance_self(int cpu, int flag)
        while (sd) {
                cpumask_t span;
                struct sched_group *group;
-               int new_cpu;
-               int weight;
+               int new_cpu, weight;
+
+               if (!(sd->flags & flag)) {
+                       sd = sd->child;
+                       continue;
+               }
 
                span = sd->span;
                group = find_idlest_group(sd, t, cpu);
-               if (!group)
-                       goto nextlevel;
+               if (!group) {
+                       sd = sd->child;
+                       continue;
+               }
 
                new_cpu = find_idlest_cpu(group, t, cpu);
-               if (new_cpu == -1 || new_cpu == cpu)
-                       goto nextlevel;
+               if (new_cpu == -1 || new_cpu == cpu) {
+                       /* Now try balancing at a lower domain level of cpu */
+                       sd = sd->child;
+                       continue;
+               }
 
-               /* Now try balancing at a lower domain level */
+               /* Now try balancing at a lower domain level of new_cpu */
                cpu = new_cpu;
-nextlevel:
                sd = NULL;
                weight = cpus_weight(span);
                for_each_domain(cpu, tmp) {
@@ -5448,12 +5456,18 @@ static void cpu_attach_domain(struct sched_domain *sd, int cpu)
                struct sched_domain *parent = tmp->parent;
                if (!parent)
                        break;
-               if (sd_parent_degenerate(tmp, parent))
+               if (sd_parent_degenerate(tmp, parent)) {
                        tmp->parent = parent->parent;
+                       if (parent->parent)
+                               parent->parent->child = tmp;
+               }
        }
 
-       if (sd && sd_degenerate(sd))
+       if (sd && sd_degenerate(sd)) {
                sd = sd->parent;
+               if (sd)
+                       sd->child = NULL;
+       }
 
        sched_domain_debug(sd, cpu);
 
@@ -6288,6 +6302,8 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                *sd = SD_NODE_INIT;
                sd->span = sched_domain_node_span(cpu_to_node(i));
                sd->parent = p;
+               if (p)
+                       p->child = sd;
                cpus_and(sd->span, sd->span, *cpu_map);
 #endif
 
@@ -6297,6 +6313,8 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                *sd = SD_CPU_INIT;
                sd->span = nodemask;
                sd->parent = p;
+               if (p)
+                       p->child = sd;
                sd->groups = &sched_group_phys[group];
 
 #ifdef CONFIG_SCHED_MC
@@ -6307,6 +6325,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                sd->span = cpu_coregroup_map(i);
                cpus_and(sd->span, sd->span, *cpu_map);
                sd->parent = p;
+               p->child = sd;
                sd->groups = &sched_group_core[group];
 #endif
 
@@ -6318,6 +6337,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                sd->span = cpu_sibling_map[i];
                cpus_and(sd->span, sd->span, *cpu_map);
                sd->parent = p;
+               p->child = sd;
                sd->groups = &sched_group_cpus[group];
 #endif
        }