From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
To: linux-ia64@vger.kernel.org
Subject: [RFC][patch 9/10] Multiple vector domain support - inter domain interrupt
Date: Thu, 14 Jul 2005 09:37:37 +0000 [thread overview]
Message-ID: <42D63261.6070208@jp.fujitsu.com> (raw)
This patch adds inter domain interrupt migration for IOSAPIC. This is
needed when all CPUs in the domain is hot-removed.
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
---
linux-2.6.13-rc1-kanesige/arch/ia64/kernel/iosapic.c | 68 ++++++++++++------
linux-2.6.13-rc1-kanesige/arch/ia64/kernel/irq_ia64.c | 36 ++++++++-
linux-2.6.13-rc1-kanesige/include/asm-ia64/hw_irq.h | 1
3 files changed, 83 insertions(+), 22 deletions(-)
diff -puN arch/ia64/kernel/iosapic.c~vector-domain-ia64-migrate-irq-domain arch/ia64/kernel/iosapic.c
--- linux-2.6.13-rc1/arch/ia64/kernel/iosapic.c~vector-domain-ia64-migrate-irq-domain 2005-07-13 16:12:53.000000000 +0900
+++ linux-2.6.13-rc1-kanesige/arch/ia64/kernel/iosapic.c 2005-07-13 16:12:53.000000000 +0900
@@ -311,6 +311,25 @@ unmask_irq (unsigned int irq)
static void
+iosapic_move_gsv (unsigned int src, unsigned int dst)
+{
+ struct iosapic_intr_info *info_src = &iosapic_intr_info[src];
+ struct iosapic_intr_info *info_dst = &iosapic_intr_info[dst];
+ struct iosapic_rte_info *rte, *next;
+
+ memcpy(info_dst, info_src, sizeof(*info_dst));
+ info_dst->low32 &= ~0xff;
+ info_dst->low32 |= (ia64_vector)gsv_to_vector(dst);
+ INIT_LIST_HEAD(&info_dst->rtes);
+ list_for_each_entry_safe(rte, next, &info_src->rtes, rte_list)
+ list_move_tail(&rte->rte_list, &info_dst->rtes);
+ memset(info_src, 0, sizeof(*info_src));
+ info_src->low32 = IOSAPIC_MASK;
+ INIT_LIST_HEAD(&info_src->rtes);
+}
+
+
+static void
iosapic_set_affinity (unsigned int irq, cpumask_t mask)
{
#ifdef CONFIG_SMP
@@ -331,15 +350,24 @@ iosapic_set_affinity (unsigned int irq,
cpu = first_cpu(mask);
dest = cpu_physical_id(cpu);
- /*
- * XXX - IRQ migration between different domains is not supported yet.
- */
- if (!cpu_isset(cpu, ia64_domain_to_cpumask(gsv_to_domain(gsv))))
- return;
-
if (list_empty(&iosapic_intr_info[gsv].rtes))
return; /* not an IOSAPIC interrupt */
+ /*
+ * IRQ migration between different domains
+ */
+ if (!cpu_isset(cpu, ia64_domain_to_cpumask(gsv_to_domain(gsv)))) {
+ int src = gsv;
+ spin_lock_irqsave(&iosapic_lock, flags);
+ gsv = reassign_irq_gsv(irq, ia64_cpu_to_domain(cpu));
+ if (gsv < 0) {
+ spin_unlock_irqrestore(&iosapic_lock, flags);
+ return;
+ }
+ iosapic_move_gsv(src, gsv);
+ spin_unlock_irqrestore(&iosapic_lock, flags);
+ }
+
set_irq_affinity_info(irq, dest, redir);
/* dest contains both id and eid */
@@ -384,10 +412,17 @@ static void
iosapic_end_level_irq (unsigned int irq)
{
unsigned int gsv = irq_to_gsv(irq);
- ia64_vector vec = gsv_to_vector(gsv);
+ ia64_vector vec;
struct iosapic_rte_info *rte;
move_irq(irq);
+ /*
+ * In the case of irq migration to other domain, irq might be
+ * associated to another gsv.
+ */
+ gsv = irq_to_gsv(irq);
+ vec = gsv_to_vector(gsv);
+
list_for_each_entry(rte, &iosapic_intr_info[gsv].rtes, rte_list)
iosapic_eoi(rte->addr, vec);
}
@@ -525,18 +560,13 @@ iosapic_reassign_gsv (unsigned int gsv)
{
int new_gsv;
- if (!list_empty(&iosapic_intr_info[gsv].rtes)) {
- new_gsv = assign_irq_gsv(AUTO_ASSIGN, gsv_to_domain(gsv));
- printk(KERN_INFO "Reassigning vector %d to %d\n",
- gsv_to_vector(gsv), gsv_to_vector(new_gsv));
- memcpy(&iosapic_intr_info[new_gsv], &iosapic_intr_info[gsv],
- sizeof(struct iosapic_intr_info));
- INIT_LIST_HEAD(&iosapic_intr_info[new_gsv].rtes);
- list_move(iosapic_intr_info[gsv].rtes.next, &iosapic_intr_info[new_gsv].rtes);
- memset(&iosapic_intr_info[gsv], 0, sizeof(struct iosapic_intr_info));
- iosapic_intr_info[gsv].low32 = IOSAPIC_MASK;
- INIT_LIST_HEAD(&iosapic_intr_info[gsv].rtes);
- }
+ if (list_empty(&iosapic_intr_info[gsv].rtes))
+ return;
+
+ new_gsv = assign_irq_gsv(AUTO_ASSIGN, gsv_to_domain(gsv));
+ printk(KERN_INFO "Reassigning vector %d to %d\n",
+ gsv_to_vector(gsv), gsv_to_vector(new_gsv));
+ iosapic_move_gsv(gsv, new_gsv);
}
static struct iosapic_rte_info *iosapic_alloc_rte (void)
diff -puN arch/ia64/kernel/irq_ia64.c~vector-domain-ia64-migrate-irq-domain arch/ia64/kernel/irq_ia64.c
--- linux-2.6.13-rc1/arch/ia64/kernel/irq_ia64.c~vector-domain-ia64-migrate-irq-domain 2005-07-13 16:12:53.000000000 +0900
+++ linux-2.6.13-rc1-kanesige/arch/ia64/kernel/irq_ia64.c 2005-07-13 16:12:53.000000000 +0900
@@ -97,14 +97,21 @@ ia64_free_vector (unsigned int domain, u
static unsigned long ia64_irq_mask[BITS_TO_LONGS(NR_IRQS)];
static int
-ia64_alloc_irq (void)
+ia64_alloc_irq (int irq)
{
- int irq;
+ if (irq != AUTO_ASSIGN) {
+ if (!test_and_set_bit(irq, ia64_irq_mask))
+ return irq;
+ else
+ return -1;
+ }
+
do {
irq = find_first_zero_bit(ia64_irq_mask, NR_IRQS);
if (irq > NR_IRQS)
return -1;
} while (test_and_set_bit(irq, ia64_irq_mask));
+
return irq;
}
@@ -126,7 +133,7 @@ assign_irq_gsv_domain (int irq, int doma
if ((vector = ia64_alloc_vector(domain)) < 0)
return -ENOSPC;
- if ((irq = ia64_alloc_irq()) < 0) {
+ if ((irq = ia64_alloc_irq(irq)) < 0) {
ia64_free_vector(domain, vector);
return -ENOSPC;
}
@@ -178,6 +185,29 @@ free_irq_gsv (int gsv)
}
int
+reassign_irq_gsv (int irq, int domain)
+{
+ int new_vector, new_gsv, old_gsv, old_vector, old_domain;
+
+ new_vector = ia64_alloc_vector(domain);
+ if (new_vector < 0)
+ return -ENOSPC;
+
+ old_gsv = irq_to_gsv(irq);
+ new_gsv = domain_vector_to_gsv(domain, new_vector);
+
+ ia64_irq_to_gsv_map[irq] = new_gsv;
+ ia64_gsv_to_irq_map[new_gsv] = irq;
+ ia64_gsv_to_irq_map[old_gsv] = -1;
+
+ old_domain = gsv_to_domain(old_gsv);
+ old_vector = gsv_to_vector(old_gsv);
+ ia64_free_vector(old_domain, old_vector);
+
+ return new_gsv;
+}
+
+int
assign_irq_vector (int irq)
{
return gsv_to_vector(assign_irq_gsv(irq, 0));
diff -puN include/asm-ia64/hw_irq.h~vector-domain-ia64-migrate-irq-domain include/asm-ia64/hw_irq.h
--- linux-2.6.13-rc1/include/asm-ia64/hw_irq.h~vector-domain-ia64-migrate-irq-domain 2005-07-13 16:12:53.000000000 +0900
+++ linux-2.6.13-rc1-kanesige/include/asm-ia64/hw_irq.h 2005-07-14 13:13:49.000000000 +0900
@@ -96,6 +96,7 @@ extern struct hw_interrupt_type irq_type
extern int assign_irq_vector (int irq); /* allocate a free vector */
extern int assign_irq_gsv (int irq, int domain);
extern void free_irq_gsv (int gsv);
+extern int reassign_irq_gsv (int irq, int domain);
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);
extern void __init ia64_vector_domain_init(void);
_
reply other threads:[~2005-07-14 9:37 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=42D63261.6070208@jp.fujitsu.com \
--to=kaneshige.kenji@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox