* Does smp_reschedule_interrupt really reschedule?
@ 2005-05-13 18:18 Steven Rostedt
2005-05-13 18:26 ` Ingo Molnar
0 siblings, 1 reply; 6+ messages in thread
From: Steven Rostedt @ 2005-05-13 18:18 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Andrew Morton, LKML
I'm working mostly with Ingo's RT patched kernel, but this may also be a
problem with the vanilla kernel.
Sending out a smp_send_reschedule which causes the
smp_reschedule_interrupt to go off on each CPU. (In Ingo's I was more
concerned with the smp_send_reschedule_allbutself). In
arch/i386/kernel/smp.c there's the following code:
/*
* Reschedule call back. Nothing to do,
* all the work is done automatically when
* we return from the interrupt.
*/
fastcall void smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
}
As the comment says, do nothing since all the work is automatically done
at the return from interrupt. But is it? Doesn't the need_resched need
to be set? Here's what I'm seeing with Ingo's kernel. I capture the
time in sched.c when the smp_send_reschedule_allbutself is called, and
also a capture of the time when the schedule actually takes place. I'm
finding differences up to 2 tenths of a second. That's TENTHS! I added
the following patch:
--- arch/i386/kernel/smp.c (revision 181)
+++ arch/i386/kernel/smp.c (working copy)
@@ -593,6 +593,7 @@
{
trace_special(regs->eip, 0, 0);
ack_APIC_irq();
+ set_tsk_need_resched(current);
}
fastcall void smp_call_function_interrupt(struct pt_regs *regs)
(OK the trace_special is from Ingo's patch, but that's what I was
working with)
Now the largest latency between the call smp_send_reschedule and
schedule being called on another CPU is now 200 micro seconds, which is
much more reasonable. But it also shows that a schedule is not taking
place without it.
Now, is there more logic that I'm missing to determine if the schedule
is not needed. With Ingo's patch, he sends this when two RT tasks are
scheduled on the same CPU and one should migrate. But the time this
takes varies tremendously.
Thanks,
-- Steve
Here's the patch for 2.6.11.6, just in case this is an issue. You just
need to delete the one for Ingo's. And Ingo would need to delete this.
Then again, the above is for a -p0 and this is -p1.
--- a/arch/i386/kernel/smp.c.orig 2005-05-13 14:06:54.000000000 -0400
+++ a/arch/i386/kernel/smp.c 2005-05-13 14:07:28.000000000 -0400
@@ -582,6 +582,7 @@
fastcall void smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
+ set_tsk_need_resched(current);
}
fastcall void smp_call_function_interrupt(struct pt_regs *regs)
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: Does smp_reschedule_interrupt really reschedule?
2005-05-13 18:18 Does smp_reschedule_interrupt really reschedule? Steven Rostedt
@ 2005-05-13 18:26 ` Ingo Molnar
2005-05-13 18:51 ` Steven Rostedt
0 siblings, 1 reply; 6+ messages in thread
From: Ingo Molnar @ 2005-05-13 18:26 UTC (permalink / raw)
To: Steven Rostedt; +Cc: Andrew Morton, LKML
* Steven Rostedt <rostedt@goodmis.org> wrote:
> As the comment says, do nothing since all the work is automatically
> done at the return from interrupt. But is it? Doesn't the
> need_resched need to be set? Here's what I'm seeing with Ingo's
> kernel. I capture the time in sched.c when the
> smp_send_reschedule_allbutself is called, and also a capture of the
> time when the schedule actually takes place. I'm finding differences
> up to 2 tenths of a second. That's TENTHS! I added the following
> patch:
it's all a bit tricky. The short story is that i think both vanilla and
-RT kernels are fine.
Here is how smp_send_reschedule() is used:
CPU#0 CPU#1
set_tsk_need_resched(rq->curr);
...
smp_send_reschedule()
--- IPI --->
smp_reschedule_interrupt();
...
entry.S's need_resched check
_but_, this is intentionally racy: if CPU#1 happens to reschedule before
the IPI reaches CPU#1 (an IPI can take 10 usecs easily so the window is
not small), then need_resched might be cleared before the IPI hits. In
that case you wont get a reschedule after the IPI hits, because it was
done before!
so the correct thing to measure is what the -RT kernel's wakeup-latency
timing feature does: the time from setting need_resched, to the point
the task starts to run. The feature works on SMP too - and it doesnt
show any large latencies.
are you seeing actual process delays? If not then i think those large
latencies are just the result of the wrong assumptions in your
measurement code.
Ingo
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Does smp_reschedule_interrupt really reschedule?
2005-05-13 18:26 ` Ingo Molnar
@ 2005-05-13 18:51 ` Steven Rostedt
2005-05-14 6:37 ` Ingo Molnar
0 siblings, 1 reply; 6+ messages in thread
From: Steven Rostedt @ 2005-05-13 18:51 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Andrew Morton, LKML
On Fri, 2005-05-13 at 20:26 +0200, Ingo Molnar wrote:
> it's all a bit tricky. The short story is that i think both vanilla and
> -RT kernels are fine.
>
> Here is how smp_send_reschedule() is used:
>
> CPU#0 CPU#1
>
> set_tsk_need_resched(rq->curr);
> ...
> smp_send_reschedule()
> --- IPI --->
> smp_reschedule_interrupt();
> ...
> entry.S's need_resched check
>
OK, Forget about vanilla, I'm keeping to your kernel now ;-)
In finish_task_switch, where is need_resched set?
> _but_, this is intentionally racy: if CPU#1 happens to reschedule before
> the IPI reaches CPU#1 (an IPI can take 10 usecs easily so the window is
> not small), then need_resched might be cleared before the IPI hits. In
> that case you wont get a reschedule after the IPI hits, because it was
> done before!
>
> so the correct thing to measure is what the -RT kernel's wakeup-latency
> timing feature does: the time from setting need_resched, to the point
> the task starts to run. The feature works on SMP too - and it doesnt
> show any large latencies.
>
> are you seeing actual process delays? If not then i think those large
> latencies are just the result of the wrong assumptions in your
> measurement code.
No this wasn't from real world applications yet. So the bug may rightly
be with the placement of my timers. I was looking at the code and
didn't know how the reschedule takes place and started testing it. Let
me know where that need_resched is with that finish_task_switch code,
and I'll probably be happy with just that.
Thanks,
-- Steve
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Does smp_reschedule_interrupt really reschedule?
2005-05-13 18:51 ` Steven Rostedt
@ 2005-05-14 6:37 ` Ingo Molnar
2005-05-14 11:32 ` Steven Rostedt
0 siblings, 1 reply; 6+ messages in thread
From: Ingo Molnar @ 2005-05-14 6:37 UTC (permalink / raw)
To: Steven Rostedt; +Cc: Andrew Morton, LKML
* Steven Rostedt <rostedt@goodmis.org> wrote:
> In finish_task_switch, where is need_resched set?
why should it be set? It's the final portion of a context-switch, not
the initiator of a context-switch. need_resched is usually set by the
wakeup code, or by the preemption code.
Ingo
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Does smp_reschedule_interrupt really reschedule?
2005-05-14 6:37 ` Ingo Molnar
@ 2005-05-14 11:32 ` Steven Rostedt
2005-05-14 14:27 ` Ingo Molnar
0 siblings, 1 reply; 6+ messages in thread
From: Steven Rostedt @ 2005-05-14 11:32 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Andrew Morton, LKML
On Sat, 2005-05-14 at 08:37 +0200, Ingo Molnar wrote:
> * Steven Rostedt <rostedt@goodmis.org> wrote:
>
> > In finish_task_switch, where is need_resched set?
>
> why should it be set? It's the final portion of a context-switch, not
> the initiator of a context-switch. need_resched is usually set by the
> wakeup code, or by the preemption code.
>
Sorry, I'm still not seeing it. I'll explain my confusion a little more
detailed now.
Lets say we have a SMP machine with two CPUs. CPU0 has a RT task
running and CPU1 has a non-RT task. A RT task wakes up on CPU0 that is
higher priority than the current running RT task on CPU0. Lets add that
this newly woken up RT task has set affinity to only run on CPU0.
So in try_to_wake_up... Lets assume that the wake up happened on CPU1.
if (cpu == this_cpu || unlikely(!cpu_isset(this_cpu, p->cpus_allowed)))
goto out_set_cpu;
cpu = the task's cpu = CPU0
this_cpu = CPU1
cpu_isset(this_cpu, p->cpus_allowed) returns false so we goto
out_set_cpu.
out_set_cpu:
new_cpu = wake_idle(new_cpu, p); <--- new_cpu would still equal cpu.
if (new_cpu != cpu) {
} else {
/*
* If a newly woken up RT task cannot preempt the
* current (RT) task then try to find another
* CPU it can preempt:
*/
p can preempt current, so this is also false.
if (rt_task(p) && !TASK_PREEMPTS_CURR(p, rq)) {
smp_send_reschedule_allbutself();
rt_overload_wakeup++;
}
}
Next we activate the newly woken up RT task.
activate_task(p, rq, cpu == this_cpu);
if (!sync || cpu != this_cpu) {
if (TASK_PREEMPTS_CURR(p, rq))
resched_task(rq->curr);
}
So now the newly woken up RT task preempts the other RT task on CPU0.
preempt_schedule is called and then schedule.
Now the booted RT task should now be transferred to CPU1, since it can
run there, and CPU1 doesn't have a RT task running.
In finish_task_switch, we have:
#if defined(CONFIG_PREEMPT_RT) && defined(CONFIG_SMP)
/*
* If we pushed an RT task off the runqueue,
* then kick other CPUs, they might run it:
*/
if (unlikely(rt_task(current) && prev->array && rt_task(prev))) {
rt_overload_schedule++;
smp_send_reschedule_allbutself();
}
#endif
Here's my question, where does CPU1 get need_resched set? As discussed
earlier, smp_send_reschedule_allbutself doesn't do it.
Thanks,
-- Steve
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: Does smp_reschedule_interrupt really reschedule?
2005-05-14 11:32 ` Steven Rostedt
@ 2005-05-14 14:27 ` Ingo Molnar
0 siblings, 0 replies; 6+ messages in thread
From: Ingo Molnar @ 2005-05-14 14:27 UTC (permalink / raw)
To: Steven Rostedt; +Cc: Andrew Morton, LKML
* Steven Rostedt <rostedt@goodmis.org> wrote:
> In finish_task_switch, we have:
>
> #if defined(CONFIG_PREEMPT_RT) && defined(CONFIG_SMP)
> /*
> * If we pushed an RT task off the runqueue,
> * then kick other CPUs, they might run it:
> */
> if (unlikely(rt_task(current) && prev->array && rt_task(prev))) {
> rt_overload_schedule++;
> smp_send_reschedule_allbutself();
> }
> #endif
>
>
> Here's my question, where does CPU1 get need_resched set? As
> discussed earlier, smp_send_reschedule_allbutself doesn't do it.
hm, you are right - the 'kick other CPUs' portion of RT-overload
handling (which is a new scheduler feature currently being tested in the
-RT kernel) is missing this step. So we might as well force a reschedule
from the IPI handler - the way you suggested it. We might overdo
scheduling a bit, but it cannot hurt - and it will definitely make a
difference for the case where an RT task is waiting to be run.
the vanilla kernel is not affected.
Ingo
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2005-05-14 14:28 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-13 18:18 Does smp_reschedule_interrupt really reschedule? Steven Rostedt
2005-05-13 18:26 ` Ingo Molnar
2005-05-13 18:51 ` Steven Rostedt
2005-05-14 6:37 ` Ingo Molnar
2005-05-14 11:32 ` Steven Rostedt
2005-05-14 14:27 ` Ingo Molnar
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.