* [PATCH linux-next] sched: Fix broken setscheduler() @ 2014-03-06 4:29 Steven Rostedt 2014-03-06 11:58 ` Peter Zijlstra 0 siblings, 1 reply; 13+ messages in thread From: Steven Rostedt @ 2014-03-06 4:29 UTC (permalink / raw) To: LKML Cc: Thomas Gleixner, Sebastian Andrzej Siewior, Peter Zijlstra, Ingo Molnar I decided to run my tests on linux-next, and my wakeup_rt tracer was broken. After running a bisect, I found that the problem commit was: linux-next commit c365c292d059 "sched: Consider pi boosting in setscheduler()" And the reason the wake_rt tracer test was failing, was because it had no RT task to trace. I first noticed this when running with sched_switch event and saw that my RT task still had normal SCHED_OTHER priority. Looking at the problem commit, I found: - p->normal_prio = normal_prio(p); - p->prio = rt_mutex_getprio(p); With no + p->normal_prio = normal_prio(p); + p->prio = rt_mutex_getprio(p); Reading what the commit is suppose to do, I realize that the p->prio can't be set if the task is boosted with a higher prio, but the p->normal_prio still needs to be set regardless, otherwise, when the task is deboosted, it wont get the new priority. The p->prio has to be set before "check_class_changed()" is called, otherwise the class wont be changed. Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 4600bca..b1cc871 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3198,6 +3198,7 @@ static void __setscheduler_params(struct task_struct *p, * getparam()/getattr() don't report silly values for !rt tasks. */ p->rt_priority = attr->sched_priority; + p->normal_prio = normal_prio(p); set_load_weight(p); } @@ -3207,6 +3208,8 @@ static void __setscheduler(struct rq *rq, struct task_struct *p, { __setscheduler_params(p, attr); + p->prio = rt_mutex_getprio(p); + if (dl_prio(p->prio)) p->sched_class = &dl_sched_class; else if (rt_prio(p->prio)) ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH linux-next] sched: Fix broken setscheduler() 2014-03-06 4:29 [PATCH linux-next] sched: Fix broken setscheduler() Steven Rostedt @ 2014-03-06 11:58 ` Peter Zijlstra 2014-03-06 12:20 ` Juri Lelli 0 siblings, 1 reply; 13+ messages in thread From: Peter Zijlstra @ 2014-03-06 11:58 UTC (permalink / raw) To: Steven Rostedt Cc: LKML, Thomas Gleixner, Sebastian Andrzej Siewior, Ingo Molnar, Juri Lelli On Wed, Mar 05, 2014 at 11:29:31PM -0500, Steven Rostedt wrote: > I decided to run my tests on linux-next, and my wakeup_rt tracer was > broken. After running a bisect, I found that the problem commit was: > > linux-next commit c365c292d059 > "sched: Consider pi boosting in setscheduler()" > > And the reason the wake_rt tracer test was failing, was because it had > no RT task to trace. I first noticed this when running with > sched_switch event and saw that my RT task still had normal SCHED_OTHER > priority. Looking at the problem commit, I found: > > - p->normal_prio = normal_prio(p); > - p->prio = rt_mutex_getprio(p); > > With no > > + p->normal_prio = normal_prio(p); > + p->prio = rt_mutex_getprio(p); > > Reading what the commit is suppose to do, I realize that the p->prio > can't be set if the task is boosted with a higher prio, but the > p->normal_prio still needs to be set regardless, otherwise, when the > task is deboosted, it wont get the new priority. > > The p->prio has to be set before "check_class_changed()" is called, > otherwise the class wont be changed. So Juri had a different patch for this problem: http://lkml.kernel.org/r/20140301191838.d15d03112b2598a671dac22c@gmail.com > Signed-off-by: Steven Rostedt <rostedt@goodmis.org> > --- > diff --git a/kernel/sched/core.c b/kernel/sched/core.c > index 4600bca..b1cc871 100644 > --- a/kernel/sched/core.c > +++ b/kernel/sched/core.c > @@ -3198,6 +3198,7 @@ static void __setscheduler_params(struct task_struct *p, > * getparam()/getattr() don't report silly values for !rt tasks. > */ > p->rt_priority = attr->sched_priority; > + p->normal_prio = normal_prio(p); > set_load_weight(p); > } Now; if I'm reading things right, normal_prio is the unboosted priority of a task. And we should indeed keep setting that, otherwise the unboost doesn't know where it should go. Juri put that in __setscheduler(), but I think that's wrong because the rt_mutex_check_prio() case in __sched_setscheduler() still needs to update this. > @@ -3207,6 +3208,8 @@ static void __setscheduler(struct rq *rq, struct task_struct *p, > { > __setscheduler_params(p, attr); > > + p->prio = rt_mutex_getprio(p); > + > if (dl_prio(p->prio)) > p->sched_class = &dl_sched_class; > else if (rt_prio(p->prio)) > And when we call this we're sure to not be boosted; so this is effectively the same as Juri has: p->prio = p->normal_prio = normal_prio(p) Seeing how rt_mutex_getprio() and normal_prio() are the same under these conditions. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH linux-next] sched: Fix broken setscheduler() 2014-03-06 11:58 ` Peter Zijlstra @ 2014-03-06 12:20 ` Juri Lelli 2014-03-06 17:04 ` [PATCH v2] " Steven Rostedt 0 siblings, 1 reply; 13+ messages in thread From: Juri Lelli @ 2014-03-06 12:20 UTC (permalink / raw) To: Peter Zijlstra Cc: Steven Rostedt, LKML, Thomas Gleixner, Sebastian Andrzej Siewior, Ingo Molnar On Thu, 6 Mar 2014 12:58:25 +0100 Peter Zijlstra <peterz@infradead.org> wrote: > On Wed, Mar 05, 2014 at 11:29:31PM -0500, Steven Rostedt wrote: > > I decided to run my tests on linux-next, and my wakeup_rt tracer was > > broken. After running a bisect, I found that the problem commit was: > > > > linux-next commit c365c292d059 > > "sched: Consider pi boosting in setscheduler()" > > > > And the reason the wake_rt tracer test was failing, was because it had > > no RT task to trace. I first noticed this when running with > > sched_switch event and saw that my RT task still had normal SCHED_OTHER > > priority. Looking at the problem commit, I found: > > > > - p->normal_prio = normal_prio(p); > > - p->prio = rt_mutex_getprio(p); > > > > With no > > > > + p->normal_prio = normal_prio(p); > > + p->prio = rt_mutex_getprio(p); > > > > Reading what the commit is suppose to do, I realize that the p->prio > > can't be set if the task is boosted with a higher prio, but the > > p->normal_prio still needs to be set regardless, otherwise, when the > > task is deboosted, it wont get the new priority. > > > > The p->prio has to be set before "check_class_changed()" is called, > > otherwise the class wont be changed. > > So Juri had a different patch for this problem: > > http://lkml.kernel.org/r/20140301191838.d15d03112b2598a671dac22c@gmail.com > > > Signed-off-by: Steven Rostedt <rostedt@goodmis.org> > > --- > > diff --git a/kernel/sched/core.c b/kernel/sched/core.c > > index 4600bca..b1cc871 100644 > > --- a/kernel/sched/core.c > > +++ b/kernel/sched/core.c > > @@ -3198,6 +3198,7 @@ static void __setscheduler_params(struct task_struct *p, > > * getparam()/getattr() don't report silly values for !rt tasks. > > */ > > p->rt_priority = attr->sched_priority; > > + p->normal_prio = normal_prio(p); > > set_load_weight(p); > > } > > Now; if I'm reading things right, normal_prio is the unboosted priority > of a task. And we should indeed keep setting that, otherwise the unboost > doesn't know where it should go. > > Juri put that in __setscheduler(), but I think that's wrong because the > rt_mutex_check_prio() case in __sched_setscheduler() still needs to > update this. > Oh, right. Missed that. > > @@ -3207,6 +3208,8 @@ static void __setscheduler(struct rq *rq, struct task_struct *p, > > { > > __setscheduler_params(p, attr); > > > > + p->prio = rt_mutex_getprio(p); > > + > > if (dl_prio(p->prio)) > > p->sched_class = &dl_sched_class; > > else if (rt_prio(p->prio)) > > > > And when we call this we're sure to not be boosted; so this is > effectively the same as Juri has: > > p->prio = p->normal_prio = normal_prio(p) > > Seeing how rt_mutex_getprio() and normal_prio() are the same under these > conditions. > > Yes. I think you can go with p->prio = p->normal_prio and save a few checks in rt_mutex_getprio(). Thanks, - Juri ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2] sched: Fix broken setscheduler() 2014-03-06 12:20 ` Juri Lelli @ 2014-03-06 17:04 ` Steven Rostedt 2014-03-06 20:43 ` Thomas Gleixner 2014-03-12 10:10 ` [tip:sched/core] " tip-bot for Steven Rostedt 0 siblings, 2 replies; 13+ messages in thread From: Steven Rostedt @ 2014-03-06 17:04 UTC (permalink / raw) To: Juri Lelli Cc: Peter Zijlstra, LKML, Thomas Gleixner, Sebastian Andrzej Siewior, Ingo Molnar On Thu, 6 Mar 2014 13:20:40 +0100 Juri Lelli <juri.lelli@gmail.com> wrote: > Yes. I think you can go with > > p->prio = p->normal_prio > > and save a few checks in rt_mutex_getprio(). > You're right! Thanks. ----- I decided to run my tests on linux-next, and my wakeup_rt tracer was broken. After running a bisect, I found that the problem commit was: linux-next commit c365c292d059 "sched: Consider pi boosting in setscheduler()" And the reason the wake_rt tracer test was failing, was because it had no RT task to trace. I first noticed this when running with sched_switch event and saw that my RT task still had normal SCHED_OTHER priority. Looking at the problem commit, I found: - p->normal_prio = normal_prio(p); - p->prio = rt_mutex_getprio(p); With no + p->normal_prio = normal_prio(p); + p->prio = rt_mutex_getprio(p); Reading what the commit is suppose to do, I realize that the p->prio can't be set if the task is boosted with a higher prio, but the p->normal_prio still needs to be set regardless, otherwise, when the task is deboosted, it wont get the new priority. The p->prio has to be set before "check_class_changed()" is called, otherwise the class wont be changed. Link: http://lkml.kernel.org/r/20140305232931.449eef8c@gandalf.local.home Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- kernel/sched/core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 4600bca..3134756 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3198,6 +3198,7 @@ static void __setscheduler_params(struct task_struct *p, * getparam()/getattr() don't report silly values for !rt tasks. */ p->rt_priority = attr->sched_priority; + p->normal_prio = normal_prio(p); set_load_weight(p); } @@ -3207,6 +3208,12 @@ static void __setscheduler(struct rq *rq, struct task_struct *p, { __setscheduler_params(p, attr); + /* + * If we get here, there was no pi waiters boosting the + * task. It is safe to use the normal prio. + */ + p->prio = normal_prio(p); + if (dl_prio(p->prio)) p->sched_class = &dl_sched_class; else if (rt_prio(p->prio)) -- 1.8.1.4 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2] sched: Fix broken setscheduler() 2014-03-06 17:04 ` [PATCH v2] " Steven Rostedt @ 2014-03-06 20:43 ` Thomas Gleixner 2014-03-10 17:29 ` Steven Rostedt 2014-03-12 10:10 ` [tip:sched/core] " tip-bot for Steven Rostedt 1 sibling, 1 reply; 13+ messages in thread From: Thomas Gleixner @ 2014-03-06 20:43 UTC (permalink / raw) To: Steven Rostedt Cc: Juri Lelli, Peter Zijlstra, LKML, Sebastian Andrzej Siewior, Ingo Molnar On Thu, 6 Mar 2014, Steven Rostedt wrote: > On Thu, 6 Mar 2014 13:20:40 +0100 > Juri Lelli <juri.lelli@gmail.com> wrote: > > > Yes. I think you can go with > > > > p->prio = p->normal_prio > > > > and save a few checks in rt_mutex_getprio(). > > > > You're right! Thanks. > > ----- > > I decided to run my tests on linux-next, and my wakeup_rt tracer was > broken. After running a bisect, I found that the problem commit was: > > linux-next commit c365c292d059 > "sched: Consider pi boosting in setscheduler()" > > And the reason the wake_rt tracer test was failing, was because it had > no RT task to trace. I first noticed this when running with > sched_switch event and saw that my RT task still had normal SCHED_OTHER > priority. Looking at the problem commit, I found: > > - p->normal_prio = normal_prio(p); > - p->prio = rt_mutex_getprio(p); > > With no > > + p->normal_prio = normal_prio(p); > + p->prio = rt_mutex_getprio(p); > > Reading what the commit is suppose to do, I realize that the p->prio > can't be set if the task is boosted with a higher prio, but the > p->normal_prio still needs to be set regardless, otherwise, when the > task is deboosted, it wont get the new priority. Indeed. > The p->prio has to be set before "check_class_changed()" is called, > otherwise the class wont be changed. > > Link: http://lkml.kernel.org/r/20140305232931.449eef8c@gandalf.local.home > > Signed-off-by: Steven Rostedt <rostedt@goodmis.org> > --- > kernel/sched/core.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/kernel/sched/core.c b/kernel/sched/core.c > index 4600bca..3134756 100644 > --- a/kernel/sched/core.c > +++ b/kernel/sched/core.c > @@ -3198,6 +3198,7 @@ static void __setscheduler_params(struct task_struct *p, > * getparam()/getattr() don't report silly values for !rt tasks. > */ > p->rt_priority = attr->sched_priority; > + p->normal_prio = normal_prio(p); > set_load_weight(p); > } > > @@ -3207,6 +3208,12 @@ static void __setscheduler(struct rq *rq, struct task_struct *p, > { > __setscheduler_params(p, attr); > > + /* > + * If we get here, there was no pi waiters boosting the > + * task. It is safe to use the normal prio. > + */ > + p->prio = normal_prio(p); > + > if (dl_prio(p->prio)) > p->sched_class = &dl_sched_class; > else if (rt_prio(p->prio)) > -- > 1.8.1.4 > > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2] sched: Fix broken setscheduler() 2014-03-06 20:43 ` Thomas Gleixner @ 2014-03-10 17:29 ` Steven Rostedt 2014-03-10 21:18 ` Thomas Gleixner 0 siblings, 1 reply; 13+ messages in thread From: Steven Rostedt @ 2014-03-10 17:29 UTC (permalink / raw) To: Thomas Gleixner Cc: Juri Lelli, Peter Zijlstra, LKML, Sebastian Andrzej Siewior, Ingo Molnar On Thu, 6 Mar 2014 21:43:50 +0100 (CET) Thomas Gleixner <tglx@linutronix.de> wrote: > > Reading what the commit is suppose to do, I realize that the p->prio > > can't be set if the task is boosted with a higher prio, but the > > p->normal_prio still needs to be set regardless, otherwise, when the > > task is deboosted, it wont get the new priority. > > Indeed. Is this an Acked-by? Peter, can you pull this patch please, it is still broken in tip/master. Thanks, -- Steve ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2] sched: Fix broken setscheduler() 2014-03-10 17:29 ` Steven Rostedt @ 2014-03-10 21:18 ` Thomas Gleixner 2014-03-10 21:37 ` Steven Rostedt 0 siblings, 1 reply; 13+ messages in thread From: Thomas Gleixner @ 2014-03-10 21:18 UTC (permalink / raw) To: Steven Rostedt Cc: Juri Lelli, Peter Zijlstra, LKML, Sebastian Andrzej Siewior, Ingo Molnar On Mon, 10 Mar 2014, Steven Rostedt wrote: > On Thu, 6 Mar 2014 21:43:50 +0100 (CET) > Thomas Gleixner <tglx@linutronix.de> wrote: > > > > Reading what the commit is suppose to do, I realize that the p->prio > > > can't be set if the task is boosted with a higher prio, but the > > > p->normal_prio still needs to be set regardless, otherwise, when the > > > task is deboosted, it wont get the new priority. > > > > Indeed. > > Is this an Acked-by? > > Peter, can you pull this patch please, it is still broken in tip/master. Lemme look at it tomorrow again with an awake brain. This seems to be some forward porting hickup which needs a closer look. Just look at the 3.10-rt version of this: @@ -3825,20 +3826,25 @@ static struct task_struct *find_process_by_pid(pid_t pid) return pid ? find_task_by_vpid(pid) : current; } -/* Actually do priority change: must hold rq lock. */ -static void -__setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) +static void __setscheduler_params(struct task_struct *p, int policy, int prio) { p->policy = policy; p->rt_priority = prio; p->normal_prio = normal_prio(p); + set_load_weight(p); +} That code has changed significantly probably due to the EDF merge. We need to figure out whether there is more damage due to that. Thanks, tglx ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2] sched: Fix broken setscheduler() 2014-03-10 21:18 ` Thomas Gleixner @ 2014-03-10 21:37 ` Steven Rostedt 2014-03-11 9:35 ` Juri Lelli 0 siblings, 1 reply; 13+ messages in thread From: Steven Rostedt @ 2014-03-10 21:37 UTC (permalink / raw) To: Thomas Gleixner Cc: Juri Lelli, Peter Zijlstra, LKML, Sebastian Andrzej Siewior, Ingo Molnar On Mon, 10 Mar 2014 22:18:56 +0100 (CET) Thomas Gleixner <tglx@linutronix.de> wrote: > Lemme look at it tomorrow again with an awake brain. This seems to be > some forward porting hickup which needs a closer look. Just look at Yep, I talked with Sebastian on IRC and that seems to be the case. > the 3.10-rt version of this: > > @@ -3825,20 +3826,25 @@ static struct task_struct *find_process_by_pid(pid_t pid) > return pid ? find_task_by_vpid(pid) : current; > } > > -/* Actually do priority change: must hold rq lock. */ > -static void > -__setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) > +static void __setscheduler_params(struct task_struct *p, int policy, int prio) > { > p->policy = policy; > p->rt_priority = prio; > p->normal_prio = normal_prio(p); > + set_load_weight(p); > +} > > That code has changed significantly probably due to the EDF merge. We > need to figure out whether there is more damage due to that. Yeah, when I looked at the -rt version, it appeared to have my fix already. But in reality, the forward port broke it. Here's the problem part of the commit: + set_load_weight(p); +} - p->normal_prio = normal_prio(p); - p->prio = rt_mutex_getprio(p); Your patch never deleted the above two. And it kept them in the locations that I placed them in, in my patch. -- Steve +/* Actually do priority change: must hold pi & rq lock. */ +static void __setscheduler(struct rq *rq, struct task_struct *p, + const struct sched_attr *attr) +{ ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2] sched: Fix broken setscheduler() 2014-03-10 21:37 ` Steven Rostedt @ 2014-03-11 9:35 ` Juri Lelli 2014-03-11 10:48 ` Thomas Gleixner 0 siblings, 1 reply; 13+ messages in thread From: Juri Lelli @ 2014-03-11 9:35 UTC (permalink / raw) To: Steven Rostedt Cc: Thomas Gleixner, Peter Zijlstra, LKML, Sebastian Andrzej Siewior, Ingo Molnar On Mon, 10 Mar 2014 17:37:31 -0400 Steven Rostedt <rostedt@goodmis.org> wrote: > On Mon, 10 Mar 2014 22:18:56 +0100 (CET) > Thomas Gleixner <tglx@linutronix.de> wrote: > > > > Lemme look at it tomorrow again with an awake brain. This seems to be > > some forward porting hickup which needs a closer look. Just look at > > Yep, I talked with Sebastian on IRC and that seems to be the case. > > > the 3.10-rt version of this: > > > > @@ -3825,20 +3826,25 @@ static struct task_struct *find_process_by_pid(pid_t pid) > > return pid ? find_task_by_vpid(pid) : current; > > } > > > > -/* Actually do priority change: must hold rq lock. */ > > -static void > > -__setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) > > +static void __setscheduler_params(struct task_struct *p, int policy, int prio) > > { > > p->policy = policy; > > p->rt_priority = prio; > > p->normal_prio = normal_prio(p); > > + set_load_weight(p); > > +} > > > > That code has changed significantly probably due to the EDF merge. We > > need to figure out whether there is more damage due to that. > > Yeah, when I looked at the -rt version, it appeared to have my fix > already. But in reality, the forward port broke it. Here's the problem > part of the commit: > > + set_load_weight(p); > +} > > - p->normal_prio = normal_prio(p); > - p->prio = rt_mutex_getprio(p); > > Your patch never deleted the above two. And it kept them in the > locations that I placed them in, in my patch. > Oh, and you have to have also something like this @@ -3271,7 +3271,8 @@ static int __sched_setscheduler(struct task_struct *p, const struct sched_attr *attr, bool user) { - int newprio = MAX_RT_PRIO - 1 - attr->sched_priority; + int newprio = dl_policy(attr->sched_policy) ? MAX_DL_PRIO - 1 : + MAX_RT_PRIO - 1 - attr->sched_priority; int retval, oldprio, oldpolicy = -1, on_rq, running; int policy = attr->sched_policy; unsigned long flags; or you can fail to become DL if you are currently boosted by RT, as attr->sched_priority == 0 for DL tasks. Then rt_mutex_check_prio () returns 1 (just update params) if setting DL params for a task already boosted by another DL. But this seems to be ok, as we are already outside enforcement in this situation. (This is going to be trickier with proxy exec, though :/). Thanks, - Juri > -- Steve > > > +/* Actually do priority change: must hold pi & rq lock. */ > +static void __setscheduler(struct rq *rq, struct task_struct *p, > + const struct sched_attr *attr) > +{ > > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2] sched: Fix broken setscheduler() 2014-03-11 9:35 ` Juri Lelli @ 2014-03-11 10:48 ` Thomas Gleixner 2014-03-11 23:24 ` [PATCH v3] " Steven Rostedt 0 siblings, 1 reply; 13+ messages in thread From: Thomas Gleixner @ 2014-03-11 10:48 UTC (permalink / raw) To: Juri Lelli Cc: Steven Rostedt, Peter Zijlstra, LKML, Sebastian Andrzej Siewior, Ingo Molnar On Tue, 11 Mar 2014, Juri Lelli wrote: > On Mon, 10 Mar 2014 17:37:31 -0400 > Steven Rostedt <rostedt@goodmis.org> wrote: > > > On Mon, 10 Mar 2014 22:18:56 +0100 (CET) > > Thomas Gleixner <tglx@linutronix.de> wrote: > > > > > > > Lemme look at it tomorrow again with an awake brain. This seems to be > > > some forward porting hickup which needs a closer look. Just look at > > > > Yep, I talked with Sebastian on IRC and that seems to be the case. > > > > > the 3.10-rt version of this: > > > > > > @@ -3825,20 +3826,25 @@ static struct task_struct *find_process_by_pid(pid_t pid) > > > return pid ? find_task_by_vpid(pid) : current; > > > } > > > > > > -/* Actually do priority change: must hold rq lock. */ > > > -static void > > > -__setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) > > > +static void __setscheduler_params(struct task_struct *p, int policy, int prio) > > > { > > > p->policy = policy; > > > p->rt_priority = prio; > > > p->normal_prio = normal_prio(p); > > > + set_load_weight(p); > > > +} > > > > > > That code has changed significantly probably due to the EDF merge. We > > > need to figure out whether there is more damage due to that. > > > > Yeah, when I looked at the -rt version, it appeared to have my fix > > already. But in reality, the forward port broke it. Here's the problem > > part of the commit: > > > > + set_load_weight(p); > > +} > > > > - p->normal_prio = normal_prio(p); > > - p->prio = rt_mutex_getprio(p); > > > > Your patch never deleted the above two. And it kept them in the > > locations that I placed them in, in my patch. Correct. > > Oh, and you have to have also something like this > > @@ -3271,7 +3271,8 @@ static int __sched_setscheduler(struct task_struct *p, > const struct sched_attr *attr, > bool user) > { > - int newprio = MAX_RT_PRIO - 1 - attr->sched_priority; > + int newprio = dl_policy(attr->sched_policy) ? MAX_DL_PRIO - 1 : > + MAX_RT_PRIO - 1 - attr->sched_priority; Right, you beat me. > int retval, oldprio, oldpolicy = -1, on_rq, running; > int policy = attr->sched_policy; > unsigned long flags; > > or you can fail to become DL if you are currently boosted by RT, as > attr->sched_priority == 0 for DL tasks. Then rt_mutex_check_prio () > returns 1 (just update params) if setting DL params for a task already > boosted by another DL. But this seems to be ok, as we are already > outside enforcement in this situation. (This is going to be trickier > with proxy exec, though :/). Steve, can you please send an updated one? Thanks, tglx ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3] sched: Fix broken setscheduler() 2014-03-11 10:48 ` Thomas Gleixner @ 2014-03-11 23:24 ` Steven Rostedt 2014-03-12 10:41 ` Thomas Gleixner 0 siblings, 1 reply; 13+ messages in thread From: Steven Rostedt @ 2014-03-11 23:24 UTC (permalink / raw) To: Thomas Gleixner Cc: Juri Lelli, Peter Zijlstra, LKML, Sebastian Andrzej Siewior, Ingo Molnar I decided to run my tests on linux-next, and my wakeup_rt tracer was broken. After running a bisect, I found that the problem commit was: linux-next commit c365c292d059 "sched: Consider pi boosting in setscheduler()" And the reason the wake_rt tracer test was failing, was because it had no RT task to trace. I first noticed this when running with sched_switch event and saw that my RT task still had normal SCHED_OTHER priority. Looking at the problem commit, I found: - p->normal_prio = normal_prio(p); - p->prio = rt_mutex_getprio(p); With no + p->normal_prio = normal_prio(p); + p->prio = rt_mutex_getprio(p); Reading what the commit is suppose to do, I realize that the p->prio can't be set if the task is boosted with a higher prio, but the p->normal_prio still needs to be set regardless, otherwise, when the task is deboosted, it wont get the new priority. The p->prio has to be set before "check_class_changed()" is called, otherwise the class wont be changed. Also added fix to newprio to include a check for deadline policy that was missing. This change was suggested by Juri Lelli. Link: http://lkml.kernel.org/r/20140306120438.638bfe94@gandalf.local.home Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- kernel/sched/core.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index ee8004c..f00a032 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3197,6 +3197,7 @@ static void __setscheduler_params(struct task_struct *p, * getparam()/getattr() don't report silly values for !rt tasks. */ p->rt_priority = attr->sched_priority; + p->normal_prio = normal_prio(p); set_load_weight(p); } @@ -3206,6 +3207,12 @@ static void __setscheduler(struct rq *rq, struct task_struct *p, { __setscheduler_params(p, attr); + /* + * If we get here, there was no pi waiters boosting the + * task. It is safe to use the normal prio. + */ + p->prio = normal_prio(p); + if (dl_prio(p->prio)) p->sched_class = &dl_sched_class; else if (rt_prio(p->prio)) @@ -3264,7 +3271,8 @@ static int __sched_setscheduler(struct task_struct *p, const struct sched_attr *attr, bool user) { - int newprio = MAX_RT_PRIO - 1 - attr->sched_priority; + int newprio = dl_policy(attr->sched_policy) ? MAX_DL_PRIO - 1 : + MAX_RT_PRIO - 1 - attr->sched_priority; int retval, oldprio, oldpolicy = -1, on_rq, running; int policy = attr->sched_policy; unsigned long flags; -- 1.8.1.4 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3] sched: Fix broken setscheduler() 2014-03-11 23:24 ` [PATCH v3] " Steven Rostedt @ 2014-03-12 10:41 ` Thomas Gleixner 0 siblings, 0 replies; 13+ messages in thread From: Thomas Gleixner @ 2014-03-12 10:41 UTC (permalink / raw) To: Steven Rostedt Cc: Juri Lelli, Peter Zijlstra, LKML, Sebastian Andrzej Siewior, Ingo Molnar On Tue, 11 Mar 2014, Steven Rostedt wrote: > > I decided to run my tests on linux-next, and my wakeup_rt tracer was > broken. After running a bisect, I found that the problem commit was: > > linux-next commit c365c292d059 > "sched: Consider pi boosting in setscheduler()" > > And the reason the wake_rt tracer test was failing, was because it had > no RT task to trace. I first noticed this when running with > sched_switch event and saw that my RT task still had normal SCHED_OTHER > priority. Looking at the problem commit, I found: > > - p->normal_prio = normal_prio(p); > - p->prio = rt_mutex_getprio(p); > > With no > > + p->normal_prio = normal_prio(p); > + p->prio = rt_mutex_getprio(p); > > Reading what the commit is suppose to do, I realize that the p->prio > can't be set if the task is boosted with a higher prio, but the > p->normal_prio still needs to be set regardless, otherwise, when the > task is deboosted, it wont get the new priority. > > The p->prio has to be set before "check_class_changed()" is called, > otherwise the class wont be changed. > > Also added fix to newprio to include a check for deadline policy that > was missing. This change was suggested by Juri Lelli. > > Link: http://lkml.kernel.org/r/20140306120438.638bfe94@gandalf.local.home > Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> ^ permalink raw reply [flat|nested] 13+ messages in thread
* [tip:sched/core] sched: Fix broken setscheduler() 2014-03-06 17:04 ` [PATCH v2] " Steven Rostedt 2014-03-06 20:43 ` Thomas Gleixner @ 2014-03-12 10:10 ` tip-bot for Steven Rostedt 1 sibling, 0 replies; 13+ messages in thread From: tip-bot for Steven Rostedt @ 2014-03-12 10:10 UTC (permalink / raw) To: linux-tip-commits Cc: linux-kernel, hpa, mingo, peterz, rostedt, tglx, bigeasy, juri.lelli Commit-ID: 383afd0971538b3d77532a56404b24cfe967b5dd Gitweb: http://git.kernel.org/tip/383afd0971538b3d77532a56404b24cfe967b5dd Author: Steven Rostedt <rostedt@goodmis.org> AuthorDate: Tue, 11 Mar 2014 19:24:20 -0400 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Wed, 12 Mar 2014 10:48:59 +0100 sched: Fix broken setscheduler() I decided to run my tests on linux-next, and my wakeup_rt tracer was broken. After running a bisect, I found that the problem commit was: linux-next commit c365c292d059 "sched: Consider pi boosting in setscheduler()" And the reason the wake_rt tracer test was failing, was because it had no RT task to trace. I first noticed this when running with sched_switch event and saw that my RT task still had normal SCHED_OTHER priority. Looking at the problem commit, I found: - p->normal_prio = normal_prio(p); - p->prio = rt_mutex_getprio(p); With no + p->normal_prio = normal_prio(p); + p->prio = rt_mutex_getprio(p); Reading what the commit is suppose to do, I realize that the p->prio can't be set if the task is boosted with a higher prio, but the p->normal_prio still needs to be set regardless, otherwise, when the task is deboosted, it wont get the new priority. The p->prio has to be set before "check_class_changed()" is called, otherwise the class wont be changed. Also added fix to newprio to include a check for deadline policy that was missing. This change was suggested by Juri Lelli. Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Cc: SebastianAndrzej Siewior <bigeasy@linutronix.de> Cc: Juri Lelli <juri.lelli@gmail.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20140306120438.638bfe94@gandalf.local.home Signed-off-by: Ingo Molnar <mingo@kernel.org> --- kernel/sched/core.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 9e126a2..ae365aa 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3195,6 +3195,7 @@ static void __setscheduler_params(struct task_struct *p, * getparam()/getattr() don't report silly values for !rt tasks. */ p->rt_priority = attr->sched_priority; + p->normal_prio = normal_prio(p); set_load_weight(p); } @@ -3204,6 +3205,12 @@ static void __setscheduler(struct rq *rq, struct task_struct *p, { __setscheduler_params(p, attr); + /* + * If we get here, there was no pi waiters boosting the + * task. It is safe to use the normal prio. + */ + p->prio = normal_prio(p); + if (dl_prio(p->prio)) p->sched_class = &dl_sched_class; else if (rt_prio(p->prio)) @@ -3262,7 +3269,8 @@ static int __sched_setscheduler(struct task_struct *p, const struct sched_attr *attr, bool user) { - int newprio = MAX_RT_PRIO - 1 - attr->sched_priority; + int newprio = dl_policy(attr->sched_policy) ? MAX_DL_PRIO - 1 : + MAX_RT_PRIO - 1 - attr->sched_priority; int retval, oldprio, oldpolicy = -1, on_rq, running; int policy = attr->sched_policy; unsigned long flags; ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2014-03-12 10:41 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-03-06 4:29 [PATCH linux-next] sched: Fix broken setscheduler() Steven Rostedt 2014-03-06 11:58 ` Peter Zijlstra 2014-03-06 12:20 ` Juri Lelli 2014-03-06 17:04 ` [PATCH v2] " Steven Rostedt 2014-03-06 20:43 ` Thomas Gleixner 2014-03-10 17:29 ` Steven Rostedt 2014-03-10 21:18 ` Thomas Gleixner 2014-03-10 21:37 ` Steven Rostedt 2014-03-11 9:35 ` Juri Lelli 2014-03-11 10:48 ` Thomas Gleixner 2014-03-11 23:24 ` [PATCH v3] " Steven Rostedt 2014-03-12 10:41 ` Thomas Gleixner 2014-03-12 10:10 ` [tip:sched/core] " tip-bot for Steven Rostedt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
Powered by JetHome