All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][patch 4/10] Multiple vector domain support - per domain vector
@ 2005-07-14  9:26 Kenji Kaneshige
  0 siblings, 0 replies; only message in thread
From: Kenji Kaneshige @ 2005-07-14  9:26 UTC (permalink / raw)
  To: linux-ia64


This patch adds the code to allocate vectors in each domains. This
patch also contains the basic code to eliminate identity mapping
between IA-64 vectors and linux IRQs.

Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>

---

 linux-2.6.13-rc1-kanesige/arch/ia64/kernel/irq_ia64.c |  129 ++++++++++++++----
 linux-2.6.13-rc1-kanesige/include/asm-ia64/hw_irq.h   |    4 
 2 files changed, 107 insertions(+), 26 deletions(-)

diff -puN arch/ia64/kernel/irq_ia64.c~vector-domain-ia64-assign_irq_gsv arch/ia64/kernel/irq_ia64.c
--- linux-2.6.13-rc1/arch/ia64/kernel/irq_ia64.c~vector-domain-ia64-assign_irq_gsv	2005-07-13 14:51:42.000000000 +0900
+++ linux-2.6.13-rc1-kanesige/arch/ia64/kernel/irq_ia64.c	2005-07-13 16:12:35.000000000 +0900
@@ -63,44 +63,124 @@ EXPORT_SYMBOL(isa_irq_to_vector_map);
 int ia64_irq_to_gsv_map[NR_IRQS] = { [0 ... NR_IRQS-1] = -1 };
 int ia64_gsv_to_irq_map[NR_GSVS] = { [0 ... NR_GSVS-1] = -1 };
 
