On Wed, Feb 24, 2021 at 01:24:45PM +0100, Peter Zijlstra wrote:
> @@ -2199,12 +2199,16 @@ static int affine_move_task(struct rq *r
>                       push_task = get_task_struct(p);
>               }
>  
> +             /*
> +              * If there are pending waiters, but no pending stop_work,
> +              * then complete now.
> +              */
>               pending = p->migration_pending;
> +             if (pending && !pending->stop_pending) {
>                       p->migration_pending = NULL;
>                       complete = true;
>               }

> @@ -2282,12 +2286,13 @@ static int affine_move_task(struct rq *r
>                       if (task_on_rq_queued(p))
>                               rq = move_queued_task(rq, rf, p, dest_cpu);
>  
> +                     if (!pending->stop_pending) {
> +                             p->migration_pending = NULL;
> +                             complete = true;
> +                     }
>               }
>               task_rq_unlock(rq, p, rf);

Elsewhere Valentin argued something like the below ought to be possible.
I've not drawn diagrams yet, but if I understood his argument right it
should be possible.

---
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 1c56ac4df2c9..3ffbd1b76f3e 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2204,9 +2204,10 @@ static int affine_move_task(struct rq *rq, struct 
task_struct *p, struct rq_flag
                 * then complete now.
                 */
                pending = p->migration_pending;
-               if (pending && !pending->stop_pending) {
+               if (pending) {
                        p->migration_pending = NULL;
-                       complete = true;
+                       if (!pending->stop_pending)
+                               complete = true;
                }
 
                task_rq_unlock(rq, p, rf);
@@ -2286,10 +2287,9 @@ static int affine_move_task(struct rq *rq, struct 
task_struct *p, struct rq_flag
                        if (task_on_rq_queued(p))
                                rq = move_queued_task(rq, rf, p, dest_cpu);
 
-                       if (!pending->stop_pending) {
-                               p->migration_pending = NULL;
+                       p->migration_pending = NULL;
+                       if (!pending->stop_pending)
                                complete = true;
-                       }
                }
                task_rq_unlock(rq, p, rf);
 

Reply via email to