aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-ia64/hw_irq.h
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2008-02-25 00:32:22 -0500
committerTony Luck <tony.luck@intel.com>2008-03-04 17:16:20 -0500
commita6cd6322d594014240465210ccb290971469c6e8 (patch)
tree4be5c34dc636fa85e7b6e39e0b3ff82510c7bb8a /include/asm-ia64/hw_irq.h
parent86dffa4cd1a1d61fed68ab64c674d4094f2bdfe4 (diff)
[IA64] Fix irq migration in multiple vector domain
Fix the problem that the following error message is sometimes displayed at irq migration when vector domain is enabled. "Unexpected interrupt vector %d on CPU %d is not mapped to any IRQ!" The cause of this problem is an interrupt is sent to the previous target CPU after cleaning up vector to irq mapping table. To clean up vector to irq map on the previous target CPU safty, change the irq migration in multiple vector domain as follows. The original idea is from x86 interrupt management code. - Delay vector to irq table cleanup until the interrupts are sent to new target CPUs. By this, it is ensured that target CPU is completely changed on the interrupt controller side. - Even after the interrupts are sent to new target CPUs, there can be pended interrupts remaining on the previous target CPU. So we need to delay clearning up vector to irq table until the pended interrupt is handled. For this, send IPI to the previous target CPU with lower priority vector and clean up vector to irq table in its handler. This patch affects only to irq migration code with multiple vector domain is enabled. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'include/asm-ia64/hw_irq.h')
-rw-r--r--include/asm-ia64/hw_irq.h12
1 files changed, 11 insertions, 1 deletions
diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h
index 7e6e3779670a..76366dc9c1a0 100644
--- a/include/asm-ia64/hw_irq.h
+++ b/include/asm-ia64/hw_irq.h
@@ -93,6 +93,9 @@ extern __u8 isa_irq_to_vector_map[16];
93struct irq_cfg { 93struct irq_cfg {
94 ia64_vector vector; 94 ia64_vector vector;
95 cpumask_t domain; 95 cpumask_t domain;
96 cpumask_t old_domain;
97 unsigned move_cleanup_count;
98 u8 move_in_progress : 1;
96}; 99};
97extern spinlock_t vector_lock; 100extern spinlock_t vector_lock;
98extern struct irq_cfg irq_cfg[NR_IRQS]; 101extern struct irq_cfg irq_cfg[NR_IRQS];
@@ -106,12 +109,19 @@ extern int assign_irq_vector (int irq); /* allocate a free vector */
106extern void free_irq_vector (int vector); 109extern void free_irq_vector (int vector);
107extern int reserve_irq_vector (int vector); 110extern int reserve_irq_vector (int vector);
108extern void __setup_vector_irq(int cpu); 111extern void __setup_vector_irq(int cpu);
109extern int reassign_irq_vector(int irq, int cpu);
110extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); 112extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
111extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); 113extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
112extern int check_irq_used (int irq); 114extern int check_irq_used (int irq);
113extern void destroy_and_reserve_irq (unsigned int irq); 115extern void destroy_and_reserve_irq (unsigned int irq);
114 116
117#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG))
118extern int irq_prepare_move(int irq, int cpu);
119extern void irq_complete_move(unsigned int irq);
120#else
121static inline int irq_prepare_move(int irq, int cpu) { return 0; }
122static inline void irq_complete_move(unsigned int irq) {}
123#endif
124
115static inline void ia64_resend_irq(unsigned int vector) 125static inline void ia64_resend_irq(unsigned int vector)
116{ 126{
117 platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0); 127 platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);