@@ -4768,11 +4768,15 @@ static struct rq *move_queued_task(struct task_struct *p, int new_cpu)
void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
{
+ bool updated = false;
+
if (p->sched_class->set_cpus_allowed)
- p->sched_class->set_cpus_allowed(p, new_mask);
+ updated = p->sched_class->set_cpus_allowed(p, new_mask);
- cpumask_copy(&p->cpus_allowed, new_mask);
- p->nr_cpus_allowed = cpumask_weight(new_mask);
+ if (!updated) {
+ cpumask_copy(&p->cpus_allowed, new_mask);
+ p->nr_cpus_allowed = cpumask_weight(new_mask);
+ }
}
/*
@@ -1574,7 +1574,7 @@ static void task_woken_dl(struct rq *rq, struct task_struct *p)
}
}
-static void set_cpus_allowed_dl(struct task_struct *p,
+static bool set_cpus_allowed_dl(struct task_struct *p,
const struct cpumask *new_mask)
{
struct rq *rq;
@@ -1610,7 +1610,7 @@ static void set_cpus_allowed_dl(struct task_struct *p,
* it is on the rq AND it is not throttled).
*/
if (!on_dl_rq(&p->dl))
- return;
+ return false;
weight = cpumask_weight(new_mask);
@@ -1619,7 +1619,7 @@ static void set_cpus_allowed_dl(struct task_struct *p,
* can migrate or not.
*/
if ((p->nr_cpus_allowed > 1) == (weight > 1))
- return;
+ return false;
/*
* The process used to be able to migrate OR it can now migrate
@@ -1636,6 +1636,8 @@ static void set_cpus_allowed_dl(struct task_struct *p,
}
update_dl_migration(&rq->dl);
+
+ return false;
}
/* Assumes rq->lock is held */
@@ -2241,7 +2241,7 @@ static void task_woken_rt(struct rq *rq, struct task_struct *p)
push_rt_tasks(rq);
}
-static void set_cpus_allowed_rt(struct task_struct *p,
+static bool set_cpus_allowed_rt(struct task_struct *p,
const struct cpumask *new_mask)
{
struct rq *rq;
@@ -2250,18 +2250,19 @@ static void set_cpus_allowed_rt(struct task_struct *p,
BUG_ON(!rt_task(p));
if (!task_on_rq_queued(p))
- return;
+ return false;
weight = cpumask_weight(new_mask);
+ rq = task_rq(p);
+
/*
- * Only update if the process changes its state from whether it
- * can migrate or not.
+ * Skip updating the migration stuff if the process doesn't change
+ * its migrate state, but still need to check if it can be pushed
+ * away due to its new affinity.
*/
if ((p->nr_cpus_allowed > 1) == (weight > 1))
- return;
-
- rq = task_rq(p);
+ goto check_push;
/*
* The process used to be able to migrate OR it can now migrate
@@ -2278,6 +2279,20 @@ static void set_cpus_allowed_rt(struct task_struct *p,
}
update_rt_migration(&rq->rt);
+
+check_push:
+ if (weight > 1 &&
+ !task_running(rq, p) &&
+ !test_tsk_need_resched(rq->curr) &&
+ !cpumask_subset(new_mask, &p->cpus_allowed)) {
+ /* Update new affinity and try to push. */
+ cpumask_copy(&p->cpus_allowed, new_mask);
+ p->nr_cpus_allowed = weight;
+ push_rt_tasks(rq);
+ return true;
+ }
+
+ return false;
}
/* Assumes rq->lock is held */
@@ -1189,7 +1189,8 @@ struct sched_class {
void (*task_waking) (struct task_struct *task);
void (*task_woken) (struct rq *this_rq, struct task_struct *task);
- void (*set_cpus_allowed)(struct task_struct *p,
+ /* Return true if p's affinity was updated, false otherwise. */
+ bool (*set_cpus_allowed)(struct task_struct *p,
const struct cpumask *newmask);
void (*rq_online)(struct rq *rq);