On Tue, 5 May 2015 23:17:30 +0800 pang.xun...@zte.com.cn wrote: > > Or just do the p->{nr_,}cpus_allowed assignments in > > set_cpus_allowed_rt() and keep it all in the one callback. > > Ok, thanks. > > How about this?
This is something more like I had in mind. > > diff --git a/kernel/sched/core.c b/kernel/sched/core.c > index d13fc13..c995a02 100644 > --- a/kernel/sched/core.c > +++ b/kernel/sched/core.c > @@ -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); > + } I'm fine with this if Peter is. > } > > /* > diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c > index 5e95145..3baffb2 100644 > --- a/kernel/sched/deadline.c > +++ b/kernel/sched/deadline.c > @@ -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; > I would think DEAD_LINE tasks would need the same "feature". > 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 */ > diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c > index 8885b65..9e7a4bb 100644 > --- a/kernel/sched/rt.c > +++ b/kernel/sched/rt.c > @@ -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,18 @@ 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. Comment needs updating. > */ > 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 +2278,18 @@ static void set_cpus_allowed_rt(struct task_struct > *p, > } > > update_rt_migration(&rq->rt); > + > +check_push: > + if (weight > 1 && !task_running(rq, p) && > + !cpumask_subset(new_mask, &p->cpus_allowed)) { > + /* Update new affinity for pushing */ > + 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 */ > diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h > index e0e1299..75f869b 100644 > --- a/kernel/sched/sched.h > +++ b/kernel/sched/sched.h > @@ -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, > + /* If p's affinity was updated by it, return true. Otherwise false > */ /* Return true if p's affinity was updated, false otherwise */ -- Steve > + bool (*set_cpus_allowed)(struct task_struct *p, > const struct cpumask *newmask); > > void (*rq_online)(struct rq *rq); > > -------------------------------------------------------- > ZTE Information Security Notice: The information contained in this mail (and > any attachment transmitted herewith) is privileged and confidential and is > intended for the exclusive use of the addressee(s). If you are not an > intended recipient, any disclosure, reproduction, distribution or other > dissemination or use of the information contained is strictly prohibited. If > you have received this mail in error, please delete it and notify us > immediately. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/