diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2011-04-05 11:23:39 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2011-04-14 02:52:32 -0400 |
| commit | 184748cc50b2dceb8287f9fb657eda48ff8fcfe7 (patch) | |
| tree | da32494cf29e5ec9f80b17dc8590bdc450ea545a /arch | |
| parent | a4c98f8bbeafee12c979c90743f6fda94f7515c7 (diff) | |
sched: Provide scheduler_ipi() callback in response to smp_send_reschedule()
For future rework of try_to_wake_up() we'd like to push part of that
function 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.
BenH notes: PowerPC might use this IPI on offline CPUs under rare conditions!
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Acked-by: Chris Metcalf <cmetcalf@tilera.com>
Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Reviewed-by: Frank Rowand <frank.rowand@am.sony.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Nick Piggin <npiggin@kernel.dk>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20110405152728.744338123@chello.nl
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/alpha/kernel/smp.c | 3 | ||||
| -rw-r--r-- | arch/arm/kernel/smp.c | 5 | ||||
| -rw-r--r-- | arch/blackfin/mach-common/smp.c | 3 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/smp.c | 13 | ||||
| -rw-r--r-- | arch/ia64/kernel/irq_ia64.c | 2 | ||||
| -rw-r--r-- | arch/ia64/xen/irq_xen.c | 10 | ||||
| -rw-r--r-- | arch/m32r/kernel/smp.c | 4 | ||||
| -rw-r--r-- | arch/mips/cavium-octeon/smp.c | 2 | ||||
| -rw-r--r-- | arch/mips/kernel/smtc.c | 2 | ||||
| -rw-r--r-- | arch/mips/mti-malta/malta-int.c | 2 | ||||
| -rw-r--r-- | arch/mips/pmc-sierra/yosemite/smp.c | 4 | ||||
| -rw-r--r-- | arch/mips/sgi-ip27/ip27-irq.c | 2 | ||||
| -rw-r--r-- | arch/mips/sibyte/bcm1480/smp.c | 7 | ||||
| -rw-r--r-- | arch/mips/sibyte/sb1250/smp.c | 7 | ||||
| -rw-r--r-- | arch/mn10300/kernel/smp.c | 5 | ||||
| -rw-r--r-- | arch/parisc/kernel/smp.c | 5 | ||||
| -rw-r--r-- | arch/powerpc/kernel/smp.c | 4 | ||||
| -rw-r--r-- | arch/s390/kernel/smp.c | 6 | ||||
| -rw-r--r-- | arch/sh/kernel/smp.c | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/smp_32.c | 4 | ||||
| -rw-r--r-- | arch/sparc/kernel/smp_64.c | 1 | ||||
| -rw-r--r-- | arch/tile/kernel/smp.c | 6 | ||||
| -rw-r--r-- | arch/um/kernel/smp.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/smp.c | 5 | ||||
| -rw-r--r-- | arch/x86/xen/smp.c | 5 |
25 files changed, 61 insertions, 50 deletions
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 42aa078a5e4..5a621c6d22a 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c | |||
| @@ -585,8 +585,7 @@ handle_ipi(struct pt_regs *regs) | |||
| 585 | 585 | ||
| 586 | switch (which) { | 586 | switch (which) { |
| 587 | case IPI_RESCHEDULE: | 587 | case IPI_RESCHEDULE: |
| 588 | /* Reschedule callback. Everything to be done | 588 | scheduler_ipi(); |
| 589 | is done by the interrupt return path. */ | ||
| 590 | break; | 589 | break; |
| 591 | 590 | ||
| 592 | case IPI_CALL_FUNC: | 591 | case IPI_CALL_FUNC: |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 8fe05ad932e..7a561eb731e 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
| @@ -560,10 +560,7 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) | |||
| 560 | break; | 560 | break; |
| 561 | 561 | ||
| 562 | case IPI_RESCHEDULE: | 562 | case IPI_RESCHEDULE: |
| 563 | /* | 563 | scheduler_ipi(); |
| 564 | * nothing more to do - eveything is | ||
| 565 | * done on the interrupt return path | ||
| 566 | */ | ||
| 567 | break; | 564 | break; |
| 568 | 565 | ||
| 569 | case IPI_CALL_FUNC: | 566 | case IPI_CALL_FUNC: |
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 6e17a265c4d..326bb86f4d2 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c | |||
| @@ -164,6 +164,9 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance) | |||
| 164 | while (msg_queue->count) { | 164 | while (msg_queue->count) { |
| 165 | msg = &msg_queue->ipi_message[msg_queue->head]; | 165 | msg = &msg_queue->ipi_message[msg_queue->head]; |
| 166 | switch (msg->type) { | 166 | switch (msg->type) { |
| 167 | case BFIN_IPI_RESCHEDULE: | ||
| 168 | scheduler_ipi(); | ||
| 169 | break; | ||
| 167 | case BFIN_IPI_CALL_FUNC: | 170 | case BFIN_IPI_CALL_FUNC: |
| 168 | spin_unlock_irqrestore(&msg_queue->lock, flags); | 171 | spin_unlock_irqrestore(&msg_queue->lock, flags); |
| 169 | ipi_call_function(cpu, msg); | 172 | ipi_call_function(cpu, msg); |
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c index 4c9e3e1ba5d..66cc75657e2 100644 --- a/arch/cris/arch-v32/kernel/smp.c +++ b/arch/cris/arch-v32/kernel/smp.c | |||
| @@ -342,15 +342,18 @@ irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id) | |||
| 342 | 342 | ||
| 343 | ipi = REG_RD(intr_vect, irq_regs[smp_processor_id()], rw_ipi); | 343 | ipi = REG_RD(intr_vect, irq_regs[smp_processor_id()], rw_ipi); |
| 344 | 344 | ||
| 345 | if (ipi.vector & IPI_SCHEDULE) { | ||
| 346 | scheduler_ipi(); | ||
| 347 | } | ||
| 345 | if (ipi.vector & IPI_CALL) { | 348 | if (ipi.vector & IPI_CALL) { |
| 346 | func(info); | 349 | func(info); |
| 347 | } | 350 | } |
| 348 | if (ipi.vector & IPI_FLUSH_TLB) { | 351 | if (ipi.vector & IPI_FLUSH_TLB) { |
| 349 | if (flush_mm == FLUSH_ALL) | 352 | if (flush_mm == FLUSH_ALL) |
| 350 | __flush_tlb_all(); | 353 | __flush_tlb_all(); |
| 351 | else if (flush_vma == FLUSH_ALL) | 354 | else if (flush_vma == FLUSH_ALL) |
| 352 | __flush_tlb_mm(flush_mm); | 355 | __flush_tlb_mm(flush_mm); |
| 353 | else | 356 | else |
| 354 | __flush_tlb_page(flush_vma, flush_addr); | 357 | __flush_tlb_page(flush_vma, flush_addr); |
| 355 | } | 358 | } |
| 356 | 359 | ||
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 5b704740f16..782c3a357f2 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/irq.h> | 31 | #include <linux/irq.h> |
| 32 | #include <linux/ratelimit.h> | 32 | #include <linux/ratelimit.h> |
| 33 | #include <linux/acpi.h> | 33 | #include <linux/acpi.h> |
| 34 | #include <linux/sched.h> | ||
| 34 | 35 | ||
| 35 | #include <asm/delay.h> | 36 | #include <asm/delay.h> |
| 36 | #include <asm/intrinsics.h> | 37 | #include <asm/intrinsics.h> |
| @@ -496,6 +497,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) | |||
| 496 | smp_local_flush_tlb(); | 497 | smp_local_flush_tlb(); |
| 497 | kstat_incr_irqs_this_cpu(irq, desc); | 498 | kstat_incr_irqs_this_cpu(irq, desc); |
| 498 | } else if (unlikely(IS_RESCHEDULE(vector))) { | 499 | } else if (unlikely(IS_RESCHEDULE(vector))) { |
| 500 | scheduler_ipi(); | ||
| 499 | kstat_incr_irqs_this_cpu(irq, desc); | 501 | kstat_incr_irqs_this_cpu(irq, desc); |
| 500 | } else { | 502 | } else { |
| 501 | ia64_setreg(_IA64_REG_CR_TPR, vector); | 503 | ia64_setreg(_IA64_REG_CR_TPR, vector); |
diff --git a/arch/ia64/xen/irq_xen.c b/arch/ia64/xen/irq_xen.c index 108bb858acf..b279e142c63 100644 --- a/arch/ia64/xen/irq_xen.c +++ b/arch/ia64/xen/irq_xen.c | |||
| @@ -92,6 +92,8 @@ static unsigned short saved_irq_cnt; | |||
| 92 | static int xen_slab_ready; | 92 | static int xen_slab_ready; |
| 93 | 93 | ||
| 94 | #ifdef CONFIG_SMP | 94 | #ifdef CONFIG_SMP |
| 95 | #include <linux/sched.h> | ||
| 96 | |||
| 95 | /* Dummy stub. Though we may check XEN_RESCHEDULE_VECTOR before __do_IRQ, | 97 | /* Dummy stub. Though we may check XEN_RESCHEDULE_VECTOR before __do_IRQ, |
| 96 | * it ends up to issue several memory accesses upon percpu data and | 98 | * it ends up to issue several memory accesses upon percpu data and |
| 97 | * thus adds unnecessary traffic to other paths. | 99 | * thus adds unnecessary traffic to other paths. |
| @@ -99,7 +101,13 @@ static int xen_slab_ready; | |||
| 99 | static irqreturn_t | 101 | static irqreturn_t |
| 100 | xen_dummy_handler(int irq, void *dev_id) | 102 | xen_dummy_handler(int irq, void *dev_id) |
| 101 | { | 103 | { |
| 104 | return IRQ_HANDLED; | ||
| 105 | } | ||
| 102 | 106 | ||
| 107 | static irqreturn_t | ||
| 108 | xen_resched_handler(int irq, void *dev_id) | ||
| 109 | { | ||
| 110 | scheduler_ipi(); | ||
| 103 | return IRQ_HANDLED; | 111 | return IRQ_HANDLED; |
| 104 | } | 112 | } |
| 105 | 113 | ||
| @@ -110,7 +118,7 @@ static struct irqaction xen_ipi_irqaction = { | |||
| 110 | }; | 118 | }; |
| 111 | 119 | ||
| 112 | static struct irqaction xen_resched_irqaction = { | 120 | static struct irqaction xen_resched_irqaction = { |
| 113 | .handler = xen_dummy_handler, | 121 | .handler = xen_resched_handler, |
| 114 | .flags = IRQF_DISABLED, | 122 | .flags = IRQF_DISABLED, |
| 115 | .name = "resched" | 123 | .name = "resched" |
| 116 | }; | 124 | }; |
diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c index 31cef20b299..fc10b39893d 100644 --- a/arch/m32r/kernel/smp.c +++ b/arch/m32r/kernel/smp.c | |||
| @@ -122,8 +122,6 @@ void smp_send_reschedule(int cpu_id) | |||
| 122 | * | 122 | * |
| 123 | * Description: This routine executes on CPU which received | 123 | * Description: This routine executes on CPU which received |
| 124 | * 'RESCHEDULE_IPI'. | 124 | * 'RESCHEDULE_IPI'. |
| 125 | * Rescheduling is processed at the exit of interrupt | ||
| 126 | * operation. | ||
| 127 | * | 125 | * |
| 128 | * Born on Date: 2002.02.05 | 126 | * Born on Date: 2002.02.05 |
| 129 | * | 127 | * |
| @@ -138,7 +136,7 @@ void smp_send_reschedule(int cpu_id) | |||
| 138 | *==========================================================================*/ | 136 | *==========================================================================*/ |
| 139 | void smp_reschedule_interrupt(void) | 137 | void smp_reschedule_interrupt(void) |
| 140 | { | 138 | { |
| 141 | /* nothing to do */ | 139 | scheduler_ipi(); |
| 142 | } | 140 | } |
| 143 | 141 | ||
| 144 | /*==========================================================================* | 142 | /*==========================================================================* |
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index ba78b21cc8d..76923eeb58b 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c | |||
| @@ -44,6 +44,8 @@ static irqreturn_t mailbox_interrupt(int irq, void *dev_id) | |||
| 44 | 44 | ||
| 45 | if (action & SMP_CALL_FUNCTION) | 45 | if (action & SMP_CALL_FUNCTION) |
| 46 | smp_call_function_interrupt(); | 46 | smp_call_function_interrupt(); |
| 47 | if (action & SMP_RESCHEDULE_YOURSELF) | ||
| 48 | scheduler_ipi(); | ||
| 47 | 49 | ||
| 48 | /* Check if we've been told to flush the icache */ | 50 | /* Check if we've been told to flush the icache */ |
| 49 | if (action & SMP_ICACHE_FLUSH) | 51 | if (action & SMP_ICACHE_FLUSH) |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 5a88cc4ccd5..cedac463374 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
| @@ -929,7 +929,7 @@ static void post_direct_ipi(int cpu, struct smtc_ipi *pipi) | |||
| 929 | 929 | ||
| 930 | static void ipi_resched_interrupt(void) | 930 | static void ipi_resched_interrupt(void) |
| 931 | { | 931 | { |
| 932 | /* Return from interrupt should be enough to cause scheduler check */ | 932 | scheduler_ipi(); |
| 933 | } | 933 | } |
| 934 | 934 | ||
| 935 | static void ipi_call_interrupt(void) | 935 | static void ipi_call_interrupt(void) |
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 9027061f0ea..7d93e6fbfa5 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c | |||
| @@ -309,6 +309,8 @@ static void ipi_call_dispatch(void) | |||
| 309 | 309 | ||
| 310 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | 310 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) |
| 311 | { | 311 | { |
| 312 | scheduler_ipi(); | ||
| 313 | |||
| 312 | return IRQ_HANDLED; | 314 | return IRQ_HANDLED; |
| 313 | } | 315 | } |
| 314 | 316 | ||
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index efc9e889b34..2608752898c 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c | |||
| @@ -55,6 +55,8 @@ void titan_mailbox_irq(void) | |||
| 55 | 55 | ||
| 56 | if (status & 0x2) | 56 | if (status & 0x2) |
| 57 | smp_call_function_interrupt(); | 57 | smp_call_function_interrupt(); |
| 58 | if (status & 0x4) | ||
| 59 | scheduler_ipi(); | ||
| 58 | break; | 60 | break; |
| 59 | 61 | ||
| 60 | case 1: | 62 | case 1: |
| @@ -63,6 +65,8 @@ void titan_mailbox_irq(void) | |||
| 63 | 65 | ||
| 64 | if (status & 0x2) | 66 | if (status & 0x2) |
| 65 | smp_call_function_interrupt(); | 67 | smp_call_function_interrupt(); |
| 68 | if (status & 0x4) | ||
| 69 | scheduler_ipi(); | ||
| 66 | break; | 70 | break; |
| 67 | } | 71 | } |
| 68 | } | 72 | } |
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 0a04603d577..b18b04e4857 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c | |||
| @@ -147,8 +147,10 @@ static void ip27_do_irq_mask0(void) | |||
| 147 | #ifdef CONFIG_SMP | 147 | #ifdef CONFIG_SMP |
| 148 | if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) { | 148 | if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) { |
| 149 | LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ); | 149 | LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ); |
| 150 | scheduler_ipi(); | ||
| 150 | } else if (pend0 & (1UL << CPU_RESCHED_B_IRQ)) { | 151 | } else if (pend0 & (1UL << CPU_RESCHED_B_IRQ)) { |
| 151 | LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ); | 152 | LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ); |
| 153 | scheduler_ipi(); | ||
| 152 | } else if (pend0 & (1UL << CPU_CALL_A_IRQ)) { | 154 | } else if (pend0 & (1UL << CPU_CALL_A_IRQ)) { |
| 153 | LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ); | 155 | LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ); |
| 154 | smp_call_function_interrupt(); | 156 | smp_call_function_interrupt(); |
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c index 47b347c992e..d667875be56 100644 --- a/arch/mips/sibyte/bcm1480/smp.c +++ b/arch/mips/sibyte/bcm1480/smp.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
| 21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
| 22 | #include <linux/kernel_stat.h> | 22 | #include <linux/kernel_stat.h> |
| 23 | #include <linux/sched.h> | ||
| 23 | 24 | ||
| 24 | #include <asm/mmu_context.h> | 25 | #include <asm/mmu_context.h> |
| 25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
| @@ -189,10 +190,8 @@ void bcm1480_mailbox_interrupt(void) | |||
| 189 | /* Clear the mailbox to clear the interrupt */ | 190 | /* Clear the mailbox to clear the interrupt */ |
| 190 | __raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]); | 191 | __raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]); |
| 191 | 192 | ||
| 192 | /* | 193 | if (action & SMP_RESCHEDULE_YOURSELF) |
| 193 | * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the | 194 | scheduler_ipi(); |
| 194 | * interrupt will do the reschedule for us | ||
| 195 | */ | ||
| 196 | 195 | ||
| 197 | if (action & SMP_CALL_FUNCTION) | 196 | if (action & SMP_CALL_FUNCTION) |
| 198 | smp_call_function_interrupt(); | 197 | smp_call_function_interrupt(); |
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c index c00a5cb1128..38e7f6bd792 100644 --- a/arch/mips/sibyte/sb1250/smp.c +++ b/arch/mips/sibyte/sb1250/smp.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
| 22 | #include <linux/smp.h> | 22 | #include <linux/smp.h> |
| 23 | #include <linux/kernel_stat.h> | 23 | #include <linux/kernel_stat.h> |
| 24 | #include <linux/sched.h> | ||
| 24 | 25 | ||
| 25 | #include <asm/mmu_context.h> | 26 | #include <asm/mmu_context.h> |
| 26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
| @@ -177,10 +178,8 @@ void sb1250_mailbox_interrupt(void) | |||
| 177 | /* Clear the mailbox to clear the interrupt */ | 178 | /* Clear the mailbox to clear the interrupt */ |
| 178 | ____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]); | 179 | ____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]); |
| 179 | 180 | ||
| 180 | /* | 181 | if (action & SMP_RESCHEDULE_YOURSELF) |
| 181 | * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the | 182 | scheduler_ipi(); |
| 182 | * interrupt will do the reschedule for us | ||
| 183 | */ | ||
| 184 | 183 | ||
| 185 | if (action & SMP_CALL_FUNCTION) | 184 | if (action & SMP_CALL_FUNCTION) |
| 186 | smp_call_function_interrupt(); | 185 | smp_call_function_interrupt(); |
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c index 226c826a219..83fb2791223 100644 --- a/arch/mn10300/kernel/smp.c +++ b/arch/mn10300/kernel/smp.c | |||
| @@ -494,14 +494,11 @@ void smp_send_stop(void) | |||
| 494 | * @irq: The interrupt number. | 494 | * @irq: The interrupt number. |
| 495 | * @dev_id: The device ID. | 495 | * @dev_id: The device ID. |
| 496 | * | 496 | * |
| 497 | * We need do nothing here, since the scheduling will be effected on our way | ||
| 498 | * back through entry.S. | ||
| 499 | * | ||
| 500 | * Returns IRQ_HANDLED to indicate we handled the interrupt successfully. | 497 | * Returns IRQ_HANDLED to indicate we handled the interrupt successfully. |
| 501 | */ | 498 | */ |
| 502 | static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id) | 499 | static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id) |
| 503 | { | 500 | { |
| 504 | /* do nothing */ | 501 | scheduler_ipi(); |
| 505 | return IRQ_HANDLED; | 502 | return IRQ_HANDLED; |
| 506 | } | 503 | } |
| 507 | 504 | ||
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 69d63d354ef..828305f19cf 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c | |||
| @@ -155,10 +155,7 @@ ipi_interrupt(int irq, void *dev_id) | |||
| 155 | 155 | ||
| 156 | case IPI_RESCHEDULE: | 156 | case IPI_RESCHEDULE: |
| 157 | smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu); | 157 | smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu); |
| 158 | /* | 158 | scheduler_ipi(); |
| 159 | * Reschedule callback. Everything to be | ||
| 160 | * done is done by the interrupt return path. | ||
| 161 | */ | ||
| 162 | break; | 159 | break; |
| 163 | 160 | ||
| 164 | case IPI_CALL_FUNC: | 161 | case IPI_CALL_FUNC: |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index cbdbb14be4b..9f9c204bef6 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
| @@ -116,7 +116,7 @@ void smp_message_recv(int msg) | |||
| 116 | generic_smp_call_function_interrupt(); | 116 | generic_smp_call_function_interrupt(); |
| 117 | break; | 117 | break; |
| 118 | case PPC_MSG_RESCHEDULE: | 118 | case PPC_MSG_RESCHEDULE: |
| 119 | /* we notice need_resched on exit */ | 119 | scheduler_ipi(); |
| 120 | break; | 120 | break; |
| 121 | case PPC_MSG_CALL_FUNC_SINGLE: | 121 | case PPC_MSG_CALL_FUNC_SINGLE: |
| 122 | generic_smp_call_function_single_interrupt(); | 122 | generic_smp_call_function_single_interrupt(); |
| @@ -146,7 +146,7 @@ static irqreturn_t call_function_action(int irq, void *data) | |||
| 146 | 146 | ||
| 147 | static irqreturn_t reschedule_action(int irq, void *data) | 147 | static irqreturn_t reschedule_action(int irq, void *data) |
| 148 | { | 148 | { |
| 149 | /* we just need the return path side effect of checking need_resched */ | 149 | scheduler_ipi(); |
| 150 | return IRQ_HANDLED; | 150 | return IRQ_HANDLED; |
| 151 | } | 151 | } |
| 152 | 152 | ||
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 63a97db83f9..63c7d9ff220 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
| @@ -165,12 +165,12 @@ static void do_ext_call_interrupt(unsigned int ext_int_code, | |||
| 165 | kstat_cpu(smp_processor_id()).irqs[EXTINT_IPI]++; | 165 | kstat_cpu(smp_processor_id()).irqs[EXTINT_IPI]++; |
| 166 | /* | 166 | /* |
| 167 | * handle bit signal external calls | 167 | * handle bit signal external calls |
| 168 | * | ||
| 169 | * For the ec_schedule signal we have to do nothing. All the work | ||
| 170 | * is done automatically when we return from the interrupt. | ||
| 171 | */ | 168 | */ |
| 172 | bits = xchg(&S390_lowcore.ext_call_fast, 0); | 169 | bits = xchg(&S390_lowcore.ext_call_fast, 0); |
| 173 | 170 | ||
| 171 | if (test_bit(ec_schedule, &bits)) | ||
| 172 | scheduler_ipi(); | ||
| 173 | |||
| 174 | if (test_bit(ec_call_function, &bits)) | 174 | if (test_bit(ec_call_function, &bits)) |
| 175 | generic_smp_call_function_interrupt(); | 175 | generic_smp_call_function_interrupt(); |
| 176 | 176 | ||
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 509b36b4511..6207561ea34 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/cpu.h> | 21 | #include <linux/cpu.h> |
| 22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
| 23 | #include <linux/sched.h> | ||
| 23 | #include <asm/atomic.h> | 24 | #include <asm/atomic.h> |
| 24 | #include <asm/processor.h> | 25 | #include <asm/processor.h> |
| 25 | #include <asm/system.h> | 26 | #include <asm/system.h> |
| @@ -323,6 +324,7 @@ void smp_message_recv(unsigned int msg) | |||
| 323 | generic_smp_call_function_interrupt(); | 324 | generic_smp_call_function_interrupt(); |
| 324 | break; | 325 | break; |
| 325 | case SMP_MSG_RESCHEDULE: | 326 | case SMP_MSG_RESCHEDULE: |
| 327 | scheduler_ipi(); | ||
| 326 | break; | 328 | break; |
| 327 | case SMP_MSG_FUNCTION_SINGLE: | 329 | case SMP_MSG_FUNCTION_SINGLE: |
| 328 | generic_smp_call_function_single_interrupt(); | 330 | generic_smp_call_function_single_interrupt(); |
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 91c10fb7085..f95690c167b 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c | |||
| @@ -125,7 +125,9 @@ struct linux_prom_registers smp_penguin_ctable __cpuinitdata = { 0 }; | |||
| 125 | 125 | ||
| 126 | void smp_send_reschedule(int cpu) | 126 | void smp_send_reschedule(int cpu) |
| 127 | { | 127 | { |
| 128 | /* See sparc64 */ | 128 | /* |
| 129 | * XXX missing reschedule IPI, see scheduler_ipi() | ||
| 130 | */ | ||
| 129 | } | 131 | } |
| 130 | 132 | ||
| 131 | void smp_send_stop(void) | 133 | void smp_send_stop(void) |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 3e94a8c2323..9478da7fdb3 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
| @@ -1368,6 +1368,7 @@ void smp_send_reschedule(int cpu) | |||
| 1368 | void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) | 1368 | void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) |
| 1369 | { | 1369 | { |
| 1370 | clear_softint(1 << irq); | 1370 | clear_softint(1 << irq); |
| 1371 | scheduler_ipi(); | ||
| 1371 | } | 1372 | } |
| 1372 | 1373 | ||
| 1373 | /* This is a nop because we capture all other cpus | 1374 | /* This is a nop because we capture all other cpus |
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c index a4293102ef8..c52224d5ed4 100644 --- a/arch/tile/kernel/smp.c +++ b/arch/tile/kernel/smp.c | |||
| @@ -189,12 +189,8 @@ void flush_icache_range(unsigned long start, unsigned long end) | |||
| 189 | /* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */ | 189 | /* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */ |
| 190 | static irqreturn_t handle_reschedule_ipi(int irq, void *token) | 190 | static irqreturn_t handle_reschedule_ipi(int irq, void *token) |
| 191 | { | 191 | { |
| 192 | /* | ||
| 193 | * Nothing to do here; when we return from interrupt, the | ||
| 194 | * rescheduling will occur there. But do bump the interrupt | ||
| 195 | * profiler count in the meantime. | ||
| 196 | */ | ||
| 197 | __get_cpu_var(irq_stat).irq_resched_count++; | 192 | __get_cpu_var(irq_stat).irq_resched_count++; |
| 193 | scheduler_ipi(); | ||
| 198 | 194 | ||
| 199 | return IRQ_HANDLED; | 195 | return IRQ_HANDLED; |
| 200 | } | 196 | } |
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 106bf27e2a9..eefb107d2d7 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c | |||
| @@ -173,7 +173,7 @@ void IPI_handler(int cpu) | |||
| 173 | break; | 173 | break; |
| 174 | 174 | ||
| 175 | case 'R': | 175 | case 'R': |
| 176 | set_tsk_need_resched(current); | 176 | scheduler_ipi(); |
| 177 | break; | 177 | break; |
| 178 | 178 | ||
| 179 | case 'S': | 179 | case 'S': |
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 513deac7228..013e7eba83b 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c | |||
| @@ -194,14 +194,13 @@ static void native_stop_other_cpus(int wait) | |||
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | /* | 196 | /* |
| 197 | * Reschedule call back. Nothing to do, | 197 | * Reschedule call back. |
| 198 | * all the work is done automatically when | ||
| 199 | * we return from the interrupt. | ||
| 200 | */ | 198 | */ |
| 201 | void smp_reschedule_interrupt(struct pt_regs *regs) | 199 | void smp_reschedule_interrupt(struct pt_regs *regs) |
| 202 | { | 200 | { |
| 203 | ack_APIC_irq(); | 201 | ack_APIC_irq(); |
| 204 | inc_irq_stat(irq_resched_count); | 202 | inc_irq_stat(irq_resched_count); |
| 203 | scheduler_ipi(); | ||
| 205 | /* | 204 | /* |
| 206 | * KVM uses this interrupt to force a cpu out of guest mode | 205 | * KVM uses this interrupt to force a cpu out of guest mode |
| 207 | */ | 206 | */ |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 30612441ed9..762b46ab14d 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
| @@ -46,13 +46,12 @@ static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id); | |||
| 46 | static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id); | 46 | static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id); |
| 47 | 47 | ||
| 48 | /* | 48 | /* |
| 49 | * Reschedule call back. Nothing to do, | 49 | * Reschedule call back. |
| 50 | * all the work is done automatically when | ||
| 51 | * we return from the interrupt. | ||
| 52 | */ | 50 | */ |
| 53 | static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) | 51 | static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) |
| 54 | { | 52 | { |
| 55 | inc_irq_stat(irq_resched_count); | 53 | inc_irq_stat(irq_resched_count); |
| 54 | scheduler_ipi(); | ||
| 56 | 55 | ||
| 57 | return IRQ_HANDLED; | 56 | return IRQ_HANDLED; |
| 58 | } | 57 | } |
