ALSA: usb-audio: add support for Akai MPD16
[safe/jmp/linux-2.6] / kernel / sched_rt.c
index f365e66..8afb953 100644 (file)
@@ -136,6 +136,11 @@ static void dequeue_pushable_task(struct rq *rq, struct task_struct *p)
        plist_del(&p->pushable_tasks, &rq->rt.pushable_tasks);
 }
 
+static inline int has_pushable_tasks(struct rq *rq)
+{
+       return !plist_head_empty(&rq->rt.pushable_tasks);
+}
+
 #else
 
 static inline void enqueue_pushable_task(struct rq *rq, struct task_struct *p)
@@ -189,17 +194,20 @@ static inline struct rt_rq *group_rt_rq(struct sched_rt_entity *rt_se)
        return rt_se->my_q;
 }
 
-static void enqueue_rt_entity(struct sched_rt_entity *rt_se);
+static void enqueue_rt_entity(struct sched_rt_entity *rt_se, bool head);
 static void dequeue_rt_entity(struct sched_rt_entity *rt_se);
 
 static void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
 {
+       int this_cpu = smp_processor_id();
        struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
-       struct sched_rt_entity *rt_se = rt_rq->rt_se;
+       struct sched_rt_entity *rt_se;
+
+       rt_se = rt_rq->tg->rt_se[this_cpu];
 
        if (rt_rq->rt_nr_running) {
                if (rt_se && !on_rt_rq(rt_se))
-                       enqueue_rt_entity(rt_se);
+                       enqueue_rt_entity(rt_se, false);
                if (rt_rq->highest_prio.curr < curr->prio)
                        resched_task(curr);
        }
@@ -207,7 +215,10 @@ static void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
 
 static void sched_rt_rq_dequeue(struct rt_rq *rt_rq)
 {
-       struct sched_rt_entity *rt_se = rt_rq->rt_se;
+       int this_cpu = smp_processor_id();
+       struct sched_rt_entity *rt_se;
+
+       rt_se = rt_rq->tg->rt_se[this_cpu];
 
        if (rt_se && on_rt_rq(rt_se))
                dequeue_rt_entity(rt_se);
@@ -322,7 +333,7 @@ static int do_balance_runtime(struct rt_rq *rt_rq)
 
        weight = cpumask_weight(rd->span);
 
-       spin_lock(&rt_b->rt_runtime_lock);
+       raw_spin_lock(&rt_b->rt_runtime_lock);
        rt_period = ktime_to_ns(rt_b->rt_period);
        for_each_cpu(i, rd->span) {
                struct rt_rq *iter = sched_rt_period_rt_rq(rt_b, i);
@@ -331,7 +342,7 @@ static int do_balance_runtime(struct rt_rq *rt_rq)
                if (iter == rt_rq)
                        continue;
 
-               spin_lock(&iter->rt_runtime_lock);
+               raw_spin_lock(&iter->rt_runtime_lock);
                /*
                 * Either all rqs have inf runtime and there's nothing to steal
                 * or __disable_runtime() below sets a specific rq to inf to
@@ -353,14 +364,14 @@ static int do_balance_runtime(struct rt_rq *rt_rq)
                        rt_rq->rt_runtime += diff;
                        more = 1;
                        if (rt_rq->rt_runtime == rt_period) {
-                               spin_unlock(&iter->rt_runtime_lock);
+                               raw_spin_unlock(&iter->rt_runtime_lock);
                                break;
                        }
                }
 next:
-               spin_unlock(&iter->rt_runtime_lock);
+               raw_spin_unlock(&iter->rt_runtime_lock);
        }
-       spin_unlock(&rt_b->rt_runtime_lock);
+       raw_spin_unlock(&rt_b->rt_runtime_lock);
 
        return more;
 }
@@ -381,8 +392,8 @@ static void __disable_runtime(struct rq *rq)
                s64 want;
                int i;
 
-               spin_lock(&rt_b->rt_runtime_lock);
-               spin_lock(&rt_rq->rt_runtime_lock);
+               raw_spin_lock(&rt_b->rt_runtime_lock);
+               raw_spin_lock(&rt_rq->rt_runtime_lock);
                /*
                 * Either we're all inf and nobody needs to borrow, or we're
                 * already disabled and thus have nothing to do, or we have
@@ -391,7 +402,7 @@ static void __disable_runtime(struct rq *rq)
                if (rt_rq->rt_runtime == RUNTIME_INF ||
                                rt_rq->rt_runtime == rt_b->rt_runtime)
                        goto balanced;
-               spin_unlock(&rt_rq->rt_runtime_lock);
+               raw_spin_unlock(&rt_rq->rt_runtime_lock);
 
                /*
                 * Calculate the difference between what we started out with
@@ -413,7 +424,7 @@ static void __disable_runtime(struct rq *rq)
                        if (iter == rt_rq || iter->rt_runtime == RUNTIME_INF)
                                continue;
 
-                       spin_lock(&iter->rt_runtime_lock);
+                       raw_spin_lock(&iter->rt_runtime_lock);
                        if (want > 0) {
                                diff = min_t(s64, iter->rt_runtime, want);
                                iter->rt_runtime -= diff;
@@ -422,13 +433,13 @@ static void __disable_runtime(struct rq *rq)
                                iter->rt_runtime -= want;
                                want -= want;
                        }
-                       spin_unlock(&iter->rt_runtime_lock);
+                       raw_spin_unlock(&iter->rt_runtime_lock);
 
                        if (!want)
                                break;
                }
 
-               spin_lock(&rt_rq->rt_runtime_lock);
+               raw_spin_lock(&rt_rq->rt_runtime_lock);
                /*
                 * We cannot be left wanting - that would mean some runtime
                 * leaked out of the system.
@@ -440,8 +451,8 @@ balanced:
                 * runtime - in which case borrowing doesn't make sense.
                 */
                rt_rq->rt_runtime = RUNTIME_INF;
-               spin_unlock(&rt_rq->rt_runtime_lock);
-               spin_unlock(&rt_b->rt_runtime_lock);
+               raw_spin_unlock(&rt_rq->rt_runtime_lock);
+               raw_spin_unlock(&rt_b->rt_runtime_lock);
        }
 }
 
@@ -449,9 +460,9 @@ static void disable_runtime(struct rq *rq)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&rq->lock, flags);
+       raw_spin_lock_irqsave(&rq->lock, flags);
        __disable_runtime(rq);
