2009-09-23 04:54:49

by Peter Williams

[permalink] [raw]
Subject: [PATCH] sched: Make sure task has correct sched_class after policy change

>From the code in rt_mutex_setprio(), it is evident that the intention
is that task's with a RT 'prio' value as a consequence of receiving a PI
boost also have their 'sched_class' field set to '&rt_sched_class'.
However, the code in __setscheduler() could result in this intention
being frustrated.

This patch fixes this problem.

Signed-off-by: Peter Williams <[email protected]>

diff --git a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6159,6 +6159,8 @@ __setscheduler(struct rq *rq, struct tas
p->normal_prio = normal_prio(p);
/* we are holding p->pi_lock already */
p->prio = rt_mutex_getprio(p);
+ if (rt_prio(p->prio))
+ p->sched_class = &rt_sched_class;
set_load_weight(p);
}


2009-09-23 06:32:51

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH] sched: Make sure task has correct sched_class after policy change

On Wed, 2009-09-23 at 02:21 +0000, Peter Williams wrote:
> From the code in rt_mutex_setprio(), it is evident that the intention
> is that task's with a RT 'prio' value as a consequence of receiving a PI
> boost also have their 'sched_class' field set to '&rt_sched_class'.
> However, the code in __setscheduler() could result in this intention
> being frustrated.
>
> This patch fixes this problem.
>
> Signed-off-by: Peter Williams <[email protected]>

I think you're right, but the problem seems to be that it sets
sched_class based on policy, which seems fragile in the face of PI.

How about the alternative below?

---
kernel/sched.c | 17 ++++-------------
1 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index 91843ba..753a52c 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6129,23 +6129,14 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
{
BUG_ON(p->se.on_rq);

- p->policy = policy;
- switch (p->policy) {
- case SCHED_NORMAL:
- case SCHED_BATCH:
- case SCHED_IDLE:
- p->sched_class = &fair_sched_class;
- break;
- case SCHED_FIFO:
- case SCHED_RR:
- p->sched_class = &rt_sched_class;
- break;
- }
-
p->rt_priority = prio;
p->normal_prio = normal_prio(p);
/* we are holding p->pi_lock already */
p->prio = rt_mutex_getprio(p);
+ if (rt_prio(p->prio))
+ p->sched_class = &rt_sched_class;
+ else
+ p->sched_class = &fair_sched_class;
set_load_weight(p);
}


2009-09-23 12:40:27

by Peter Williams

[permalink] [raw]
Subject: Re: [PATCH] sched: Make sure task has correct sched_class after policy change

On 23/09/09 16:32, Peter Zijlstra wrote:
> On Wed, 2009-09-23 at 02:21 +0000, Peter Williams wrote:
>> From the code in rt_mutex_setprio(), it is evident that the intention
>> is that task's with a RT 'prio' value as a consequence of receiving a PI
>> boost also have their 'sched_class' field set to '&rt_sched_class'.
>> However, the code in __setscheduler() could result in this intention
>> being frustrated.
>>
>> This patch fixes this problem.
>>
>> Signed-off-by: Peter Williams<[email protected]>
>
> I think you're right, but the problem seems to be that it sets
> sched_class based on policy, which seems fragile in the face of PI.
>
> How about the alternative below?

Yes, that's what I meant to do i.e. use p->prio in the if condition. I
sent a second patch with a fix but your solution is neater :-).

>
> ---
> kernel/sched.c | 17 ++++-------------
> 1 files changed, 4 insertions(+), 13 deletions(-)
>
> diff --git a/kernel/sched.c b/kernel/sched.c
> index 91843ba..753a52c 100644
> --- a/kernel/sched.c
> +++ b/kernel/sched.c
> @@ -6129,23 +6129,14 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
> {
> BUG_ON(p->se.on_rq);
>
> - p->policy = policy;
> - switch (p->policy) {
> - case SCHED_NORMAL:
> - case SCHED_BATCH:
> - case SCHED_IDLE:
> - p->sched_class =&fair_sched_class;
> - break;
> - case SCHED_FIFO:
> - case SCHED_RR:
> - p->sched_class =&rt_sched_class;
> - break;
> - }
> -
> p->rt_priority = prio;
> p->normal_prio = normal_prio(p);
> /* we are holding p->pi_lock already */
> p->prio = rt_mutex_getprio(p);
> + if (rt_prio(p->prio))
> + p->sched_class =&rt_sched_class;
> + else
> + p->sched_class =&fair_sched_class;
> set_load_weight(p);
> }

Peter
--
Peter Williams [email protected]

"Learning, n. The kind of ignorance distinguishing the studious."
-- Ambrose Bierce

2009-10-12 00:37:39

by Peter Williams

[permalink] [raw]
Subject: Re: [PATCH] sched: Make sure task has correct sched_class after policy change

