]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - kernel/sched.c
sched: style cleanup, #2
[karo-tx-linux.git] / kernel / sched.c
index 36bd8ff2a669b4169a7e496cb3fa26b4183c0d8c..23b9925a1dfb3971ff8b30637b1ee0b763b4a764 100644 (file)
@@ -96,10 +96,9 @@ unsigned long long __attribute__((weak)) sched_clock(void)
 #define MAX_USER_PRIO          (USER_PRIO(MAX_PRIO))
 
 /*
- * Some helpers for converting nanosecond timing to jiffy resolution
+ * Helpers for converting nanosecond timing to jiffy resolution
  */
 #define NS_TO_JIFFIES(TIME)    ((unsigned long)(TIME) / (NSEC_PER_SEC / HZ))
-#define JIFFIES_TO_NS(TIME)    ((TIME) * (NSEC_PER_SEC / HZ))
 
 #define NICE_0_LOAD            SCHED_LOAD_SCALE
 #define NICE_0_SHIFT           SCHED_LOAD_SHIFT
@@ -236,17 +235,17 @@ static void set_se_shares(struct sched_entity *se, unsigned long shares);
  *     Every task in system belong to this group at bootup.
  */
 struct task_group init_task_group = {
-       .se     = init_sched_entity_p,
+       .se     = init_sched_entity_p,
        .cfs_rq = init_cfs_rq_p,
 };
 
 #ifdef CONFIG_FAIR_USER_SCHED
-# define INIT_TASK_GROUP_LOAD  2*NICE_0_LOAD
+# define INIT_TASK_GROUP_LOAD  (2*NICE_0_LOAD)
 #else
 # define INIT_TASK_GROUP_LOAD  NICE_0_LOAD
 #endif
 
-#define MIN_GROUP_SHARES       2
+#define MIN_GROUP_SHARES       2
 
 static int init_task_group_load = INIT_TASK_GROUP_LOAD;
 
@@ -349,6 +348,35 @@ struct rt_rq {
        int overloaded;
 };
 
+#ifdef CONFIG_SMP
+
+/*
+ * We add the notion of a root-domain which will be used to define per-domain
+ * variables. Each exclusive cpuset essentially defines an island domain by
+ * fully partitioning the member cpus from any other cpuset. Whenever a new
+ * exclusive cpuset is created, we also create and attach a new root-domain
+ * object.
+ *
+ * By default the system creates a single root-domain with all cpus as
+ * members (mimicking the global state we have today).
+ */
+struct root_domain {
+       atomic_t refcount;
+       cpumask_t span;
+       cpumask_t online;
+
+       /*
+        * The "RT overload" flag: it gets set if a CPU has more than
+        * one runnable RT task.
+        */
+       cpumask_t rto_mask;
+       atomic_t rto_count;
+};
+
+static struct root_domain def_root_domain;
+
+#endif
+
 /*
  * This is the main, per-CPU runqueue data structure.
  *
@@ -406,6 +434,7 @@ struct rq {
        atomic_t nr_iowait;
 
 #ifdef CONFIG_SMP
+       struct root_domain *rd;
        struct sched_domain *sd;
 
        /* For active balancing */
@@ -5037,7 +5066,7 @@ int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask)
        if (p->sched_class->set_cpus_allowed)
                p->sched_class->set_cpus_allowed(p, &new_mask);
        else {
-               p->cpus_allowed    = new_mask;
+               p->cpus_allowed = new_mask;
                p->nr_cpus_allowed = cpus_weight(new_mask);
        }
 
@@ -5550,6 +5579,15 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
        case CPU_ONLINE_FROZEN:
                /* Strictly unnecessary, as first user will wake it. */
                wake_up_process(cpu_rq(cpu)->migration_thread);
+
+               /* Update our root-domain */
+               rq = cpu_rq(cpu);
+               spin_lock_irqsave(&rq->lock, flags);
+               if (rq->rd) {
+                       BUG_ON(!cpu_isset(cpu, rq->rd->span));
+                       cpu_set(cpu, rq->rd->online);
+               }
+               spin_unlock_irqrestore(&rq->lock, flags);
                break;
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -5600,6 +5638,17 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
                }
                spin_unlock_irq(&rq->lock);
                break;
+
+       case CPU_DOWN_PREPARE:
+               /* Update our root-domain */
+               rq = cpu_rq(cpu);
+               spin_lock_irqsave(&rq->lock, flags);
+               if (rq->rd) {
+                       BUG_ON(!cpu_isset(cpu, rq->rd->span));
+                       cpu_clear(cpu, rq->rd->online);
+               }
+               spin_unlock_irqrestore(&rq->lock, flags);
+               break;
 #endif
        }
        return NOTIFY_OK;
@@ -5788,11 +5837,71 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent)
        return 1;
 }
 
+static void rq_attach_root(struct rq *rq, struct root_domain *rd)
+{
+       unsigned long flags;
+       const struct sched_class *class;
+
+       spin_lock_irqsave(&rq->lock, flags);
+
+       if (rq->rd) {
+               struct root_domain *old_rd = rq->rd;
+
+               for (class = sched_class_highest; class; class = class->next) {
+                       if (class->leave_domain)
+                               class->leave_domain(rq);
+               }
+
+               if (atomic_dec_and_test(&old_rd->refcount))
+                       kfree(old_rd);
+       }
+
+       atomic_inc(&rd->refcount);
+       rq->rd = rd;
+
+       for (class = sched_class_highest; class; class = class->next) {
+               if (class->join_domain)
+                       class->join_domain(rq);
+       }
+
+       spin_unlock_irqrestore(&rq->lock, flags);
+}
+
+static void init_rootdomain(struct root_domain *rd, const cpumask_t *map)
+{
+       memset(rd, 0, sizeof(*rd));
+
+       rd->span = *map;
+       cpus_and(rd->online, rd->span, cpu_online_map);
+}
+
+static void init_defrootdomain(void)
+{
+       cpumask_t cpus = CPU_MASK_ALL;
+
+       init_rootdomain(&def_root_domain, &cpus);
+       atomic_set(&def_root_domain.refcount, 1);
+}
+
+static struct root_domain *alloc_rootdomain(const cpumask_t *map)
+{
+       struct root_domain *rd;
+
+       rd = kmalloc(sizeof(*rd), GFP_KERNEL);
+       if (!rd)
+               return NULL;
+
+       init_rootdomain(rd, map);
+
+       return rd;
+}
+
 /*
- * Attach the domain 'sd' to 'cpu' as its base domain.  Callers must
+ * Attach the domain 'sd' to 'cpu' as its base domain. Callers must
  * hold the hotplug lock.
  */
-static void cpu_attach_domain(struct sched_domain *sd, int cpu)
+static void
+cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu)
 {
        struct rq *rq = cpu_rq(cpu);
        struct sched_domain *tmp;
@@ -5817,6 +5926,7 @@ static void cpu_attach_domain(struct sched_domain *sd, int cpu)
 
        sched_domain_debug(sd, cpu);
 
+       rq_attach_root(rq, rd);
        rcu_assign_pointer(rq->sd, sd);
 }
 
@@ -6185,6 +6295,7 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd)
 static int build_sched_domains(const cpumask_t *cpu_map)
 {
        int i;
+       struct root_domain *rd;
 #ifdef CONFIG_NUMA
        struct sched_group **sched_group_nodes = NULL;
        int sd_allnodes = 0;
@@ -6201,6 +6312,12 @@ static int build_sched_domains(const cpumask_t *cpu_map)
        sched_group_nodes_bycpu[first_cpu(*cpu_map)] = sched_group_nodes;
 #endif
 
+       rd = alloc_rootdomain(cpu_map);
+       if (!rd) {
+               printk(KERN_WARNING "Cannot alloc root domain\n");
+               return -ENOMEM;
+       }
+
        /*
         * Set up domains for cpus specified by the cpu_map.
         */
@@ -6417,7 +6534,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
 #else
                sd = &per_cpu(phys_domains, i);
 #endif
-               cpu_attach_domain(sd, i);
+               cpu_attach_domain(sd, rd, i);
        }
 
        return 0;
@@ -6475,7 +6592,7 @@ static void detach_destroy_domains(const cpumask_t *cpu_map)
        unregister_sched_domain_sysctl();
 
        for_each_cpu_mask(i, *cpu_map)
-               cpu_attach_domain(NULL, i);
+               cpu_attach_domain(NULL, &def_root_domain, i);
        synchronize_sched();
        arch_destroy_sched_domains(cpu_map);
 }
@@ -6727,6 +6844,10 @@ void __init sched_init(void)
        int highest_cpu = 0;
        int i, j;
 
+#ifdef CONFIG_SMP
+       init_defrootdomain();
+#endif
+
        for_each_possible_cpu(i) {
                struct rt_prio_array *array;
                struct rq *rq;
@@ -6765,6 +6886,8 @@ void __init sched_init(void)
                        rq->cpu_load[j] = 0;
 #ifdef CONFIG_SMP
                rq->sd = NULL;
+               rq->rd = NULL;
+               rq_attach_root(rq, &def_root_domain);
                rq->active_balance = 0;
                rq->next_balance = jiffies;
                rq->push_cpu = 0;
@@ -6974,7 +7097,7 @@ static int rebalance_shares(struct sched_domain *sd, int this_cpu)
                for_each_cpu_mask(i, sdspan)
                        total_load += tg->cfs_rq[i]->load.weight;
 
-               /* Nothing to do if this group has no load  */
+               /* Nothing to do if this group has no load */
                if (!total_load)
                        continue;