diff options
-rw-r--r-- | arch/x86/include/asm/entry_arch.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/hw_irq.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/irq_vectors.h | 5 | ||||
-rw-r--r-- | arch/x86/kernel/irqinit.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/smp.c | 18 | ||||
-rw-r--r-- | include/linux/smp.h | 5 |
6 files changed, 34 insertions, 0 deletions
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h index f5693c81a1db..19e22e3784d0 100644 --- a/arch/x86/include/asm/entry_arch.h +++ b/arch/x86/include/asm/entry_arch.h | |||
@@ -13,6 +13,7 @@ | |||
13 | BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) | 13 | BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) |
14 | BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) | 14 | BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) |
15 | BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) | 15 | BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) |
16 | BUILD_INTERRUPT(pull_timers_interrupt,PULL_TIMERS_VECTOR) | ||
16 | BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) | 17 | BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) |
17 | BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR) | 18 | BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR) |
18 | 19 | ||
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index ba180d93b08c..162e5f9646ed 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h | |||
@@ -53,6 +53,8 @@ extern void threshold_interrupt(void); | |||
53 | extern void call_function_interrupt(void); | 53 | extern void call_function_interrupt(void); |
54 | extern void call_function_single_interrupt(void); | 54 | extern void call_function_single_interrupt(void); |
55 | 55 | ||
56 | extern void pull_timers_interrupt(void); | ||
57 | |||
56 | /* PIC specific functions */ | 58 | /* PIC specific functions */ |
57 | extern void disable_8259A_irq(unsigned int irq); | 59 | extern void disable_8259A_irq(unsigned int irq); |
58 | extern void enable_8259A_irq(unsigned int irq); | 60 | extern void enable_8259A_irq(unsigned int irq); |
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index 5b21f0ec3df2..28c3bf3f4c84 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h | |||
@@ -104,6 +104,11 @@ | |||
104 | #define LOCAL_TIMER_VECTOR 0xef | 104 | #define LOCAL_TIMER_VECTOR 0xef |
105 | 105 | ||
106 | /* | 106 | /* |
107 | * LITMUS^RT pull timers IRQ vector | ||
108 | */ | ||
109 | #define PULL_TIMERS_VECTOR 0xee | ||
110 | |||
111 | /* | ||
107 | * Generic system vector for platform specific use | 112 | * Generic system vector for platform specific use |
108 | */ | 113 | */ |
109 | #define GENERIC_INTERRUPT_VECTOR 0xed | 114 | #define GENERIC_INTERRUPT_VECTOR 0xed |
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index 40f30773fb29..f5fa64c0b37e 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c | |||
@@ -172,6 +172,9 @@ static void __init smp_intr_init(void) | |||
172 | alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, | 172 | alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, |
173 | call_function_single_interrupt); | 173 | call_function_single_interrupt); |
174 | 174 | ||
175 | /* IPI for hrtimer pulling on remote cpus */ | ||
176 | alloc_intr_gate(PULL_TIMERS_VECTOR, pull_timers_interrupt); | ||
177 | |||
175 | /* Low priority IPI to cleanup after moving an irq */ | 178 | /* Low priority IPI to cleanup after moving an irq */ |
176 | set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); | 179 | set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); |
177 | set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors); | 180 | set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors); |
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 337ce0c44f92..e83f79de863c 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c | |||
@@ -150,6 +150,16 @@ void native_send_call_func_ipi(const struct cpumask *mask) | |||
150 | free_cpumask_var(allbutself); | 150 | free_cpumask_var(allbutself); |
151 | } | 151 | } |
152 | 152 | ||
153 | /* trigger timers on remote cpu */ | ||
154 | void smp_send_pull_timers(int cpu) | ||
155 | { | ||
156 | if (unlikely(cpu_is_offline(cpu))) { | ||
157 | WARN_ON(1); | ||
158 | return; | ||
159 | } | ||
160 | apic->send_IPI_mask(cpumask_of(cpu), PULL_TIMERS_VECTOR); | ||
161 | } | ||
162 | |||
153 | /* | 163 | /* |
154 | * this function calls the 'stop' function on all other CPUs in the system. | 164 | * this function calls the 'stop' function on all other CPUs in the system. |
155 | */ | 165 | */ |
@@ -230,6 +240,14 @@ void smp_call_function_single_interrupt(struct pt_regs *regs) | |||
230 | irq_exit(); | 240 | irq_exit(); |
231 | } | 241 | } |
232 | 242 | ||
243 | extern void hrtimer_pull(void); | ||
244 | |||
245 | void smp_pull_timers_interrupt(struct pt_regs *regs) | ||
246 | { | ||
247 | ack_APIC_irq(); | ||
248 | TRACE("pull timer interrupt\n"); | ||
249 | } | ||
250 | |||
233 | struct smp_ops smp_ops = { | 251 | struct smp_ops smp_ops = { |
234 | .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu, | 252 | .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu, |
235 | .smp_prepare_cpus = native_smp_prepare_cpus, | 253 | .smp_prepare_cpus = native_smp_prepare_cpus, |
diff --git a/include/linux/smp.h b/include/linux/smp.h index 39c64bae776d..76bb3e45351f 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h | |||
@@ -77,6 +77,11 @@ void __smp_call_function_single(int cpuid, struct call_single_data *data, | |||
77 | int wait); | 77 | int wait); |
78 | 78 | ||
79 | /* | 79 | /* |
80 | * sends a 'pull timer' event to a remote CPU | ||
81 | */ | ||
82 | extern void smp_send_pull_timers(int cpu); | ||
83 | |||
84 | /* | ||
80 | * Generic and arch helpers | 85 | * Generic and arch helpers |
81 | */ | 86 | */ |
82 | #ifdef CONFIG_USE_GENERIC_SMP_HELPERS | 87 | #ifdef CONFIG_USE_GENERIC_SMP_HELPERS |