lkml.org 
[lkml]   [2021]   [Jul]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH RT 2/8] sched: Simplify migration_cpu_stop()
    5.10.47-rt46-rc1 stable review patch.
    If anyone has any objections, please let me know.

    ------------------

    From: Peter Zijlstra <peterz@infradead.org>

    commit c20cf065d4a619d394d23290093b1002e27dff86 upstream.

    When affine_move_task() issues a migration_cpu_stop(), the purpose of
    that function is to complete that @pending, not any random other
    p->migration_pending that might have gotten installed since.

    This realization much simplifies migration_cpu_stop() and allows
    further necessary steps to fix all this as it provides the guarantee
    that @pending's stopper will complete @pending (and not some random
    other @pending).

    Fixes: 6d337eab041d ("sched: Fix migrate_disable() vs set_cpus_allowed_ptr()")
    Cc: stable@kernel.org
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Reviewed-by: Valentin Schneider <valentin.schneider@arm.com>
    Link: https://lkml.kernel.org/r/20210224131355.430014682@infradead.org
    Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
    Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
    ---
    kernel/sched/core.c | 56 +++++++--------------------------------------
    1 file changed, 8 insertions(+), 48 deletions(-)

    diff --git a/kernel/sched/core.c b/kernel/sched/core.c
    index a3dea38f410a..d497b13efb53 100644
    --- a/kernel/sched/core.c
    +++ b/kernel/sched/core.c
    @@ -1934,8 +1934,8 @@ static struct rq *__migrate_task(struct rq *rq, struct rq_flags *rf,
    */
    static int migration_cpu_stop(void *data)
    {
    - struct set_affinity_pending *pending;
    struct migration_arg *arg = data;
    + struct set_affinity_pending *pending = arg->pending;
    struct task_struct *p = arg->task;
    int dest_cpu = arg->dest_cpu;
    struct rq *rq = this_rq();
    @@ -1957,25 +1957,6 @@ static int migration_cpu_stop(void *data)
    raw_spin_lock(&p->pi_lock);
    rq_lock(rq, &rf);

    - pending = p->migration_pending;
    - if (pending && !arg->pending) {
    - /*
    - * This happens from sched_exec() and migrate_task_to(),
    - * neither of them care about pending and just want a task to
    - * maybe move about.
    - *
    - * Even if there is a pending, we can ignore it, since
    - * affine_move_task() will have it's own stop_work's in flight
    - * which will manage the completion.
    - *
    - * Notably, pending doesn't need to match arg->pending. This can
    - * happen when tripple concurrent affine_move_task() first sets
    - * pending, then clears pending and eventually sets another
    - * pending.
    - */
    - pending = NULL;
    - }
    -
    /*
    * If task_rq(p) != rq, it cannot be migrated here, because we're
    * holding rq->lock, if p->on_rq == 0 it cannot get enqueued because
    @@ -1986,31 +1967,20 @@ static int migration_cpu_stop(void *data)
    goto out;

    if (pending) {
    - p->migration_pending = NULL;
    + if (p->migration_pending == pending)
    + p->migration_pending = NULL;
    complete = true;
    }

    - /* migrate_enable() -- we must not race against SCA */
    - if (dest_cpu < 0) {
    - /*
    - * When this was migrate_enable() but we no longer
    - * have a @pending, a concurrent SCA 'fixed' things
    - * and we should be valid again. Nothing to do.
    - */
    - if (!pending) {
    - WARN_ON_ONCE(!cpumask_test_cpu(task_cpu(p), &p->cpus_mask));
    - goto out;
    - }
    -
    + if (dest_cpu < 0)
    dest_cpu = cpumask_any_distribute(&p->cpus_mask);
    - }

    if (task_on_rq_queued(p))
    rq = __migrate_task(rq, &rf, p, dest_cpu);
    else
    p->wake_cpu = dest_cpu;

    - } else if (dest_cpu < 0 || pending) {
    + } else if (pending) {
    /*
    * This happens when we get migrated between migrate_enable()'s
    * preempt_enable() and scheduling the stopper task. At that
    @@ -2025,22 +1995,13 @@ static int migration_cpu_stop(void *data)
    * ->pi_lock, so the allowed mask is stable - if it got
    * somewhere allowed, we're done.
    */
    - if (pending && cpumask_test_cpu(task_cpu(p), p->cpus_ptr)) {
    - p->migration_pending = NULL;
    + if (cpumask_test_cpu(task_cpu(p), p->cpus_ptr)) {
    + if (p->migration_pending == pending)
    + p->migration_pending = NULL;
    complete = true;
    goto out;
    }

    - /*
    - * When this was migrate_enable() but we no longer have an
    - * @pending, a concurrent SCA 'fixed' things and we should be
    - * valid again. Nothing to do.
    - */
    - if (!pending) {
    - WARN_ON_ONCE(!cpumask_test_cpu(task_cpu(p), &p->cpus_mask));
    - goto out;
    - }
    -
    /*
    * When migrate_enable() hits a rq mis-match we can't reliably
    * determine is_migration_disabled() and so have to chase after
    @@ -2058,7 +2019,6 @@ static int migration_cpu_stop(void *data)
    complete_all(&pending->done);

    /* For pending->{arg,stop_work} */
    - pending = arg->pending;
    if (pending && refcount_dec_and_test(&pending->refs))
    wake_up_var(&pending->refs);

    --
    2.30.2
    \
     
     \ /
      Last update: 2021-07-10 00:00    [W:4.667 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site