For future rework of try_to_wake_up() we'd like to push part of that
onto the CPU the task is actually going to run on, in order to do so we
need a generic callback from the existing scheduler IPI.
This patch introduces such a generic callback: scheduler_ipi() and
implements it as a NOP.
I visited existing smp_send_reschedule() implementations and tried to
add a call to scheduler_ipi() in their handler part, but esp. for MIPS
I'm not quite sure I actually got all of them.
Also, while reading through all this, I noticed the blackfin SMP code
looks to be broken, it simply discards any IPI when low on memory.
Signed-off-by: Peter Zijlstra <redacted>
---
arch/alpha/kernel/smp.c | 1 +
arch/arm/kernel/smp.c | 1 +
arch/blackfin/mach-common/smp.c | 3 ++-
arch/cris/arch-v32/kernel/smp.c | 13 ++++++++-----
arch/ia64/kernel/irq_ia64.c | 2 ++
arch/ia64/xen/irq_xen.c | 10 +++++++++-
arch/m32r/kernel/smp.c | 2 +-
arch/mips/kernel/smtc.c | 1 +
arch/mips/sibyte/bcm1480/smp.c | 7 +++----
arch/mips/sibyte/sb1250/smp.c | 7 +++----
arch/mn10300/kernel/smp.c | 2 +-
arch/parisc/kernel/smp.c | 1 +
arch/powerpc/kernel/smp.c | 1 +
arch/s390/kernel/smp.c | 6 +++---
arch/sh/kernel/smp.c | 2 ++
arch/sparc/kernel/smp_32.c | 2 +-
arch/sparc/kernel/smp_64.c | 1 +
arch/tile/kernel/smp.c | 1 +
arch/um/kernel/smp.c | 2 +-
arch/x86/kernel/smp.c | 1 +
arch/x86/xen/smp.c | 1 +
include/linux/sched.h | 1 +
22 files changed, 46 insertions(+), 22 deletions(-)
nce)
case BFIN_IPI_RESCHEDULE:
/* That's the easiest one; leave it to
* return_from_int. */
+ scheduler_ipi();
kfree(msg);
break;
case BFIN_IPI_CALL_FUNC:
@@ -92,6 +92,8 @@ static unsigned short saved_irq_cnt;staticintxen_slab_ready;
=20
#ifdef CONFIG_SMP
+#include <linux/sched.h>
+
/* Dummy stub. Though we may check XEN_RESCHEDULE_VECTOR before __do_IRQ,
* it ends up to issue several memory accesses upon percpu data and
* thus adds unnecessary traffic to other paths.
ipi)
static void ipi_resched_interrupt(void)
{
/* Return from interrupt should be enough to cause scheduler check */
+ scheduler_ipi();
}
=20
static void ipi_call_interrupt(void)
@@ -189,10 +190,8 @@ void bcm1480_mailbox_interrupt(void) /* Clear the mailbox to clear the interrupt */ __raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]);
=20
- /*
- * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
- * interrupt will do the reschedule for us
- */
+ if (actione & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
=20
if (action & SMP_CALL_FUNCTION)
smp_call_function_interrupt();
@@ -177,10 +178,8 @@ void sb1250_mailbox_interrupt(void) /* Clear the mailbox to clear the interrupt */ ____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
=20
- /*
- * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
- * interrupt will do the reschedule for us
- */
+ if (action & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
=20
if (action & SMP_CALL_FUNCTION)
smp_call_function_interrupt();
data)
static irqreturn_t reschedule_action(int irq, void *data)
{
/* we just need the return path side effect of checking need_resched */
+ scheduler_ipi();
return IRQ_HANDLED;
}
=20
@@ -163,12 +163,12 @@ static void do_ext_call_interrupt(unsigned int ext_in=
t_code,
=20
/*
* handle bit signal external calls
- *
- * For the ec_schedule signal we have to do nothing. All the work
- * is done automatically when we return from the interrupt.
*/
bits =3D xchg(&S390_lowcore.ext_call_fast, 0);
=20
+ if (test_bit(ec_schedule, &bits))
+ scheduler_ipi();
+
if (test_bit(ec_call_function, &bits))
generic_smp_call_function_interrupt();
=20
Maybe remove the comment "everything is done on the interrupt return path"
as with this function call, that is no longer the case.
Looks like the same is true for Alpha as well?
From: Peter Zijlstra <peterz@infradead.org> Date: 2011-01-17 11:42:28
On Mon, 2011-01-17 at 12:31 +0100, Peter Zijlstra wrote:
On Mon, 2011-01-17 at 11:26 +0000, Russell King - ARM Linux wrote:
quoted
Maybe remove the comment "everything is done on the interrupt return pa=
th"
quoted
as with this function call, that is no longer the case.
(Removed am33, m32r-ka, m32r, arm-kernel lists because they kept sending
bounces)
---
Subject: sched: provide scheduler_ipi() callback in response to smp_send_re=
schedule()
From: Peter Zijlstra <peterz@infradead.org>
Date: Mon, 17 Jan 2011 12:07:13 +0100
For future rework of try_to_wake_up() we'd like to push part of that
onto the CPU the task is actually going to run on, in order to do so we
need a generic callback from the existing scheduler IPI.
This patch introduces such a generic callback: scheduler_ipi() and
implements it as a NOP.
I visited existing smp_send_reschedule() implementations and tried to
add a call to scheduler_ipi() in their handler part, but esp. for MIPS
I'm not quite sure I actually got all of them.
Also, while reading through all this, I noticed the blackfin SMP code
looks to be broken, it simply discards any IPI when low on memory.
Signed-off-by: Peter Zijlstra <redacted>
LKML-Reference: <new-submission>
---
arch/alpha/kernel/smp.c | 3 +--
arch/arm/kernel/smp.c | 5 +----
arch/blackfin/mach-common/smp.c | 5 ++---
arch/cris/arch-v32/kernel/smp.c | 13 ++++++++-----
arch/ia64/kernel/irq_ia64.c | 2 ++
arch/ia64/xen/irq_xen.c | 10 +++++++++-
arch/m32r/kernel/smp.c | 4 +---
arch/mips/kernel/smtc.c | 2 +-
arch/mips/sibyte/bcm1480/smp.c | 7 +++----
arch/mips/sibyte/sb1250/smp.c | 7 +++----
arch/mn10300/kernel/smp.c | 5 +----
arch/parisc/kernel/smp.c | 5 +----
arch/powerpc/kernel/smp.c | 2 +-
arch/s390/kernel/smp.c | 6 +++---
arch/sh/kernel/smp.c | 2 ++
arch/sparc/kernel/smp_32.c | 2 +-
arch/sparc/kernel/smp_64.c | 1 +
arch/tile/kernel/smp.c | 6 +-----
arch/um/kernel/smp.c | 2 +-
arch/x86/kernel/smp.c | 5 ++---
arch/x86/xen/smp.c | 5 ++---
include/linux/sched.h | 1 +
22 files changed, 48 insertions(+), 52 deletions(-)
Index: linux-2.6/arch/alpha/kernel/smp.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=20
switch (which) {
case IPI_RESCHEDULE:
- /* Reschedule callback. Everything to be done
- is done by the interrupt return path. */
+ scheduler_ipi();
break;
=20
case IPI_CALL_FUNC:
Index: linux-2.6/arch/arm/kernel/smp.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=20
case IPI_RESCHEDULE:
- /*
- * nothing more to do - eveything is
- * done on the interrupt return path
- */
+ scheduler_ipi();
break;
=20
case IPI_CALL_FUNC:
Index: linux-2.6/arch/blackfin/mach-common/smp.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
@@ -92,6 +92,8 @@ static unsigned short saved_irq_cnt;staticintxen_slab_ready;
=20
#ifdef CONFIG_SMP
+#include <linux/sched.h>
+
/* Dummy stub. Though we may check XEN_RESCHEDULE_VECTOR before __do_IRQ,
* it ends up to issue several memory accesses upon percpu data and
* thus adds unnecessary traffic to other paths.
@@ -189,10 +190,8 @@ void bcm1480_mailbox_interrupt(void) /* Clear the mailbox to clear the interrupt */ __raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]);
=20
- /*
- * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
- * interrupt will do the reschedule for us
- */
+ if (actione & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
=20
if (action & SMP_CALL_FUNCTION)
smp_call_function_interrupt();
Index: linux-2.6/arch/mips/sibyte/sb1250/smp.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
@@ -177,10 +178,8 @@ void sb1250_mailbox_interrupt(void) /* Clear the mailbox to clear the interrupt */ ____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
=20
- /*
- * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
- * interrupt will do the reschedule for us
- */
+ if (action & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
=20
if (action & SMP_CALL_FUNCTION)
smp_call_function_interrupt();
Index: linux-2.6/arch/mn10300/kernel/smp.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=20
/*
* handle bit signal external calls
- *
- * For the ec_schedule signal we have to do nothing. All the work
- * is done automatically when we return from the interrupt.
*/
bits =3D xchg(&S390_lowcore.ext_call_fast, 0);
=20
+ if (test_bit(ec_schedule, &bits))
+ scheduler_ipi();
+
if (test_bit(ec_call_function, &bits))
generic_smp_call_function_interrupt();
=20
Index: linux-2.6/arch/sh/kernel/smp.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=20
/* This is a nop because we capture all other cpus
Index: linux-2.6/arch/tile/kernel/smp.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
@@ -184,12 +184,8 @@ void flush_icache_range(unsigned long st/* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */staticirqreturn_thandle_reschedule_ipi(intirq,void*token){-/*-*Nothingtodohere;whenwereturnfrominterrupt,the-*reschedulingwilloccurthere.Butdobumptheinterrupt-*profilercountinthemeantime.-*/__get_cpu_var(irq_stat).irq_resched_count++;+scheduler_ipi();
=20
/*
- * Reschedule call back. Nothing to do,
- * all the work is done automatically when
- * we return from the interrupt.
+ * Reschedule call back.
*/
void smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
inc_irq_stat(irq_resched_count);
+ scheduler_ipi();
/*
* KVM uses this interrupt to force a cpu out of guest mode
*/
Index: linux-2.6/arch/x86/xen/smp.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
From: Martin Schwidefsky <hidden> Date: 2011-01-17 12:18:23
On Mon, 17 Jan 2011 12:07:13 +0100
Peter Zijlstra [off-list ref] wrote:
quoted hunk
I visited existing smp_send_reschedule() implementations and tried to
add a call to scheduler_ipi() in their handler part, but esp. for MIPS
I'm not quite sure I actually got all of them.
@@ -184,12 +184,8 @@ void flush_icache_range(unsigned long st/* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */staticirqreturn_thandle_reschedule_ipi(intirq,void*token){-/*-*Nothingtodohere;whenwereturnfrominterrupt,the-*reschedulingwilloccurthere.Butdobumptheinterrupt-*profilercountinthemeantime.-*/__get_cpu_var(irq_stat).irq_resched_count++;+scheduler_ipi();returnIRQ_HANDLED;}
Acked-by: Chris Metcalf <redacted>
--
Chris Metcalf, Tilera Corp.
http://www.tilera.com
From: David Daney <hidden> Date: 2011-01-17 19:19:17
On 01/17/2011 03:07 AM, Peter Zijlstra wrote:
For future rework of try_to_wake_up() we'd like to push part of that
onto the CPU the task is actually going to run on, in order to do so we
need a generic callback from the existing scheduler IPI.
This patch introduces such a generic callback: scheduler_ipi() and
implements it as a NOP.
I visited existing smp_send_reschedule() implementations and tried to
add a call to scheduler_ipi() in their handler part, but esp. for MIPS
I'm not quite sure I actually got all of them.
Also, while reading through all this, I noticed the blackfin SMP code
looks to be broken, it simply discards any IPI when low on memory.
Signed-off-by: Peter Zijlstra<redacted>
---
arch/alpha/kernel/smp.c | 1 +
arch/arm/kernel/smp.c | 1 +
arch/blackfin/mach-common/smp.c | 3 ++-
arch/cris/arch-v32/kernel/smp.c | 13 ++++++++-----
arch/ia64/kernel/irq_ia64.c | 2 ++
arch/ia64/xen/irq_xen.c | 10 +++++++++-
arch/m32r/kernel/smp.c | 2 +-
arch/mips/kernel/smtc.c | 1 +
arch/mips/sibyte/bcm1480/smp.c | 7 +++----
arch/mips/sibyte/sb1250/smp.c | 7 +++----
[...]
Peter,
You will also have to patch the mailbox_interrupt() function in
arch/mips/cavium-octeon/smp.c
David Daney.
On Mon, 2011-01-17 at 12:07 +0100, Peter Zijlstra wrote:
For future rework of try_to_wake_up() we'd like to push part of that
onto the CPU the task is actually going to run on, in order to do so we
need a generic callback from the existing scheduler IPI.
This patch introduces such a generic callback: scheduler_ipi() and
implements it as a NOP.
I visited existing smp_send_reschedule() implementations and tried to
add a call to scheduler_ipi() in their handler part, but esp. for MIPS
I'm not quite sure I actually got all of them.
Also, while reading through all this, I noticed the blackfin SMP code
looks to be broken, it simply discards any IPI when low on memory.
Beware of false positive, I've used "fake" reschedule IPIs in the past
for other things (like kicking a CPU out of sleep state for unrelated
reasons). Nothing that I know that is upstream today but some of that
might come back. I'd like to avoid having to add an atomic to know if
it's a real reschedule, will the scheduler be smart enough to not bother
with false positives ?
Cheers,
Ben.
@@ -92,6 +92,8 @@ static unsigned short saved_irq_cnt;staticintxen_slab_ready;#ifdef CONFIG_SMP+#include<linux/sched.h>+/* Dummy stub. Though we may check XEN_RESCHEDULE_VECTOR before __do_IRQ,*itendsuptoissueseveralmemoryaccessesuponpercpudataand*thusaddsunnecessarytraffictootherpaths.
@@ -99,7 +101,13 @@ static int xen_slab_ready;staticirqreturn_txen_dummy_handler(intirq,void*dev_id){+returnIRQ_HANDLED;+}+staticirqreturn_t+xen_resched_handler(intirq,void*dev_id)+{+scheduler_ipi();returnIRQ_HANDLED;}
@@ -931,6 +931,7 @@ static void post_direct_ipi(int cpu, struct smtc_ipi *pipi)staticvoidipi_resched_interrupt(void){/* Return from interrupt should be enough to cause scheduler check */+scheduler_ipi();}staticvoidipi_call_interrupt(void)
@@ -189,10 +190,8 @@ void bcm1480_mailbox_interrupt(void)/* Clear the mailbox to clear the interrupt */__raw_writeq(((u64)action)<<48,mailbox_0_clear_regs[cpu]);-/*-*NothingtodoforSMP_RESCHEDULE_YOURSELF;returningfromthe-*interruptwilldotherescheduleforus-*/+if(actione&SMP_RESCHEDULE_YOURSELF)+scheduler_ipi();if(action&SMP_CALL_FUNCTION)smp_call_function_interrupt();
@@ -177,10 +178,8 @@ void sb1250_mailbox_interrupt(void)/* Clear the mailbox to clear the interrupt */____raw_writeq(((u64)action)<<48,mailbox_clear_regs[cpu]);-/*-*NothingtodoforSMP_RESCHEDULE_YOURSELF;returningfromthe-*interruptwilldotherescheduleforus-*/+if(action&SMP_RESCHEDULE_YOURSELF)+scheduler_ipi();if(action&SMP_CALL_FUNCTION)smp_call_function_interrupt();
@@ -128,6 +128,7 @@ static irqreturn_t call_function_action(int irq, void *data)staticirqreturn_treschedule_action(intirq,void*data){/* we just need the return path side effect of checking need_resched */+scheduler_ipi();returnIRQ_HANDLED;}
@@ -1369,6 +1369,7 @@ void smp_send_reschedule(int cpu)void__irq_entrysmp_receive_signal_client(intirq,structpt_regs*regs){clear_softint(1<<irq);+scheduler_ipi();}/* This is a nop because we capture all other cpus
On Tue, 2011-01-18 at 07:31 +1100, Benjamin Herrenschmidt wrote:
=20
Beware of false positive, I've used "fake" reschedule IPIs in the past
for other things (like kicking a CPU out of sleep state for unrelated
reasons). Nothing that I know that is upstream today but some of that
might come back. I'd like to avoid having to add an atomic to know if
it's a real reschedule, will the scheduler be smart enough to not bother
with false positives ?=20
Yes it can deal with that, some will be for reschedules, some will be
for ttwu tail ends and x86 too uses this ipi for a few random other
things like kicking kvm out of guest context..
@@ -128,6 +128,7 @@ static irqreturn_t call_function_action(int irq, void *data)staticirqreturn_treschedule_action(intirq,void*data){/* we just need the return path side effect of checking need_resched */+scheduler_ipi();returnIRQ_HANDLED;}
@@ -98,6 +98,7 @@ void smp_message_recv(int msg)break;casePPC_MSG_RESCHEDULE:/* we notice need_resched on exit */+scheduler_ipi();break;casePPC_MSG_CALL_FUNC_SINGLE:generic_smp_call_function_single_interrupt();
Fold that in and add:
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Thanks Ben!
BTW. I we lurking at some of our CPU hotplug code and I think I cannot
totally guarantee that this won't be called on an offline CPU. If that's
a problem, you may want to add a test for that.
IE. The call function IPIs are normally not going to be sent to an
offlined CPU, and stop_machine should be a good enough fence here, but
we do abuse reschedule for a number of things (including in some case
to wake up a sleeping CPU that was pseudo-offlined :-)
Cheers,
Ben.
@@ -98,6 +98,7 @@ void smp_message_recv(int msg)break;casePPC_MSG_RESCHEDULE:/* we notice need_resched on exit */+scheduler_ipi();break;casePPC_MSG_CALL_FUNC_SINGLE:generic_smp_call_function_single_interrupt();
Fold that in and add:
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Thanks Ben!
BTW. I we lurking at some of our CPU hotplug code and I think I cannot
totally guarantee that this won't be called on an offline CPU. If that's
a problem, you may want to add a test for that.
IE. The call function IPIs are normally not going to be sent to an
offlined CPU, and stop_machine should be a good enough fence here, but
we do abuse reschedule for a number of things (including in some case
to wake up a sleeping CPU that was pseudo-offlined :-)
Hmm, I _think_ that should all work out nicely, but we'll see, if when
this stuff hits the tree powerpc machines start falling over we'd better
put that check in ;-)
Meanwhile I'm going to preserve this comment in the changelog of this
patch so we don't forget.