From: Ishimatsu Yasuaki <isimatu.yasuaki@jp.fujitsu.com>
To: linux-ia64@vger.kernel.org
Subject: [PATCH 10/12] Support irq migration across domain
Date: Wed, 09 May 2007 07:56:47 +0000 [thread overview]
Message-ID: <46417EBF.9020301@jp.fujitsu.com> (raw)
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);
reply other threads:[~2007-05-09 7:56 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=46417EBF.9020301@jp.fujitsu.com \
--to=isimatu.yasuaki@jp.fujitsu.com \
--cc=linux-ia64@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.