sched: Remove rq argument to sched_class::task_waking()
[firefly-linux-kernel-4.4.55.git] / kernel / sched.c
index 81ab58efd788e624b1801ae2e31b04816f61d869..46f42cac4eb16965fcbf1a64f3aaecdf7fa6046f 100644 (file)
@@ -1785,7 +1785,6 @@ static void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
        update_rq_clock(rq);
        sched_info_queued(p);
        p->sched_class->enqueue_task(rq, p, flags);
-       p->se.on_rq = 1;
 }
 
 static void dequeue_task(struct rq *rq, struct task_struct *p, int flags)
@@ -1793,7 +1792,6 @@ static void dequeue_task(struct rq *rq, struct task_struct *p, int flags)
        update_rq_clock(rq);
        sched_info_dequeued(p);
        p->sched_class->dequeue_task(rq, p, flags);
-       p->se.on_rq = 0;
 }
 
 /*
@@ -2128,7 +2126,7 @@ static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
         * A queue event has occurred, and we're going to schedule.  In
         * this case, we can save a useless back to back clock update.
         */
-       if (rq->curr->se.on_rq && test_tsk_need_resched(rq->curr))
+       if (rq->curr->on_rq && test_tsk_need_resched(rq->curr))
                rq->skip_clock_update = 1;
 }
 
@@ -2197,13 +2195,15 @@ static int migration_cpu_stop(void *data);
  * The task's runqueue lock must be held.
  * Returns true if you have to wait for migration thread.
  */
-static bool migrate_task(struct task_struct *p, struct rq *rq)
+static bool need_migrate_task(struct task_struct *p)
 {
        /*
         * If the task is not on a runqueue (and not running), then
         * the next wake-up will properly place the task.
         */
-       return p->se.on_rq || task_running(rq, p);
+       bool running = p->on_rq || p->on_cpu;
+       smp_rmb(); /* finish_lock_switch() */
+       return running;
 }
 
 /*
@@ -2263,7 +2263,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state)
                rq = task_rq_lock(p, &flags);
                trace_sched_wait_task(p);
                running = task_running(rq, p);
-               on_rq = p->se.on_rq;
+               on_rq = p->on_rq;
                ncsw = 0;
                if (!match_state || p->state == match_state)
                        ncsw = p->nvcsw | LONG_MIN; /* sets MSB */
@@ -2342,7 +2342,7 @@ EXPORT_SYMBOL_GPL(kick_process);
 
 #ifdef CONFIG_SMP
 /*
- * ->cpus_allowed is protected by either TASK_WAKING or rq->lock held.
+ * ->cpus_allowed is protected by both rq->lock and p->pi_lock
  */
 static int select_fallback_rq(int cpu, struct task_struct *p)
 {
@@ -2375,12 +2375,12 @@ static int select_fallback_rq(int cpu, struct task_struct *p)
 }
 
 /*
- * The caller (fork, wakeup) owns TASK_WAKING, ->cpus_allowed is stable.
+ * The caller (fork, wakeup) owns p->pi_lock, ->cpus_allowed is stable.
  */
 static inline
-int select_task_rq(struct rq *rq, struct task_struct *p, int sd_flags, int wake_flags)
+int select_task_rq(struct task_struct *p, int sd_flags, int wake_flags)
 {
-       int cpu = p->sched_class->select_task_rq(rq, p, sd_flags, wake_flags);
+       int cpu = p->sched_class->select_task_rq(p, sd_flags, wake_flags);
 
        /*
         * In order not to call set_task_cpu() on a blocking task we need
@@ -2406,31 +2406,55 @@ static void update_avg(u64 *avg, u64 sample)
 }
 #endif
 
-static inline void ttwu_activate(struct task_struct *p, struct rq *rq,
-                                bool is_sync, bool is_migrate, bool is_local,
-                                unsigned long en_flags)
+static void
+ttwu_stat(struct rq *rq, struct task_struct *p, int cpu, int wake_flags)
 {
+#ifdef CONFIG_SCHEDSTATS
+#ifdef CONFIG_SMP
+       int this_cpu = smp_processor_id();
+
+       if (cpu == this_cpu) {
+               schedstat_inc(rq, ttwu_local);
+               schedstat_inc(p, se.statistics.nr_wakeups_local);
+       } else {
+               struct sched_domain *sd;
+
+               schedstat_inc(p, se.statistics.nr_wakeups_remote);
+               for_each_domain(this_cpu, sd) {
+                       if (cpumask_test_cpu(cpu, sched_domain_span(sd))) {
+                               schedstat_inc(sd, ttwu_wake_remote);
+                               break;
+                       }
+               }
+       }
+#endif /* CONFIG_SMP */
+
+       schedstat_inc(rq, ttwu_count);
        schedstat_inc(p, se.statistics.nr_wakeups);
-       if (is_sync)
+
+       if (wake_flags & WF_SYNC)
                schedstat_inc(p, se.statistics.nr_wakeups_sync);
-       if (is_migrate)
+
+       if (cpu != task_cpu(p))
                schedstat_inc(p, se.statistics.nr_wakeups_migrate);
-       if (is_local)
-               schedstat_inc(p, se.statistics.nr_wakeups_local);
-       else
-               schedstat_inc(p, se.statistics.nr_wakeups_remote);
 
+#endif /* CONFIG_SCHEDSTATS */
+}
+
+static void ttwu_activate(struct rq *rq, struct task_struct *p, int en_flags)
+{
        activate_task(rq, p, en_flags);
+       p->on_rq = 1;
 
        /* if a worker is waking up, notify workqueue */
        if (p->flags & PF_WQ_WORKER)
                wq_worker_waking_up(p, cpu_of(rq));
 }
 
-static inline void ttwu_post_activation(struct task_struct *p, struct rq *rq,
-                                       int wake_flags, bool success)
+static void
+ttwu_post_activation(struct task_struct *p, struct rq *rq, int wake_flags)
 {
-       trace_sched_wakeup(p, success);
+       trace_sched_wakeup(p, true);
        check_preempt_curr(rq, p, wake_flags);
 
        p->state = TASK_RUNNING;
@@ -2477,16 +2501,17 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
        this_cpu = get_cpu();
 
        smp_wmb();
-       rq = task_rq_lock(p, &flags);
+       raw_spin_lock_irqsave(&p->pi_lock, flags);
+       rq = __task_rq_lock(p);
        if (!(p->state & state))
                goto out;
 
-       if (p->se.on_rq)
+       cpu = task_cpu(p);
+
+       if (p->on_rq)
                goto out_running;
 
-       cpu = task_cpu(p);
        orig_cpu = cpu;
-
 #ifdef CONFIG_SMP
        if (unlikely(task_running(rq, p)))
                goto out_activate;
@@ -2506,11 +2531,11 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
        p->state = TASK_WAKING;
 
        if (p->sched_class->task_waking) {
-               p->sched_class->task_waking(rq, p);
+               p->sched_class->task_waking(p);
                en_flags |= ENQUEUE_WAKING;
        }
 
-       cpu = select_task_rq(rq, p, SD_BALANCE_WAKE, wake_flags);
+       cpu = select_task_rq(p, SD_BALANCE_WAKE, wake_flags);
        if (cpu != orig_cpu)
                set_task_cpu(p, cpu);
        __task_rq_unlock(rq);
@@ -2527,30 +2552,16 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
        WARN_ON(task_cpu(p) != cpu);
        WARN_ON(p->state != TASK_WAKING);
 
-#ifdef CONFIG_SCHEDSTATS
-       schedstat_inc(rq, ttwu_count);
-       if (cpu == this_cpu)
-               schedstat_inc(rq, ttwu_local);
-       else {
-               struct sched_domain *sd;
-               for_each_domain(this_cpu, sd) {
-                       if (cpumask_test_cpu(cpu, sched_domain_span(sd))) {
-                               schedstat_inc(sd, ttwu_wake_remote);
-                               break;
-                       }
-               }
-       }
-#endif /* CONFIG_SCHEDSTATS */
-
 out_activate:
 #endif /* CONFIG_SMP */
-       ttwu_activate(p, rq, wake_flags & WF_SYNC, orig_cpu != cpu,
-                     cpu == this_cpu, en_flags);
-       success = 1;
+       ttwu_activate(rq, p, en_flags);
 out_running:
-       ttwu_post_activation(p, rq, wake_flags, success);
+       ttwu_post_activation(p, rq, wake_flags);
+       ttwu_stat(rq, p, cpu, wake_flags);
+       success = 1;
 out:
-       task_rq_unlock(rq, &flags);
+       __task_rq_unlock(rq);
+       raw_spin_unlock_irqrestore(&p->pi_lock, flags);
        put_cpu();
 
        return success;
@@ -2567,7 +2578,6 @@ out:
 static void try_to_wake_up_local(struct task_struct *p)
 {
        struct rq *rq = task_rq(p);
-       bool success = false;
 
        BUG_ON(rq != this_rq());
        BUG_ON(p == current);
@@ -2576,15 +2586,11 @@ static void try_to_wake_up_local(struct task_struct *p)
        if (!(p->state & TASK_NORMAL))
                return;
 
-       if (!p->se.on_rq) {
-               if (likely(!task_running(rq, p))) {
-                       schedstat_inc(rq, ttwu_count);
-                       schedstat_inc(rq, ttwu_local);
-               }
-               ttwu_activate(p, rq, false, false, true, ENQUEUE_WAKEUP);
-               success = true;
-       }
-       ttwu_post_activation(p, rq, 0, success);
+       if (!p->on_rq)
+               ttwu_activate(rq, p, ENQUEUE_WAKEUP);
+
+       ttwu_post_activation(p, rq, 0);
+       ttwu_stat(rq, p, smp_processor_id(), 0);
 }
 
 /**
@@ -2617,19 +2623,21 @@ int wake_up_state(struct task_struct *p, unsigned int state)
  */
 static void __sched_fork(struct task_struct *p)
 {
+       p->on_rq                        = 0;
+
+       p->se.on_rq                     = 0;
        p->se.exec_start                = 0;
        p->se.sum_exec_runtime          = 0;
        p->se.prev_sum_exec_runtime     = 0;
        p->se.nr_migrations             = 0;
        p->se.vruntime                  = 0;
+       INIT_LIST_HEAD(&p->se.group_node);
 
 #ifdef CONFIG_SCHEDSTATS
        memset(&p->se.statistics, 0, sizeof(p->se.statistics));
 #endif
 
        INIT_LIST_HEAD(&p->rt.run_list);
-       p->se.on_rq = 0;
-       INIT_LIST_HEAD(&p->se.group_node);
 
 #ifdef CONFIG_PREEMPT_NOTIFIERS
        INIT_HLIST_HEAD(&p->preempt_notifiers);
@@ -2738,7 +2746,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
         * We set TASK_WAKING so that select_task_rq() can drop rq->lock
         * without people poking at ->cpus_allowed.
         */
-       cpu = select_task_rq(rq, p, SD_BALANCE_FORK, 0);
+       cpu = select_task_rq(p, SD_BALANCE_FORK, 0);
        set_task_cpu(p, cpu);
 
        p->state = TASK_RUNNING;
@@ -2747,7 +2755,8 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
 
        rq = task_rq_lock(p, &flags);
        activate_task(rq, p, 0);
-       trace_sched_wakeup_new(p, 1);
+       p->on_rq = 1;
+       trace_sched_wakeup_new(p, true);
        check_preempt_curr(rq, p, WF_FORK);
 #ifdef CONFIG_SMP
        if (p->sched_class->task_woken)
@@ -3467,7 +3476,7 @@ void sched_exec(void)
        int dest_cpu;
 
        rq = task_rq_lock(p, &flags);
-       dest_cpu = p->sched_class->select_task_rq(rq, p, SD_BALANCE_EXEC, 0);
+       dest_cpu = p->sched_class->select_task_rq(p, SD_BALANCE_EXEC, 0);
        if (dest_cpu == smp_processor_id())
                goto unlock;
 
@@ -3475,7 +3484,7 @@ void sched_exec(void)
         * select_task_rq() can race against ->cpus_allowed
         */
        if (cpumask_test_cpu(dest_cpu, &p->cpus_allowed) &&
-           likely(cpu_active(dest_cpu)) && migrate_task(p, rq)) {
+           likely(cpu_active(dest_cpu)) && need_migrate_task(p)) {
                struct migration_arg arg = { p, dest_cpu };
 
                task_rq_unlock(rq, &flags);
@@ -4048,7 +4057,7 @@ static inline void schedule_debug(struct task_struct *prev)
 
 static void put_prev_task(struct rq *rq, struct task_struct *prev)
 {
-       if (prev->se.on_rq)
+       if (prev->on_rq)
                update_rq_clock(rq);
        prev->sched_class->put_prev_task(rq, prev);
 }
@@ -4123,7 +4132,9 @@ need_resched:
                                if (to_wakeup)
                                        try_to_wake_up_local(to_wakeup);
                        }
+
                        deactivate_task(rq, prev, DEQUEUE_SLEEP);
+                       prev->on_rq = 0;
 
                        /*
                         * If we are going to sleep and we have plugged IO queued, make
@@ -4687,12 +4698,14 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
 
        BUG_ON(prio < 0 || prio > MAX_PRIO);
 
+       lockdep_assert_held(&p->pi_lock);
+
        rq = task_rq_lock(p, &flags);
 
        trace_sched_pi_setprio(p, prio);
        oldprio = p->prio;
        prev_class = p->sched_class;
-       on_rq = p->se.on_rq;
+       on_rq = p->on_rq;
        running = task_current(rq, p);
        if (on_rq)
                dequeue_task(rq, p, 0);
@@ -4740,7 +4753,7 @@ void set_user_nice(struct task_struct *p, long nice)
                p->static_prio = NICE_TO_PRIO(nice);
                goto out_unlock;
        }
-       on_rq = p->se.on_rq;
+       on_rq = p->on_rq;
        if (on_rq)
                dequeue_task(rq, p, 0);
 
@@ -4874,8 +4887,6 @@ static struct task_struct *find_process_by_pid(pid_t pid)
 static void
 __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
 {
-       BUG_ON(p->se.on_rq);
-
        p->policy = policy;
        p->rt_priority = prio;
        p->normal_prio = normal_prio(p);
@@ -5041,7 +5052,7 @@ recheck:
                raw_spin_unlock_irqrestore(&p->pi_lock, flags);
                goto recheck;
        }
-       on_rq = p->se.on_rq;
+       on_rq = p->on_rq;
        running = task_current(rq, p);
        if (on_rq)
                deactivate_task(rq, p, 0);
@@ -5312,7 +5323,6 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask)
 {
        struct task_struct *p;
        unsigned long flags;
-       struct rq *rq;
        int retval;
 
        get_online_cpus();
@@ -5327,9 +5337,9 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask)
        if (retval)
                goto out_unlock;
 
-       rq = task_rq_lock(p, &flags);
+       raw_spin_lock_irqsave(&p->pi_lock, flags);
        cpumask_and(mask, &p->cpus_allowed, cpu_online_mask);
-       task_rq_unlock(rq, &flags);
+       raw_spin_unlock_irqrestore(&p->pi_lock, flags);
 
 out_unlock:
        rcu_read_unlock();
@@ -5877,18 +5887,8 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
        unsigned int dest_cpu;
        int ret = 0;
 
-       /*
-        * Serialize against TASK_WAKING so that ttwu() and wunt() can
-        * drop the rq->lock and still rely on ->cpus_allowed.
-        */
-again:
-       while (task_is_waking(p))
-               cpu_relax();
-       rq = task_rq_lock(p, &flags);
-       if (task_is_waking(p)) {
-               task_rq_unlock(rq, &flags);
-               goto again;
-       }
+       raw_spin_lock_irqsave(&p->pi_lock, flags);
+       rq = __task_rq_lock(p);
 
        if (!cpumask_intersects(new_mask, cpu_active_mask)) {
                ret = -EINVAL;
@@ -5913,16 +5913,18 @@ again:
                goto out;
 
        dest_cpu = cpumask_any_and(cpu_active_mask, new_mask);
-       if (migrate_task(p, rq)) {
+       if (need_migrate_task(p)) {
                struct migration_arg arg = { p, dest_cpu };
                /* Need help from migration thread: drop lock and wait. */
-               task_rq_unlock(rq, &flags);
+               __task_rq_unlock(rq);
+               raw_spin_unlock_irqrestore(&p->pi_lock, flags);
                stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg);
                tlb_migrate_finish(p->mm);
                return 0;
        }
 out:
-       task_rq_unlock(rq, &flags);
+       __task_rq_unlock(rq);
+       raw_spin_unlock_irqrestore(&p->pi_lock, flags);
 
        return ret;
 }
@@ -5962,7 +5964,7 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
         * If we're not on a rq, the next wake-up will ensure we're
         * placed properly.
         */
-       if (p->se.on_rq) {
+       if (p->on_rq) {
                deactivate_task(rq_src, p, 0);
                set_task_cpu(p, dest_cpu);
                activate_task(rq_dest, p, 0);
@@ -8336,7 +8338,7 @@ static void normalize_task(struct rq *rq, struct task_struct *p)
        int old_prio = p->prio;
        int on_rq;
 
-       on_rq = p->se.on_rq;
+       on_rq = p->on_rq;
        if (on_rq)
                deactivate_task(rq, p, 0);
        __setscheduler(rq, p, SCHED_NORMAL, 0);
@@ -8679,7 +8681,7 @@ void sched_move_task(struct task_struct *tsk)
        rq = task_rq_lock(tsk, &flags);
 
        running = task_current(rq, tsk);
-       on_rq = tsk->se.on_rq;
+       on_rq = tsk->on_rq;
 
        if (on_rq)
                dequeue_task(rq, tsk, 0);