aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/x86/Kconfig3
-rw-r--r--arch/x86/include/asm/entry_arch.h1
-rw-r--r--arch/x86/include/asm/hw_irq.h3
-rw-r--r--arch/x86/include/asm/irq_vectors.h6
-rw-r--r--arch/x86/kernel/entry_64.S2
-rw-r--r--arch/x86/kernel/irqinit.c3
-rw-r--r--arch/x86/kernel/smp.c23
8 files changed, 44 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4f412167b95d..411536b9c975 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2249,5 +2249,8 @@ source "arch/arm/kvm/Kconfig"
2249config ARCH_HAS_FEATHER_TRACE 2249config ARCH_HAS_FEATHER_TRACE
2250 def_bool n 2250 def_bool n
2251 2251
2252config ARCH_HAS_SEND_PULL_TIMERS
2253 def_bool n
2254
2252source "litmus/Kconfig" 2255source "litmus/Kconfig"
2253 2256
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 171cdc9cc5db..b0695266a4cb 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2350,4 +2350,7 @@ source "lib/Kconfig"
2350config ARCH_HAS_FEATHER_TRACE 2350config ARCH_HAS_FEATHER_TRACE
2351 def_bool y 2351 def_bool y
2352 2352
2353config ARCH_HAS_SEND_PULL_TIMERS
2354 def_bool y
2355
2353source "litmus/Kconfig" 2356source "litmus/Kconfig"
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h
index 9bd4ecac72be..3a3c2f1ac1c4 100644
--- a/arch/x86/include/asm/entry_arch.h
+++ b/arch/x86/include/asm/entry_arch.h
@@ -13,6 +13,7 @@
13BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) 13BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
14BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) 14BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
15BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) 15BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR)
16BUILD_INTERRUPT(pull_timers_interrupt,PULL_TIMERS_VECTOR)
16BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) 17BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR)
17BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR) 18BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR)
18#endif 19#endif
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 1da97efad08a..672de9367d27 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -77,6 +77,8 @@ extern void threshold_interrupt(void);
77extern void call_function_interrupt(void); 77extern void call_function_interrupt(void);
78extern void call_function_single_interrupt(void); 78extern void call_function_single_interrupt(void);
79 79
80extern void pull_timers_interrupt(void);
81
80/* IOAPIC */ 82/* IOAPIC */
81#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs)) 83#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
82extern unsigned long io_apic_irqs; 84extern unsigned long io_apic_irqs;
@@ -166,6 +168,7 @@ extern asmlinkage void smp_irq_move_cleanup_interrupt(void);
166extern void smp_reschedule_interrupt(struct pt_regs *); 168extern void smp_reschedule_interrupt(struct pt_regs *);
167extern void smp_call_function_interrupt(struct pt_regs *); 169extern void smp_call_function_interrupt(struct pt_regs *);
168extern void smp_call_function_single_interrupt(struct pt_regs *); 170extern void smp_call_function_single_interrupt(struct pt_regs *);
171extern void smp_pull_timers_interrupt(struct pt_regs *);
169#ifdef CONFIG_X86_32 172#ifdef CONFIG_X86_32
170extern void smp_invalidate_interrupt(struct pt_regs *); 173extern void smp_invalidate_interrupt(struct pt_regs *);
171#else 174#else
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 5702d7e3111d..224116be0e22 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -124,6 +124,12 @@
124 */ 124 */
125#define LOCAL_TIMER_VECTOR 0xef 125#define LOCAL_TIMER_VECTOR 0xef
126 126
127/*
128 * LITMUS^RT pull timers IRQ vector.
129 * Make sure it's not used by Linux.
130 */
131#define PULL_TIMERS_VECTOR 0xdf
132
127#define NR_VECTORS 256 133#define NR_VECTORS 256
128 134
129#define FPU_IRQ 13 135#define FPU_IRQ 13
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 727208941030..a48b3ea137cd 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1183,6 +1183,8 @@ apicinterrupt CALL_FUNCTION_VECTOR \
1183 call_function_interrupt smp_call_function_interrupt 1183 call_function_interrupt smp_call_function_interrupt
1184apicinterrupt RESCHEDULE_VECTOR \ 1184apicinterrupt RESCHEDULE_VECTOR \
1185 reschedule_interrupt smp_reschedule_interrupt 1185 reschedule_interrupt smp_reschedule_interrupt
1186apicinterrupt PULL_TIMERS_VECTOR \
1187 pull_timers_interrupt smp_pull_timers_interrupt
1186#endif 1188#endif
1187 1189
1188apicinterrupt ERROR_APIC_VECTOR \ 1190apicinterrupt ERROR_APIC_VECTOR \
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index a2a1fbc594ff..77979d9bd90d 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -145,6 +145,9 @@ static void __init smp_intr_init(void)
145 alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, 145 alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR,
146 call_function_single_interrupt); 146 call_function_single_interrupt);
147 147
148 /* IPI for hrtimer pulling on remote cpus */
149 alloc_intr_gate(PULL_TIMERS_VECTOR, pull_timers_interrupt);
150
148 /* Low priority IPI to cleanup after moving an irq */ 151 /* Low priority IPI to cleanup after moving an irq */
149 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); 152 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
150 set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors); 153 set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index 48d2b7ded422..a52ef7fd6862 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -24,6 +24,8 @@
24#include <linux/cpu.h> 24#include <linux/cpu.h>
25#include <linux/gfp.h> 25#include <linux/gfp.h>
26 26
27#include <litmus/debug_trace.h>
28
27#include <asm/mtrr.h> 29#include <asm/mtrr.h>
28#include <asm/tlbflush.h> 30#include <asm/tlbflush.h>
29#include <asm/mmu_context.h> 31#include <asm/mmu_context.h>
@@ -163,6 +165,16 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs)
163 return NMI_HANDLED; 165 return NMI_HANDLED;
164} 166}
165 167
168/* trigger timers on remote cpu */
169void smp_send_pull_timers(int cpu)
170{
171 if (unlikely(cpu_is_offline(cpu))) {
172 WARN_ON(1);
173 return;
174 }
175 apic->send_IPI_mask(cpumask_of(cpu), PULL_TIMERS_VECTOR);
176}
177
166/* 178/*
167 * this function calls the 'stop' function on all other CPUs in the system. 179 * this function calls the 'stop' function on all other CPUs in the system.
168 */ 180 */
@@ -285,6 +297,17 @@ static int __init nonmi_ipi_setup(char *str)
285 297
286__setup("nonmi_ipi", nonmi_ipi_setup); 298__setup("nonmi_ipi", nonmi_ipi_setup);
287 299
300extern void hrtimer_pull(void);
301
302void smp_pull_timers_interrupt(struct pt_regs *regs)
303{
304 ack_APIC_irq();
305 irq_enter();
306 TRACE("pull timer interrupt\n");
307 hrtimer_pull();
308 irq_exit();
309}
310
288struct smp_ops smp_ops = { 311struct smp_ops smp_ops = {
289 .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu, 312 .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu,
290 .smp_prepare_cpus = native_smp_prepare_cpus, 313 .smp_prepare_cpus = native_smp_prepare_cpus,