-       spin_unlock_irqrestore(&rq->lock, flags);
+       raw_spin_unlock_irqrestore(&rq->lock, flags);
 }
 
 static void __enable_runtime(struct rq *rq)
@@ -467,13 +478,13 @@ static void __enable_runtime(struct rq *rq)
        for_each_leaf_rt_rq(rt_rq, rq) {
                struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);
 
-               spin_lock(&rt_b->rt_runtime_lock);
-               spin_lock(&rt_rq->rt_runtime_lock);
+               raw_spin_lock(&rt_b->rt_runtime_lock);
+               raw_spin_lock(&rt_rq->rt_runtime_lock);
                rt_rq->rt_runtime = rt_b->rt_runtime;
                rt_rq->rt_time = 0;
                rt_rq->rt_throttled = 0;
-               spin_unlock(&rt_rq->rt_runtime_lock);
-               spin_unlock(&rt_b->rt_runtime_lock);
+               raw_spin_unlock(&rt_rq->rt_runtime_lock);
+               raw_spin_unlock(&rt_b->rt_runtime_lock);
        }
 }
 
@@ -481,9 +492,9 @@ static void enable_runtime(struct rq *rq)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&rq->lock, flags);
+       raw_spin_lock_irqsave(&rq->lock, flags);
        __enable_runtime(rq);