-static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
+static unsigned long ia64_vector_mask[NR_VECTOR_DOMAINS][BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
 
-int
-assign_irq_vector_nopanic (int irq)
+static int
+ia64_alloc_vector (unsigned int domain)
+{
+	int pos, vec;
+	do {
+		pos = find_first_zero_bit(ia64_vector_mask[domain],
+					  IA64_NUM_DEVICE_VECTORS);
+		vec = IA64_FIRST_DEVICE_VECTOR + pos;
+		if (vec > IA64_LAST_DEVICE_VECTOR)
+			return -ENOSPC;
+	} while (test_and_set_bit(pos, ia64_vector_mask[domain]));
+	return vec;
+}
+
+static void
+ia64_free_vector (unsigned int domain, unsigned int vector)
+{
+	int pos;
+
+	if (domain >= NR_VECTOR_DOMAINS ||
+	    vector < IA64_FIRST_DEVICE_VECTOR ||
+	    vector > IA64_LAST_DEVICE_VECTOR)
+		return;
+
+	pos = vector - IA64_FIRST_DEVICE_VECTOR;
+	if (!test_and_clear_bit(pos, ia64_vector_mask[domain]))
+		printk(KERN_WARNING "%s: double free vector!\n", __FUNCTION__);
+}
+
+static unsigned long ia64_irq_mask[BITS_TO_LONGS(NR_IRQS)];
+
+static int
+ia64_alloc_irq (void)
+{
+	int irq;
+	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;
+}
+
+static void
+ia64_free_irq (unsigned int irq)
+{
+	if (irq >= NR_IRQS)
+		return;
+
+	if (!test_and_clear_bit(irq, ia64_irq_mask))
+		printk(KERN_WARNING "%s: double free irq!\n", __FUNCTION__);
+}
+
+static int
+assign_irq_gsv_domain (int irq, int domain)
 {
-	int pos, vector;
- again:
-	pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
-	vector = IA64_FIRST_DEVICE_VECTOR + pos;
-	if (vector > IA64_LAST_DEVICE_VECTOR)
-		return -1;
-	if (test_and_set_bit(pos, ia64_vector_mask))
-		goto again;
-	return vector;
+	int vector, gsv;
+
+	if ((vector = ia64_alloc_vector(domain)) < 0)
+		return -ENOSPC;
+
+	if ((irq = ia64_alloc_irq()) < 0) {
+		ia64_free_vector(domain, vector);
+		return -ENOSPC;
+	}
+
+	gsv = domain_vector_to_gsv(domain, vector);
+	ia64_irq_to_gsv_map[irq] = gsv;
+	ia64_gsv_to_irq_map[gsv] = irq;
+
+	return gsv;
 }
 
 int
-assign_irq_vector (int irq)
+assign_irq_gsv (int irq, int domain)
 {
-	int vector = assign_irq_vector_nopanic(irq);
+	static int next_domain = -1;
+	int i, gsv = -ENOSPC;
 
-	if (vector < 0)
-		panic("assign_irq_vector: out of interrupt vectors!");
+	if (domain = AUTO_ASSIGN) {
+		for (i = 0; i < NR_VECTOR_DOMAINS; i++) {
+			if (++next_domain >= NR_VECTOR_DOMAINS)
+				next_domain = 0;
+			if (!cpus_weight(ia64_domain_to_cpumask(next_domain)))
+				continue;
+			gsv = assign_irq_gsv_domain(irq, next_domain);
+			if (gsv >= 0)
+				break;
+		}
+	} else
+		gsv = assign_irq_gsv_domain(irq, domain);
 
-	return vector;
+	return gsv;
 }
 
 void
-free_irq_vector (int vector)
+free_irq_gsv (int gsv)
 {
-	int pos;
+	int vector, domain, irq = gsv_to_irq(gsv);
 
-	if (vector < IA64_FIRST_DEVICE_VECTOR || vector > IA64_LAST_DEVICE_VECTOR)
+	if (gsv >= NR_GSVS || irq > NR_IRQS)
 		return;
 
-	pos = vector - IA64_FIRST_DEVICE_VECTOR;
-	if (!test_and_clear_bit(pos, ia64_vector_mask))
-		printk(KERN_WARNING "%s: double free!\n", __FUNCTION__);
+	ia64_irq_to_gsv_map[irq] = -1;
+	ia64_gsv_to_irq_map[gsv] = -1;
+
+	vector = gsv_to_vector(gsv);
+	domain = gsv_to_domain(gsv);
+	ia64_free_vector(domain, vector);
+	ia64_free_irq(irq);
+}
+
+int
+assign_irq_vector (int irq)
+{
+	return gsv_to_vector(assign_irq_gsv(irq, 0));
 }
 
 #ifdef CONFIG_SMP
@@ -293,7 +373,7 @@ ia64_send_ipi (int cpu, int vector, int 
 void __init
 ia64_vector_domain_init (void)
 {
-	int domain, vec, gsv;
+	int vec, gsv;
 
 	/* Attach BSP to domain #0 */
 	ia64_attach_cpu_to_domain(0);
@@ -307,6 +387,7 @@ ia64_vector_domain_init (void)
 		    vec > IA64_LAST_DEVICE_VECTOR) {
 			ia64_gsv_to_irq_map[gsv] = vec;
 			ia64_irq_to_gsv_map[vec] = vec;
+			set_bit(vec, ia64_irq_mask);
 		}
 	}
 }
diff -puN include/asm-ia64/hw_irq.h~vector-domain-ia64-assign_irq_gsv include/asm-ia64/hw_irq.h
--- linux-2.6.13-rc1/include/asm-ia64/hw_irq.h~vector-domain-ia64-assign_irq_gsv	2005-07-13 14:51:42.000000000 +0900
+++ linux-2.6.13-rc1-kanesige/include/asm-ia64/hw_irq.h	2005-07-13 16:04:54.000000000 +0900
@@ -93,9 +93,9 @@ extern cpumask_t ia64_domain_cpumask[NR_
 
 extern struct hw_interrupt_type irq_type_ia64_lsapic;	/* CPU-internal interrupt controller */
 
-extern int assign_irq_vector_nopanic (int irq); /* allocate a free vector without panic */
 extern int assign_irq_vector (int irq);	/* allocate a free vector */
-extern void free_irq_vector (int vector);
+extern int assign_irq_gsv (int irq, int domain);
+extern void free_irq_gsv (int gsv);
 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);

_



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-07-14  9:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-14  9:26 [RFC][patch 4/10] Multiple vector domain support - per domain vector Kenji Kaneshige

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.