* Re: [patch] f83f9ac causes tasks running at MAX_PRIO
2009-12-02 11:46 ` Peter Zijlstra
@ 2009-12-02 12:49 ` Mike Galbraith
2009-12-03 1:25 ` Peter Williams
2009-12-02 14:03 ` Steven Rostedt
2009-12-09 9:55 ` [tip:sched/urgent] sched: Fix task priority bug tip-bot for Peter Zijlstra
2 siblings, 1 reply; 9+ messages in thread
From: Mike Galbraith @ 2009-12-02 12:49 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Ingo Molnar, Peter Williams, LKML, Steven Rostedt, Thomas Gleixner
On Wed, 2009-12-02 at 12:46 +0100, Peter Zijlstra wrote:
> init_idle() doing:
> idle->prio = idle->normal_prio = MAX_PRIO;
>
> Which will propagate... like reported.
>
> Now, since the idle-threads usually run on &idle_sched_class, nobody
> will actually look at their ->prio, so having that out-of-range might
> make sense.
>
> Just needs to get fixed up when we fork a normal thread, which would be
> in sched_fork(), now your call to normal_prio() fixes this by setting
> everything to ->static_prio for SCHED_OTHER tasks, however
>
> migration_call()
> CPU_DEAD:
> rq->idle->static_prio = MAX_PRIO;
>
> spoils that too..
Darn.
> Ingo, any particular reason we set idle threads at MAX_PRIO? Can't we
> simply do something like below and be done with it?
Hysterical reasons? That might have been a doorstop conversion kit for
O(1), but boots fine with CFS, and prio 40 tasks are history.
> ---
> kernel/sched.c | 2 --
> 1 files changed, 0 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/sched.c b/kernel/sched.c
> index c0e4e9d..5ad5a66 100644
> --- a/kernel/sched.c
> +++ b/kernel/sched.c
> @@ -6963,7 +6963,6 @@ void __cpuinit init_idle(struct task_struct *idle,
> int cpu)
> __sched_fork(idle);
> idle->se.exec_start = sched_clock();
>
> - idle->prio = idle->normal_prio = MAX_PRIO;
> cpumask_copy(&idle->cpus_allowed, cpumask_of(cpu));
> __set_task_cpu(idle, cpu);
>
> @@ -7667,7 +7666,6 @@ migration_call(struct notifier_block *nfb,
> unsigned long action, void *hcpu)
> spin_lock_irq(&rq->lock);
> update_rq_clock(rq);
> deactivate_task(rq, rq->idle, 0);
> - rq->idle->static_prio = MAX_PRIO;
> __setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
> rq->idle->sched_class = &idle_sched_class;
> migrate_dead_tasks(cpu);
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] f83f9ac causes tasks running at MAX_PRIO
2009-12-02 12:49 ` Mike Galbraith
@ 2009-12-03 1:25 ` Peter Williams
2009-12-03 1:44 ` Mike Galbraith
2009-12-03 10:02 ` Peter Zijlstra
0 siblings, 2 replies; 9+ messages in thread
From: Peter Williams @ 2009-12-03 1:25 UTC (permalink / raw)
To: Mike Galbraith, Peter Zijlstra, Ingo Molnar
Cc: LKML, Steven Rostedt, Thomas Gleixner
On 02/12/09 22:49, Mike Galbraith wrote:
> Hysterical reasons? That might have been a doorstop conversion kit for
> O(1), but boots fine with CFS, and prio 40 tasks are history.
In my (not so) humble opinion, there is still a lot of unnecessary cruft
in sched.c that should have been removed as the final (clean up) stage
of implementing CFS (i.e. stuff that was needed for O(1) but no longer
serves a useful purpose). I know that the extra overhead of this code
is probably inconsequential (and the compiler may even optimize some of
it away) but it looks untidy and makes the code harder to understand.
Recent patches that I've submitted were intended as a start to removing
some of this cruft and I had intended to send more patches after they
were accepted. I figured that it was better to do it as a number of
small changes rather than one big one. Should I continue?
Peter
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] f83f9ac causes tasks running at MAX_PRIO
2009-12-03 1:25 ` Peter Williams
@ 2009-12-03 1:44 ` Mike Galbraith
2009-12-03 10:02 ` Peter Zijlstra
1 sibling, 0 replies; 9+ messages in thread
From: Mike Galbraith @ 2009-12-03 1:44 UTC (permalink / raw)
To: Peter Williams
Cc: Peter Zijlstra, Ingo Molnar, LKML, Steven Rostedt, Thomas Gleixner
On Thu, 2009-12-03 at 11:25 +1000, Peter Williams wrote:
> On 02/12/09 22:49, Mike Galbraith wrote:
> > Hysterical reasons? That might have been a doorstop conversion kit for
> > O(1), but boots fine with CFS, and prio 40 tasks are history.
>
> In my (not so) humble opinion, there is still a lot of unnecessary cruft
> in sched.c that should have been removed as the final (clean up) stage
> of implementing CFS (i.e. stuff that was needed for O(1) but no longer
> serves a useful purpose). I know that the extra overhead of this code
> is probably inconsequential (and the compiler may even optimize some of
> it away) but it looks untidy and makes the code harder to understand.
>
> Recent patches that I've submitted were intended as a start to removing
> some of this cruft and I had intended to send more patches after they
> were accepted. I figured that it was better to do it as a number of
> small changes rather than one big one. Should I continue?
Certainly.
-Mike
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] f83f9ac causes tasks running at MAX_PRIO
2009-12-03 1:25 ` Peter Williams
2009-12-03 1:44 ` Mike Galbraith
@ 2009-12-03 10:02 ` Peter Zijlstra
1 sibling, 0 replies; 9+ messages in thread
From: Peter Zijlstra @ 2009-12-03 10:02 UTC (permalink / raw)
To: Peter Williams
Cc: Mike Galbraith, Ingo Molnar, LKML, Steven Rostedt, Thomas Gleixner
On Thu, 2009-12-03 at 11:25 +1000, Peter Williams wrote:
> Recent patches that I've submitted were intended as a start to removing
> some of this cruft and I had intended to send more patches after they
> were accepted. I figured that it was better to do it as a number of
> small changes rather than one big one. Should I continue?
Please, feel free to clean that up.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] f83f9ac causes tasks running at MAX_PRIO
2009-12-02 11:46 ` Peter Zijlstra
2009-12-02 12:49 ` Mike Galbraith
@ 2009-12-02 14:03 ` Steven Rostedt
2009-12-02 16:51 ` Mike Galbraith
2009-12-09 9:55 ` [tip:sched/urgent] sched: Fix task priority bug tip-bot for Peter Zijlstra
2 siblings, 1 reply; 9+ messages in thread
From: Steven Rostedt @ 2009-12-02 14:03 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Mike Galbraith, Ingo Molnar, Peter Williams, LKML, Thomas Gleixner
On Wed, 2009-12-02 at 12:46 +0100, Peter Zijlstra wrote:
> On Sun, 2009-11-29 at 14:23 +0100, Mike Galbraith wrote:
>
> > sched: fix task priority bug.
> >
> > f83f9ac removed a call to effective_prio() in wake_up_new_task(), which
> > leads to tasks running at MAX_PRIO. That call set both the child's prio
> > and normal_prio fields to normal_prio(child). Do the same fork time by
> > setting both to normal_prio(parent).
> >
> > Signed-off-by: Mike Galbraith <efault@gmx.de>
> > Cc: Ingo Molnar <mingo@elte.hu>
> > Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > Cc: Peter Williams <pwil3058@bigpond.net.au>
> > LKML-Reference: <new-submission>
> >
> > ---
> > kernel/sched.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > Index: linux-2.6/kernel/sched.c
> > ===================================================================
> > --- linux-2.6.orig/kernel/sched.c
> > +++ linux-2.6/kernel/sched.c
> > @@ -2609,7 +2609,7 @@ void sched_fork(struct task_struct *p, i
> > /*
> > * Make sure we do not leak PI boosting priority to the child.
> > */
> > - p->prio = current->normal_prio;
> > + p->prio = p->normal_prio = normal_prio(current);
> >
> > if (!rt_prio(p->prio))
> > p->sched_class = &fair_sched_class;
> >
>
> Damn PI stuff makes my head hurt ;-)
I recommend Advil
>
> So we've got:
>
> ->prio - the actual effective priority [ prio scale ]
> ->normal_prio - the task's normal priority [ prio scale ]
> ->static_prio - SCHED_OTHER's nice value [ prio scale ]
> ->rt_priority - SCHED_FIFO/RR prio value [ sched_param scale ]
>
> [ with prio scale being:
>
> [0, MAX_RT_PRIO-1] [MAX_RT_PRIO, MAX_PRIO-1]
> RT-100, RT-99..RT-1 NICE-20, NICE+19
> ]
>
> So at sched_fork() we do the
>
> p->prio = p->normal_prio;
>
> thing, to unboost.
>
> If that results in MAX_PRIO, then our parent's ->normal_prio is stuffed.
>
> Looking at the code I can see that happening because we've got:
>
> init_idle() doing:
> idle->prio = idle->normal_prio = MAX_PRIO;
But this is only called on the idle task, which should never fork.
>
> Which will propagate... like reported.
>
> Now, since the idle-threads usually run on &idle_sched_class, nobody
> will actually look at their ->prio, so having that out-of-range might
> make sense.
>
> Just needs to get fixed up when we fork a normal thread, which would be
> in sched_fork(), now your call to normal_prio() fixes this by setting
> everything to ->static_prio for SCHED_OTHER tasks, however
>
> migration_call()
> CPU_DEAD:
> rq->idle->static_prio = MAX_PRIO;
>
> spoils that too, then again, at that point nothing will fork from that
> idle thread.
Well, that is when the CPU is dead, right?
>
> Funny thing though, INIT_TASK() sets everything at MAX_PRIO-20.
Right, because the init task will fork. But once a task becomes idle, it
should never do anything (but service interrupts).
>
> Ingo, any particular reason we set idle threads at MAX_PRIO? Can't we
> simply do something like below and be done with it?
There probably isn't any reason this can't be done, but I'm thinking we
may be papering over a bug instead of solving one.
-- Steve
>
> ---
> kernel/sched.c | 2 --
> 1 files changed, 0 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/sched.c b/kernel/sched.c
> index c0e4e9d..5ad5a66 100644
> --- a/kernel/sched.c
> +++ b/kernel/sched.c
> @@ -6963,7 +6963,6 @@ void __cpuinit init_idle(struct task_struct *idle,
> int cpu)
> __sched_fork(idle);
> idle->se.exec_start = sched_clock();
>
> - idle->prio = idle->normal_prio = MAX_PRIO;
> cpumask_copy(&idle->cpus_allowed, cpumask_of(cpu));
> __set_task_cpu(idle, cpu);
>
> @@ -7667,7 +7666,6 @@ migration_call(struct notifier_block *nfb,
> unsigned long action, void *hcpu)
> spin_lock_irq(&rq->lock);
> update_rq_clock(rq);
> deactivate_task(rq, rq->idle, 0);
> - rq->idle->static_prio = MAX_PRIO;
> __setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
> rq->idle->sched_class = &idle_sched_class;
> migrate_dead_tasks(cpu);
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] f83f9ac causes tasks running at MAX_PRIO
2009-12-02 14:03 ` Steven Rostedt
@ 2009-12-02 16:51 ` Mike Galbraith
0 siblings, 0 replies; 9+ messages in thread
From: Mike Galbraith @ 2009-12-02 16:51 UTC (permalink / raw)
To: rostedt
Cc: Peter Zijlstra, Ingo Molnar, Peter Williams, LKML, Thomas Gleixner
On Wed, 2009-12-02 at 09:03 -0500, Steven Rostedt wrote:
> On Wed, 2009-12-02 at 12:46 +0100, Peter Zijlstra wrote:
> > Funny thing though, INIT_TASK() sets everything at MAX_PRIO-20.
>
> Right, because the init task will fork. But once a task becomes idle, it
> should never do anything (but service interrupts).
Seems it forks _as_ the idle thread..
/*
* Make us the idle thread. Technically, schedule() should not be
* called from this thread, however somewhere below it might be,
* but because we are the idle thread, we just pick up running again
* when this runqueue becomes "idle".
*/
init_idle(current, smp_processor_id());
calc_load_update = jiffies + LOAD_FREQ;
/*
* During early bootup we pretend to be a normal task:
*/
current->sched_class = &fair_sched_class;
..init task becomes the idle thread in sched_init().. gets to
rest_init(), forks with prio and normal_prio now at MAX_PRIO, but
static_prio still at NICE_0.
Peter's change looks OK unless I'm missing something. Though...
static void pull_task(struct rq *src_rq, struct task_struct *p,
struct rq *this_rq, int this_cpu)
{
deactivate_task(src_rq, p, 0);
set_task_cpu(p, this_cpu);
activate_task(this_rq, p, 0);
/*
* Note that idle threads have a prio of MAX_PRIO, for this test
* to be always true for them.
*/
check_preempt_curr(this_rq, p, 0);
}
..we have some O(1) comments for future generations to ponder.
-Mike
^ permalink raw reply [flat|nested] 9+ messages in thread
* [tip:sched/urgent] sched: Fix task priority bug
2009-12-02 11:46 ` Peter Zijlstra
2009-12-02 12:49 ` Mike Galbraith
2009-12-02 14:03 ` Steven Rostedt
@ 2009-12-09 9:55 ` tip-bot for Peter Zijlstra
2 siblings, 0 replies; 9+ messages in thread
From: tip-bot for Peter Zijlstra @ 2009-12-09 9:55 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, a.p.zijlstra, efault, tglx, mingo
Commit-ID: 57785df5ac53c70da9fb53696130f3c551bfe1f9
Gitweb: http://git.kernel.org/tip/57785df5ac53c70da9fb53696130f3c551bfe1f9
Author: Peter Zijlstra <a.p.zijlstra@chello.nl>
AuthorDate: Fri, 4 Dec 2009 09:59:02 +0100
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 9 Dec 2009 10:03:10 +0100
sched: Fix task priority bug
83f9ac removed a call to effective_prio() in wake_up_new_task(), which
leads to tasks running at MAX_PRIO.
This is caused by the idle thread being set to MAX_PRIO before forking
off init. O(1) used that to make sure idle was always preempted, CFS
uses check_preempt_curr_idle() for that so we can savely remove this bit
of legacy code.
Reported-by: Mike Galbraith <efault@gmx.de>
Tested-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1259754383.4003.610.camel@laptop>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/sched.c | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/kernel/sched.c b/kernel/sched.c
index 71eb062..3878f50 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -3158,10 +3158,6 @@ static void pull_task(struct rq *src_rq, struct task_struct *p,
deactivate_task(src_rq, p, 0);
set_task_cpu(p, this_cpu);
activate_task(this_rq, p, 0);
- /*
- * Note that idle threads have a prio of MAX_PRIO, for this test
- * to be always true for them.
- */
check_preempt_curr(this_rq, p, 0);
}
@@ -6992,7 +6988,6 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
__sched_fork(idle);
idle->se.exec_start = sched_clock();
- idle->prio = idle->normal_prio = MAX_PRIO;
cpumask_copy(&idle->cpus_allowed, cpumask_of(cpu));
__set_task_cpu(idle, cpu);
@@ -7696,7 +7691,6 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
spin_lock_irq(&rq->lock);
update_rq_clock(rq);
deactivate_task(rq, rq->idle, 0);
- rq->idle->static_prio = MAX_PRIO;
__setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
rq->idle->sched_class = &idle_sched_class;
migrate_dead_tasks(cpu);
^ permalink raw reply [flat|nested] 9+ messages in thread