On 23/09/09 22:40, Peter Williams wrote:
> On 23/09/09 16:32, Peter Zijlstra wrote:
>> On Wed, 2009-09-23 at 02:21 +0000, Peter Williams wrote:
>>> From the code in rt_mutex_setprio(), it is evident that the intention
>>> is that task's with a RT 'prio' value as a consequence of receiving a PI
>>> boost also have their 'sched_class' field set to '&rt_sched_class'.
>>> However, the code in __setscheduler() could result in this intention
>>> being frustrated.
>>>
>>> This patch fixes this problem.
>>>
>>> Signed-off-by: Peter Williams<[email protected]>
>>
>> I think you're right, but the problem seems to be that it sets
>> sched_class based on policy, which seems fragile in the face of PI.
>>
>> How about the alternative below?
>
> Yes, that's what I meant to do i.e. use p->prio in the if condition. I
> sent a second patch with a fix but your solution is neater :-).
>
>>
>> ---
>> kernel/sched.c | 17 ++++-------------
>> 1 files changed, 4 insertions(+), 13 deletions(-)
>>
>> diff --git a/kernel/sched.c b/kernel/sched.c
>> index 91843ba..753a52c 100644
>> --- a/kernel/sched.c
>> +++ b/kernel/sched.c
>> @@ -6129,23 +6129,14 @@ __setscheduler(struct rq *rq, struct
>> task_struct *p, int policy, int prio)
>> {
>> BUG_ON(p->se.on_rq);
>>
>> - p->policy = policy;
>> - switch (p->policy) {
>> - case SCHED_NORMAL:
>> - case SCHED_BATCH:
>> - case SCHED_IDLE:
>> - p->sched_class =&fair_sched_class;
>> - break;
>> - case SCHED_FIFO:
>> - case SCHED_RR:
>> - p->sched_class =&rt_sched_class;
>> - break;
>> - }
>> -
>> p->rt_priority = prio;
>> p->normal_prio = normal_prio(p);
>> /* we are holding p->pi_lock already */
>> p->prio = rt_mutex_getprio(p);
>> + if (rt_prio(p->prio))
>> + p->sched_class =&rt_sched_class;
>> + else
>> + p->sched_class =&fair_sched_class;
>> set_load_weight(p);
>> }
>
> Peter

What ever happened to this patch? It doesn't seem to have made it into
the main line yet.

Cheers
Peter
--
Peter Williams [email protected]

"Learning, n. The kind of ignorance distinguishing the studious."
-- Ambrose Bierce

2009-10-12 15:34:57

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH] sched: Make sure task has correct sched_class after policy change

On Mon, 2009-10-12 at 10:36 +1000, Peter Williams wrote:

> What ever happened to this patch? It doesn't seem to have made it into
> the main line yet.

I,.. uhm,.. guess I'm turning senile and utterly forgot about it.

Queued it, thanks for reminding me!

2009-10-14 13:15:29

by Peter Zijlstra

[permalink] [raw]
Subject: [tip:sched/urgent] sched: Make sure task has correct sched_class after policy change

Commit-ID: 67d08dfed042855431dc99c9e0e6f6f7e85737ef
Gitweb: http://git.kernel.org/tip/67d08dfed042855431dc99c9e0e6f6f7e85737ef
Author: Peter Zijlstra <[email protected]>
AuthorDate: Mon, 12 Oct 2009 17:20:54 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Wed, 14 Oct 2009 15:02:35 +0200

sched: Make sure task has correct sched_class after policy change

>From the code in rt_mutex_setprio(), it is evident that the
intention is that task's with a RT 'prio' value as a consequence of
receiving a PI boost also have their 'sched_class' field set to
'&rt_sched_class'.

However, Peter noticed that the code in __setscheduler() could
result in this intention being frustrated. Fix it.

Reported-by: Peter Williams <[email protected]>
Signed-off-by: Peter Zijlstra <[email protected]>
LKML-Reference: <1253687579.7695.89.camel@twins>
Signed-off-by: Ingo Molnar <[email protected]>
---
kernel/sched.c | 17 ++++-------------
1 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index 789001d..2d7a002 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6145,23 +6145,14 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
{
BUG_ON(p->se.on_rq);

- p->policy = policy;
- switch (p->policy) {
- case SCHED_NORMAL:
- case SCHED_BATCH:
- case SCHED_IDLE:
- p->sched_class = &fair_sched_class;
- break;
- case SCHED_FIFO:
- case SCHED_RR:
- p->sched_class = &rt_sched_class;
- break;
- }
-
p->rt_priority = prio;
p->normal_prio = normal_prio(p);
/* we are holding p->pi_lock already */
p->prio = rt_mutex_getprio(p);
+ if (rt_prio(p->prio))
+ p->sched_class = &rt_sched_class;
+ else
+ p->sched_class = &fair_sched_class;
set_load_weight(p);
}