sched: Reject CPU affinity changes based on task_cpu_possible_mask()
[linux-2.6-microblaze.git] / kernel / sched / deadline.c
index 9a29897..e943146 100644 (file)
@@ -157,7 +157,7 @@ void __add_running_bw(u64 dl_bw, struct dl_rq *dl_rq)
 {
        u64 old = dl_rq->running_bw;
 
-       lockdep_assert_held(&(rq_of_dl_rq(dl_rq))->lock);
+       lockdep_assert_rq_held(rq_of_dl_rq(dl_rq));
        dl_rq->running_bw += dl_bw;
        SCHED_WARN_ON(dl_rq->running_bw < old); /* overflow */
        SCHED_WARN_ON(dl_rq->running_bw > dl_rq->this_bw);
@@ -170,7 +170,7 @@ void __sub_running_bw(u64 dl_bw, struct dl_rq *dl_rq)
 {
        u64 old = dl_rq->running_bw;
 
-       lockdep_assert_held(&(rq_of_dl_rq(dl_rq))->lock);
+       lockdep_assert_rq_held(rq_of_dl_rq(dl_rq));
        dl_rq->running_bw -= dl_bw;
        SCHED_WARN_ON(dl_rq->running_bw > old); /* underflow */
        if (dl_rq->running_bw > old)
@@ -184,7 +184,7 @@ void __add_rq_bw(u64 dl_bw, struct dl_rq *dl_rq)
 {
        u64 old = dl_rq->this_bw;
 
-       lockdep_assert_held(&(rq_of_dl_rq(dl_rq))->lock);
+       lockdep_assert_rq_held(rq_of_dl_rq(dl_rq));
        dl_rq->this_bw += dl_bw;
        SCHED_WARN_ON(dl_rq->this_bw < old); /* overflow */
 }
@@ -194,7 +194,7 @@ void __sub_rq_bw(u64 dl_bw, struct dl_rq *dl_rq)
 {
        u64 old = dl_rq->this_bw;
 
-       lockdep_assert_held(&(rq_of_dl_rq(dl_rq))->lock);
+       lockdep_assert_rq_held(rq_of_dl_rq(dl_rq));
        dl_rq->this_bw -= dl_bw;
        SCHED_WARN_ON(dl_rq->this_bw > old); /* underflow */
        if (dl_rq->this_bw > old)
@@ -348,10 +348,10 @@ static void task_non_contending(struct task_struct *p)
        if ((zerolag_time < 0) || hrtimer_active(&dl_se->inactive_timer)) {
                if (dl_task(p))
                        sub_running_bw(dl_se, dl_rq);
-               if (!dl_task(p) || p->state == TASK_DEAD) {
+               if (!dl_task(p) || READ_ONCE(p->__state) == TASK_DEAD) {
                        struct dl_bw *dl_b = dl_bw_of(task_cpu(p));
 
-                       if (p->state == TASK_DEAD)
+                       if (READ_ONCE(p->__state) == TASK_DEAD)
                                sub_rq_bw(&p->dl, &rq->dl);
                        raw_spin_lock(&dl_b->lock);
                        __dl_sub(dl_b, p->dl.dl_bw, dl_bw_cpus(task_cpu(p)));
@@ -987,7 +987,7 @@ static int start_dl_timer(struct task_struct *p)
        ktime_t now, act;
        s64 delta;
 
-       lockdep_assert_held(&rq->lock);
+       lockdep_assert_rq_held(rq);
 
        /*
         * We want the timer to fire at the deadline, but considering
@@ -1097,9 +1097,9 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)
                 * If the runqueue is no longer available, migrate the
                 * task elsewhere. This necessarily changes rq.
                 */
-               lockdep_unpin_lock(&rq->lock, rf.cookie);
+               lockdep_unpin_lock(__rq_lockp(rq), rf.cookie);
                rq = dl_task_offline_migration(rq, p);
-               rf.cookie = lockdep_pin_lock(&rq->lock);
+               rf.cookie = lockdep_pin_lock(__rq_lockp(rq));
                update_rq_clock(rq);
 
                /*
@@ -1355,10 +1355,10 @@ static enum hrtimer_restart inactive_task_timer(struct hrtimer *timer)
        sched_clock_tick();
        update_rq_clock(rq);
 
-       if (!dl_task(p) || p->state == TASK_DEAD) {
+       if (!dl_task(p) || READ_ONCE(p->__state) == TASK_DEAD) {
                struct dl_bw *dl_b = dl_bw_of(task_cpu(p));
 
-               if (p->state == TASK_DEAD && dl_se->dl_non_contending) {
+               if (READ_ONCE(p->__state) == TASK_DEAD && dl_se->dl_non_contending) {
                        sub_running_bw(&p->dl, dl_rq_of_se(&p->dl));
                        sub_rq_bw(&p->dl, dl_rq_of_se(&p->dl));
                        dl_se->dl_non_contending = 0;
@@ -1722,7 +1722,7 @@ static void migrate_task_rq_dl(struct task_struct *p, int new_cpu __maybe_unused
 {
        struct rq *rq;
 
-       if (p->state != TASK_WAKING)
+       if (READ_ONCE(p->__state) != TASK_WAKING)
                return;
 
        rq = task_rq(p);
@@ -1731,8 +1731,9 @@ static void migrate_task_rq_dl(struct task_struct *p, int new_cpu __maybe_unused
         * from try_to_wake_up(). Hence, p->pi_lock is locked, but
         * rq->lock is not... So, lock it
         */
-       raw_spin_lock(&rq->lock);
+       raw_spin_rq_lock(rq);
        if (p->dl.dl_non_contending) {
+               update_rq_clock(rq);
                sub_running_bw(&p->dl, &rq->dl);
                p->dl.dl_non_contending = 0;
                /*
@@ -1746,7 +1747,7 @@ static void migrate_task_rq_dl(struct task_struct *p, int new_cpu __maybe_unused
                        put_task_struct(p);
        }
        sub_rq_bw(&p->dl, &rq->dl);
-       raw_spin_unlock(&rq->lock);
+       raw_spin_rq_unlock(rq);
 }
 
 static void check_preempt_equal_dl(struct rq *rq, struct task_struct *p)
@@ -1852,7 +1853,7 @@ static struct sched_dl_entity *pick_next_dl_entity(struct rq *rq,
        return rb_entry(left, struct sched_dl_entity, rb_node);
 }
 
-static struct task_struct *pick_next_task_dl(struct rq *rq)
+static struct task_struct *pick_task_dl(struct rq *rq)
 {
        struct sched_dl_entity *dl_se;
        struct dl_rq *dl_rq = &rq->dl;
@@ -1864,7 +1865,18 @@ static struct task_struct *pick_next_task_dl(struct rq *rq)
        dl_se = pick_next_dl_entity(rq, dl_rq);
        BUG_ON(!dl_se);
        p = dl_task_of(dl_se);
-       set_next_task_dl(rq, p, true);
+
+       return p;
+}
+
+static struct task_struct *pick_next_task_dl(struct rq *rq)
+{
+       struct task_struct *p;
+
+       p = pick_task_dl(rq);
+       if (p)
+               set_next_task_dl(rq, p, true);
+
        return p;
 }
 
@@ -2291,10 +2303,10 @@ skip:
                double_unlock_balance(this_rq, src_rq);
 
                if (push_task) {
-                       raw_spin_unlock(&this_rq->lock);
+                       raw_spin_rq_unlock(this_rq);
                        stop_one_cpu_nowait(src_rq->cpu, push_cpu_stop,
                                            push_task, &src_rq->push_work);
-                       raw_spin_lock(&this_rq->lock);
+                       raw_spin_rq_lock(this_rq);
                }
        }
 
@@ -2486,6 +2498,8 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p)
                        check_preempt_curr_dl(rq, p, 0);
                else
                        resched_curr(rq);
+       } else {
+               update_dl_rq_load_avg(rq_clock_pelt(rq), rq, 0);
        }
 }
 
@@ -2539,6 +2553,7 @@ DEFINE_SCHED_CLASS(dl) = {
 
 #ifdef CONFIG_SMP
        .balance                = balance_dl,
+       .pick_task              = pick_task_dl,
        .select_task_rq         = select_task_rq_dl,
        .migrate_task_rq        = migrate_task_rq_dl,
        .set_cpus_allowed       = set_cpus_allowed_dl,
@@ -2727,7 +2742,7 @@ void __setparam_dl(struct task_struct *p, const struct sched_attr *attr)
        dl_se->dl_runtime = attr->sched_runtime;
        dl_se->dl_deadline = attr->sched_deadline;
        dl_se->dl_period = attr->sched_period ?: dl_se->dl_deadline;
-       dl_se->flags = attr->sched_flags;
+       dl_se->flags = attr->sched_flags & SCHED_DL_FLAGS;
        dl_se->dl_bw = to_ratio(dl_se->dl_period, dl_se->dl_runtime);
        dl_se->dl_density = to_ratio(dl_se->dl_deadline, dl_se->dl_runtime);
 }
@@ -2740,7 +2755,8 @@ void __getparam_dl(struct task_struct *p, struct sched_attr *attr)
        attr->sched_runtime = dl_se->dl_runtime;
        attr->sched_deadline = dl_se->dl_deadline;
        attr->sched_period = dl_se->dl_period;
-       attr->sched_flags = dl_se->flags;
+       attr->sched_flags &= ~SCHED_DL_FLAGS;
+       attr->sched_flags |= dl_se->flags;
 }
 
 /*
@@ -2837,7 +2853,7 @@ bool dl_param_changed(struct task_struct *p, const struct sched_attr *attr)
        if (dl_se->dl_runtime != attr->sched_runtime ||
            dl_se->dl_deadline != attr->sched_deadline ||
            dl_se->dl_period != attr->sched_period ||
-           dl_se->flags != attr->sched_flags)
+           dl_se->flags != (attr->sched_flags & SCHED_DL_FLAGS))
                return true;
 
        return false;