* [PATCH 10/12] Support irq migration across domain
@ 2007-05-09 7:56 Ishimatsu Yasuaki
0 siblings, 0 replies; only message in thread
From: Ishimatsu Yasuaki @ 2007-05-09 7:56 UTC (permalink / raw)
To: linux-ia64
Add support for IRQ migration across vector domain.
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
---
arch/ia64/kernel/iosapic.c | 20 +++++++++++++++++---
arch/ia64/kernel/irq_ia64.c | 42 +++++++++++++++++++++++++++++++++++++++---
arch/ia64/kernel/msi_ia64.c | 20 ++++++++++++++------
include/asm-ia64/hw_irq.h | 1 +
include/asm-ia64/iosapic.h | 2 ++
5 files changed, 73 insertions(+), 12 deletions(-)
Index: linux-2.6.21/arch/ia64/kernel/iosapic.c
=================================--- linux-2.6.21.orig/arch/ia64/kernel/iosapic.c 2007-05-08 12:12:56.000000000 +0900
+++ linux-2.6.21/arch/ia64/kernel/iosapic.c 2007-05-08 12:13:39.000000000 +0900
@@ -352,11 +352,13 @@
irq &= (~IA64_IRQ_REDIRECTED);
- /* IRQ migration across domain is not supported yet */
- cpus_and(mask, mask, irq_to_domain(irq));
+ cpus_and(mask, mask, cpu_online_map);
if (cpus_empty(mask))
return;
+ if (reassign_irq_vector(irq, first_cpu(mask)))
+ return;
+
dest = cpu_physical_id(first_cpu(mask));
if (list_empty(&iosapic_intr_info[irq].rtes))
@@ -374,6 +376,8 @@
else
/* change delivery mode to fixed */
low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
+ low32 &= IOSAPIC_VECTOR_MASK;
+ low32 |= irq_to_vector(irq);
iosapic_intr_info[irq].low32 = low32;
iosapic_intr_info[irq].dest = dest;
@@ -402,10 +406,20 @@
{
ia64_vector vec = irq_to_vector(irq);
struct iosapic_rte_info *rte;
+ int do_unmask_irq = 0;
+
+ if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
+ do_unmask_irq = 1;
+ mask_irq(irq);
+ }
- move_native_irq(irq);
list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
iosapic_eoi(rte->iosapic->addr, vec);
+
+ if (unlikely(do_unmask_irq)) {
+ move_masked_irq(irq);
+ unmask_irq(irq);
+ }
}
#define iosapic_shutdown_level_irq mask_irq
Index: linux-2.6.21/arch/ia64/kernel/irq_ia64.c
=================================--- linux-2.6.21.orig/arch/ia64/kernel/irq_ia64.c 2007-05-08 12:12:56.000000000 +0900
+++ linux-2.6.21/arch/ia64/kernel/irq_ia64.c 2007-05-08 12:13:39.000000000 +0900
@@ -145,23 +145,31 @@
return ret;
}
-static void clear_irq_vector(int irq)
+static void __clear_irq_vector(int irq)
{
- unsigned long flags;
int vector, cpu, pos;
cpumask_t mask;
+ cpumask_t domain;
- spin_lock_irqsave(&vector_lock, flags);
BUG_ON((unsigned)irq >= NR_IRQS);
BUG_ON(irq_cfg[irq].vector = IRQ_VECTOR_UNASSIGNED);
vector = irq_cfg[irq].vector;
+ domain = irq_cfg[irq].domain;
cpus_and(mask, irq_cfg[irq].domain, cpu_online_map);
for_each_cpu_mask(cpu, mask)
per_cpu(vector_irq, cpu)[vector] = VECTOR_IRQ_UNASSIGNED;
irq_cfg[irq].vector = IRQ_VECTOR_UNASSIGNED;
irq_cfg[irq].domain = CPU_MASK_NONE;
pos = vector - IA64_FIRST_DEVICE_VECTOR;
- cpus_andnot(vector_table[pos], vector_table[pos], irq_cfg[irq].domain);
+ cpus_andnot(vector_table[pos], vector_table[pos], domain);
+}
+
+static void clear_irq_vector(int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&vector_lock, flags);
+ __clear_irq_vector(irq);
spin_unlock_irqrestore(&vector_lock, flags);
}
@@ -224,6 +232,36 @@
return CPU_MASK_ALL;
}
+static int __reassign_irq_vector(int irq, int cpu)
+{
+ struct irq_cfg *cfg = &irq_cfg[irq];
+ int vector;
+ cpumask_t domain;
+
+ if (cfg->vector = IRQ_VECTOR_UNASSIGNED || !cpu_online(cpu))
+ return -EINVAL;
+ if (cpu_isset(cpu, cfg->domain))
+ return 0;
+ domain = vector_allocation_domain(cpu);
+ vector = find_unassigned_vector(domain);
+ if (vector < 0)
+ return -ENOSPC;
+ __clear_irq_vector(irq);
+ BUG_ON(__bind_irq_vector(irq, vector, domain));
+ return 0;
+}
+
+int reassign_irq_vector(int irq, int cpu)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&vector_lock, flags);
+ ret = __reassign_irq_vector(irq, cpu);
+ spin_unlock_irqrestore(&vector_lock, flags);
+ return ret;
+}
+
/*
* Dynamic irq allocate and deallocation for MSI
*/
Index: linux-2.6.21/arch/ia64/kernel/msi_ia64.c
=================================--- linux-2.6.21.orig/arch/ia64/kernel/msi_ia64.c 2007-05-08 12:12:56.000000000 +0900
+++ linux-2.6.21/arch/ia64/kernel/msi_ia64.c 2007-05-08 12:13:39.000000000 +0900
@@ -13,6 +13,7 @@
#define MSI_DATA_VECTOR_SHIFT 0
#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT)
+#define MSI_DATA_VECTOR_MASK 0xffffff00
#define MSI_DATA_DELIVERY_SHIFT 8
#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT)
@@ -50,22 +51,29 @@
static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
{
struct msi_msg msg;
- u32 addr;
+ u32 addr, data;
+ int cpu = first_cpu(cpu_mask);
- /* IRQ migration across domain is not supported yet */
- cpus_and(cpu_mask, cpu_mask, irq_to_domain(irq));
- if (cpus_empty(cpu_mask))
+ if (!cpu_online(cpu))
+ return;
+
+ if (reassign_irq_vector(irq, cpu))
return;
read_msi_msg(irq, &msg);
addr = msg.address_lo;
addr &= MSI_ADDR_DESTID_MASK;
- addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(first_cpu(cpu_mask)));
+ addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(cpu));
msg.address_lo = addr;
+ data = msg.data;
+ data &= MSI_DATA_VECTOR_MASK;
+ data |= MSI_DATA_VECTOR(irq_to_vector(irq));
+ msg.data = data;
+
write_msi_msg(irq, &msg);
- irq_desc[irq].affinity = cpu_mask;
+ irq_desc[irq].affinity = cpumask_of_cpu(cpu);
}
#endif /* CONFIG_SMP */
Index: linux-2.6.21/include/asm-ia64/iosapic.h
=================================--- linux-2.6.21.orig/include/asm-ia64/iosapic.h 2007-05-07 11:41:48.000000000 +0900
+++ linux-2.6.21/include/asm-ia64/iosapic.h 2007-05-08 12:13:39.000000000 +0900
@@ -47,6 +47,8 @@
#define IOSAPIC_MASK_SHIFT 16
#define IOSAPIC_MASK (1<<IOSAPIC_MASK_SHIFT)
+#define IOSAPIC_VECTOR_MASK 0xffffff00
+
#ifndef __ASSEMBLY__
#ifdef CONFIG_IOSAPIC
Index: linux-2.6.21/include/asm-ia64/hw_irq.h
=================================--- linux-2.6.21.orig/include/asm-ia64/hw_irq.h 2007-05-08 12:12:56.000000000 +0900
+++ linux-2.6.21/include/asm-ia64/hw_irq.h 2007-05-08 12:13:39.000000000 +0900
@@ -105,6 +105,7 @@
extern void free_irq_vector (int vector);
extern int reserve_irq_vector (int vector);
extern void __setup_vector_irq(int cpu);
+extern int reassign_irq_vector(int irq, int cpu);
extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-05-09 7:56 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-09 7:56 [PATCH 10/12] Support irq migration across domain Ishimatsu Yasuaki
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.