-       spin_unlock_irqrestore(&rq->lock, flags);
+       raw_spin_unlock_irqrestore(&rq->lock, flags);
 }
 
 static int balance_runtime(struct rt_rq *rt_rq)
@@ -491,9 +502,9 @@ static int balance_runtime(struct rt_rq *rt_rq)
        int more = 0;
 
        if (rt_rq->rt_time > rt_rq->rt_runtime) {
-               spin_unlock(&rt_rq->rt_runtime_lock);
+               raw_spin_unlock(&rt_rq->rt_runtime_lock);
                more = do_balance_runtime(rt_rq);
-               spin_lock(&rt_rq->rt_runtime_lock);
+               raw_spin_lock(&rt_rq->rt_runtime_lock);
        }
 
        return more;
@@ -519,11 +530,11 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
                struct rt_rq *rt_rq = sched_rt_period_rt_rq(rt_b, i);
                struct rq *rq = rq_of_rt_rq(rt_rq);
 
-               spin_lock(&rq->lock);
+               raw_spin_lock(&rq->lock);
                if (rt_rq->rt_time) {
                        u64 runtime;
 
-                       spin_lock(&rt_rq->rt_runtime_lock);
+                       raw_spin_lock(&rt_rq->rt_runtime_lock);
                        if (rt_rq->rt_throttled)
                                balance_runtime(rt_rq);
                        runtime = rt_rq->rt_runtime;
@@ -534,13 +545,13 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
                        }
                        if (rt_rq->rt_time || rt_rq->rt_nr_running)
                                idle = 0;
-                       spin_unlock(&rt_rq->rt_runtime_lock);
+                       raw_spin_unlock(&rt_rq->rt_runtime_lock);
                } else if (rt_rq->rt_nr_running)
                        idle = 0;
 
                if (enqueue)
                        sched_rt_rq_enqueue(rt_rq);
-               spin_unlock(&rq->lock);
+               raw_spin_unlock(&rq->lock);
        }
 
        return idle;
@@ -602,7 +613,7 @@ static void update_curr_rt(struct rq *rq)
        if (unlikely((s64)delta_exec < 0))
                delta_exec = 0;
 
-       schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec));
+       schedstat_set(curr->se.statistics.exec_max, max(curr->se.statistics.exec_max, delta_exec));
 
        curr->se.sum_exec_runtime += delta_exec;
        account_group_exec_runtime(curr, delta_exec);
@@ -610,6 +621,8 @@ static void update_curr_rt(struct rq *rq)
        curr->se.exec_start = rq->clock;
        cpuacct_charge(curr, delta_exec);
 
+       sched_rt_avg_update(rq, delta_exec);
+
        if (!rt_bandwidth_enabled())
                return;
 
@@ -617,11 +630,11 @@ static void update_curr_rt(struct rq *rq)
                rt_rq = rt_rq_of_se(rt_se);
 
                if (sched_rt_runtime(rt_rq) != RUNTIME_INF) {
-                       spin_lock(&rt_rq->rt_runtime_lock);
+                       raw_spin_lock(&rt_rq->rt_runtime_lock);
                        rt_rq->rt_time += delta_exec;
                        if (sched_rt_runtime_exceeded(rt_rq))
                                resched_task(curr);
-                       spin_unlock(&rt_rq->rt_runtime_lock);
+                       raw_spin_unlock(&rt_rq->rt_runtime_lock);
                }
        }
 }
@@ -796,7 +809,7 @@ void dec_rt_tasks(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
        dec_rt_group(rt_se, rt_rq);
 }
 
-static void __enqueue_rt_entity(struct sched_rt_entity *rt_se)
+static void __enqueue_rt_entity(struct sched_rt_entity *rt_se, bool head)
 {
        struct rt_rq *rt_rq = rt_rq_of_se(rt_se);
        struct rt_prio_array *array = &rt_rq->active;
@@ -812,7 +825,10 @@ static void __enqueue_rt_entity(struct sched_rt_entity *rt_se)
        if (group_rq && (rt_rq_throttled(group_rq) || !group_rq->rt_nr_running))
                return;
 
-       list_add_tail(&rt_se->run_list, queue);
+       if (head)
+               list_add(&rt_se->run_list, queue);
+       else
+               list_add_tail(&rt_se->run_list, queue);
        __set_bit(rt_se_prio(rt_se), array->bitmap);
 
        inc_rt_tasks(rt_se, rt_rq);
@@ -849,11 +865,11 @@ static void dequeue_rt_stack(struct sched_rt_entity *rt_se)
        }
 }
 
-static void enqueue_rt_entity(struct sched_rt_entity *rt_se)
+static void enqueue_rt_entity(struct sched_rt_entity *rt_se, bool head)
 {
        dequeue_rt_stack(rt_se);
        for_each_sched_rt_entity(rt_se)
-               __enqueue_rt_entity(rt_se);
+               __enqueue_rt_entity(rt_se, head);
 }
 
 static void dequeue_rt_entity(struct sched_rt_entity *rt_se)
@@ -864,29 +880,28 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se)
                struct rt_rq *rt_rq = group_rt_rq(rt_se);
 
                if (rt_rq && rt_rq->rt_nr_running)
-                       __enqueue_rt_entity(rt_se);
+                       __enqueue_rt_entity(rt_se, false);
        }
 }
 
 /*
  * Adding/removing a task to/from a priority array:
  */
-static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup)
+static void
+enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags)
 {
        struct sched_rt_entity *rt_se = &p->rt;
 
-       if (wakeup)
+       if (flags & ENQUEUE_WAKEUP)
                rt_se->timeout = 0;
 
-       enqueue_rt_entity(rt_se);
+       enqueue_rt_entity(rt_se, flags & ENQUEUE_HEAD);
 
        if (!task_current(rq, p) && p->rt.nr_cpus_allowed > 1)
                enqueue_pushable_task(rq, p);
-
-       inc_cpu_load(rq, p->se.load.weight);
 }
 
-static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep)
+static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int flags)
 {
        struct sched_rt_entity *rt_se = &p->rt;
 
@@ -894,8 +909,6 @@ static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep)
        dequeue_rt_entity(rt_se);
 
        dequeue_pushable_task(rq, p);
-
-       dec_cpu_load(rq, p->se.load.weight);
 }
 
 /*
@@ -935,9 +948,11 @@ static void yield_task_rt(struct rq *rq)
 #ifdef CONFIG_SMP
 static int find_lowest_rq(struct task_struct *task);
 
-static int select_task_rq_rt(struct task_struct *p, int sync)
+static int
+select_task_rq_rt(struct rq *rq, struct task_struct *p, int sd_flag, int flags)
 {
-       struct rq *rq = task_rq(p);
+       if (sd_flag != SD_BALANCE_WAKE)
+               return smp_processor_id();
 
        /*
         * If the current task is an RT task, then
@@ -996,7 +1011,7 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p)
 /*
  * Preempt the current task with a newly woken task if needed:
  */
