All of lore.kernel.org
 help / color / mirror / Atom feed
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 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.