-static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p, int sync)
+static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p, int flags)
 {
        if (p->prio < rq->curr->prio) {
                resched_task(rq->curr);
@@ -1064,11 +1079,6 @@ static struct task_struct *_pick_next_task_rt(struct rq *rq)
        return p;
 }
 
-static inline int has_pushable_tasks(struct rq *rq)
-{
-       return !plist_head_empty(&rq->rt.pushable_tasks);
-}
-
 static struct task_struct *pick_next_task_rt(struct rq *rq)
 {
        struct task_struct *p = _pick_next_task_rt(rq);
@@ -1077,11 +1087,13 @@ static struct task_struct *pick_next_task_rt(struct rq *rq)
        if (p)
                dequeue_pushable_task(rq, p);
 
+#ifdef CONFIG_SMP
        /*
         * We detect this state here so that we can avoid taking the RQ
         * lock again later if there is no need to push
         */
        rq->post_schedule = has_pushable_tasks(rq);
+#endif
 
        return p;
 }
@@ -1133,7 +1145,12 @@ static struct task_struct *pick_next_highest_task_rt(struct rq *rq, int cpu)
                if (next && next->prio < idx)
                        continue;
                list_for_each_entry(rt_se, array->queue + idx, run_list) {
-                       struct task_struct *p = rt_task_of(rt_se);
+                       struct task_struct *p;
+
+                       if (!rt_entity_is_task(rt_se))
+                               continue;
+
+                       p = rt_task_of(rt_se);
                        if (pick_rt_task(rq, p, cpu)) {
                                next = p;
                                break;
@@ -1150,29 +1167,12 @@ static struct task_struct *pick_next_highest_task_rt(struct rq *rq, int cpu)
 
 static DEFINE_PER_CPU(cpumask_var_t, local_cpu_mask);
 
-static inline int pick_optimal_cpu(int this_cpu,
-                                  const struct cpumask *mask)
-{
-       int first;
-
-       /* "this_cpu" is cheaper to preempt than a remote processor */
-       if ((this_cpu != -1) && cpumask_test_cpu(this_cpu, mask))
-               return this_cpu;
-
-       first = cpumask_first(mask);
-       if (first < nr_cpu_ids)
-               return first;
-
-       return -1;
-}
-
 static int find_lowest_rq(struct task_struct *task)
 {
        struct sched_domain *sd;
        struct cpumask *lowest_mask = __get_cpu_var(local_cpu_mask);
        int this_cpu = smp_processor_id();
        int cpu      = task_cpu(task);
-       cpumask_var_t domain_mask;
 
        if (task->rt.nr_cpus_allowed == 1)
                return -1; /* No other targets possible */
@@ -1195,28 +1195,26 @@ static int find_lowest_rq(struct task_struct *task)
         * Otherwise, we consult the sched_domains span maps to figure
         * out which cpu is logically closest to our hot cache data.
         */
-       if (this_cpu == cpu)
-               this_cpu = -1; /* Skip this_cpu opt if the same */
-
-       if (alloc_cpumask_var(&domain_mask, GFP_ATOMIC)) {
-               for_each_domain(cpu, sd) {
-                       if (sd->flags & SD_WAKE_AFFINE) {
-                               int best_cpu;
+       if (!cpumask_test_cpu(this_cpu, lowest_mask))
+               this_cpu = -1; /* Skip this_cpu opt if not among lowest */
 
-                               cpumask_and(domain_mask,
-                                           sched_domain_span(sd),
-                                           lowest_mask);
+       for_each_domain(cpu, sd) {
+               if (sd->flags & SD_WAKE_AFFINE) {
+                       int best_cpu;
 
-                               best_cpu = pick_optimal_cpu(this_cpu,
-                                                           domain_mask);
-
-                               if (best_cpu != -1) {
-                                       free_cpumask_var(domain_mask);
-                                       return best_cpu;
-                               }
-                       }
+                       /*
+                        * "this_cpu" is cheaper to preempt than a
+                        * remote processor.
+                        */
+                       if (this_cpu != -1 &&
+                           cpumask_test_cpu(this_cpu, sched_domain_span(sd)))
+                               return this_cpu;
+
+                       best_cpu = cpumask_first_and(lowest_mask,
+                                                    sched_domain_span(sd));
+                       if (best_cpu < nr_cpu_ids)
+                               return best_cpu;
                }
-               free_cpumask_var(domain_mask);
        }
 
        /*
@@ -1224,7 +1222,13 @@ static int find_lowest_rq(struct task_struct *task)
         * just give the caller *something* to work with from the compatible
         * locations.
         */
-       return pick_optimal_cpu(this_cpu, lowest_mask);
+       if (this_cpu != -1)
+               return this_cpu;
+
+       cpu = cpumask_any(lowest_mask);
+       if (cpu < nr_cpu_ids)
+               return cpu;
+       return -1;
 }
 
 /* Will lock the rq it finds */
@@ -1256,7 +1260,7 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq)
                                     task_running(rq, task) ||
                                     !task->se.on_rq)) {
 
-                               spin_unlock(&lowest_rq->lock);
+                               raw_spin_unlock(&lowest_rq->lock);
                                lowest_rq = NULL;
                                break;
                        }
@@ -1482,7 +1486,7 @@ static void post_schedule_rt(struct rq *rq)
  * If we are not running and we are not going to reschedule soon, we should
  * try to push tasks away now
  */
-static void task_wake_up_rt(struct rq *rq, struct task_struct *p)
+static void task_woken_rt(struct rq *rq, struct task_struct *p)
 {
        if (!task_running(rq, p) &&
            !test_tsk_need_resched(rq->curr) &&
@@ -1491,24 +1495,6 @@ static void task_wake_up_rt(struct rq *rq, struct task_struct *p)
                push_rt_tasks(rq);
 }
 
-static unsigned long
-load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
-               unsigned long max_load_move,
-               struct sched_domain *sd, enum cpu_idle_type idle,
-               int *all_pinned, int *this_best_prio)
-{
-       /* don't touch RT tasks */
-       return 0;
-}
-
-static int
-move_one_task_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
-                struct sched_domain *sd, enum cpu_idle_type idle)
-{
-       /* don't touch RT tasks */
-       return 0;
-}
-
 static void set_cpus_allowed_rt(struct task_struct *p,
                                const struct cpumask *new_mask)
 {
@@ -1680,8 +1666,9 @@ static void watchdog(struct rq *rq, struct task_struct *p)
        if (!p->signal)
                return;
 
-       soft = p->signal->rlim[RLIMIT_RTTIME].rlim_cur;
-       hard = p->signal->rlim[RLIMIT_RTTIME].rlim_max;
+       /* max may change after cur was read, this will be fixed next tick */
+       soft = task_rlimit(p, RLIMIT_RTTIME);
+       hard = task_rlimit_max(p, RLIMIT_RTTIME);
 
        if (soft != RLIM_INFINITY) {
                unsigned long next;
@@ -1731,6 +1718,17 @@ static void set_curr_task_rt(struct rq *rq)
        dequeue_pushable_task(rq, p);
 }
 
+static unsigned int get_rr_interval_rt(struct rq *rq, struct task_struct *task)
+{
+       /*
+        * Time slice is 0 for SCHED_FIFO tasks
+        */
+       if (task->policy == SCHED_RR)
+               return DEF_TIMESLICE;
+       else
+               return 0;
+}
+
 static const struct sched_class rt_sched_class = {
        .next                   = &fair_sched_class,
        .enqueue_task           = enqueue_task_rt,
@@ -1745,20 +1743,20 @@ static const struct sched_class rt_sched_class = {
 #ifdef CONFIG_SMP
        .select_task_rq         = select_task_rq_rt,
 
-       .load_balance           = load_balance_rt,
-       .move_one_task          = move_one_task_rt,
        .set_cpus_allowed       = set_cpus_allowed_rt,
        .rq_online              = rq_online_rt,
        .rq_offline             = rq_offline_rt,
        .pre_schedule           = pre_schedule_rt,
        .post_schedule          = post_schedule_rt,
-       .task_wake_up           = task_wake_up_rt,
+       .task_woken             = task_woken_rt,
        .switched_from          = switched_from_rt,
 #endif
 
        .set_curr_task          = set_curr_task_rt,
        .task_tick              = task_tick_rt,
 
+       .get_rr_interval        = get_rr_interval_rt,
+
        .prio_changed           = prio_changed_rt,
        .switched_to            = switched_to_rt,
 };