From 04b9267b15206fc902a18de1f78de6c82ca47716 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 4 Oct 2006 02:16:46 -0700 Subject: [PATCH] [PATCH] genirq: x86_64 irq: Remove the msi assumption that irq == vector This patch removes the change in behavior of the irq allocation code when CONFIG_PCI_MSI is defined. Removing all instances of the assumption that irq == vector. create_irq is rewritten to first allocate a free irq and then to assign that irq a vector. assign_irq_vector is made static and the AUTO_ASSIGN case which allocates an vector not bound to an irq is removed. The ioapic vector methods are removed, and everything now works with irqs. The definition of NR_IRQS no longer depends on CONFIG_PCI_MSI Signed-off-by: Eric W. Biederman Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Benjamin Herrenschmidt Cc: Rajesh Shah Cc: Andi Kleen Cc: "Protasevich, Natalie" Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/io_apic.c | 147 +++++++++++------------------------ include/asm-x86_64/hw_irq.h | 1 - include/asm-x86_64/io_apic.h | 40 ---------- include/asm-x86_64/irq.h | 5 -- 4 files changed, 47 insertions(+), 146 deletions(-) diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 437b6f96cc..bb16f3790f 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -44,6 +44,8 @@ #include #include +static int assign_irq_vector(int irq); + #define __apicdebuginit __init int sis_apic_bug; /* not actually supported, dummy for compile */ @@ -83,14 +85,6 @@ static struct irq_pin_list { short apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; -int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; -#ifdef CONFIG_PCI_MSI -#define vector_to_irq(vector) \ - (platform_legacy_irq(vector) ? vector : vector_irq[vector]) -#else -#define vector_to_irq(vector) (vector) -#endif - #define __DO_ACTION(R, ACTION, FINAL) \ \ { \ @@ -162,7 +156,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) spin_lock_irqsave(&ioapic_lock, flags); __DO_ACTION(1, = dest, ) - set_irq_info(irq, mask); + set_native_irq_info(irq, mask); spin_unlock_irqrestore(&ioapic_lock, flags); } #endif @@ -599,18 +593,14 @@ static inline int IO_APIC_irq_trigger(int irq) /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; -int assign_irq_vector(int irq) +static int __assign_irq_vector(int irq) { static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; - unsigned long flags; int vector; - BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS); - - spin_lock_irqsave(&vector_lock, flags); + BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); - if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) { - spin_unlock_irqrestore(&vector_lock, flags); + if (IO_APIC_VECTOR(irq) > 0) { return IO_APIC_VECTOR(irq); } next: @@ -625,10 +615,18 @@ next: } vector = current_vector; - vector_irq[vector] = irq; - if (irq != AUTO_ASSIGN) - IO_APIC_VECTOR(irq) = vector; + IO_APIC_VECTOR(irq) = vector; + + return vector; +} + +static int assign_irq_vector(int irq) +{ + int vector; + unsigned long flags; + spin_lock_irqsave(&vector_lock, flags); + vector = __assign_irq_vector(irq); spin_unlock_irqrestore(&vector_lock, flags); return vector; @@ -644,18 +642,14 @@ static struct irq_chip ioapic_chip; static void ioapic_register_intr(int irq, int vector, unsigned long trigger) { - unsigned idx; - - idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || trigger == IOAPIC_LEVEL) - set_irq_chip_and_handler(idx, &ioapic_chip, + set_irq_chip_and_handler(irq, &ioapic_chip, handle_fasteoi_irq); else - set_irq_chip_and_handler(idx, &ioapic_chip, + set_irq_chip_and_handler(irq, &ioapic_chip, handle_edge_irq); - set_intr_gate(vector, interrupt[idx]); + set_intr_gate(vector, interrupt[irq]); } static void __init setup_IO_APIC_irqs(void) @@ -872,17 +866,12 @@ void __apicdebuginit print_IO_APIC(void) ); } } - if (use_pci_vector()) - printk(KERN_INFO "Using vector-based indexing\n"); printk(KERN_DEBUG "IRQ to pin mappings:\n"); for (i = 0; i < NR_IRQS; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; - if (use_pci_vector() && !platform_legacy_irq(i)) - printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); - else - printk(KERN_DEBUG "IRQ%d ", i); + printk(KERN_DEBUG "IRQ%d ", i); for (;;) { printk("-> %d:%d", entry->apic, entry->pin); if (!entry->next) @@ -1206,42 +1195,8 @@ static unsigned int startup_ioapic_irq(unsigned int irq) return was_pending; } -static unsigned int startup_ioapic_vector(unsigned int vector) -{ - int irq = vector_to_irq(vector); - - return startup_ioapic_irq(irq); -} - -static void mask_ioapic_vector (unsigned int vector) -{ - int irq = vector_to_irq(vector); - - mask_IO_APIC_irq(irq); -} - -static void unmask_ioapic_vector (unsigned int vector) -{ - int irq = vector_to_irq(vector); - - unmask_IO_APIC_irq(irq); -} - -#ifdef CONFIG_SMP -static void set_ioapic_affinity_vector (unsigned int vector, - cpumask_t cpu_mask) -{ - int irq = vector_to_irq(vector); - - set_native_irq_info(vector, cpu_mask); - set_ioapic_affinity_irq(irq, cpu_mask); -} -#endif // CONFIG_SMP - -static int ioapic_retrigger_vector(unsigned int vector) +static int ioapic_retrigger_irq(unsigned int irq) { - int irq = vector_to_irq(vector); - send_IPI_self(IO_APIC_VECTOR(irq)); return 1; @@ -1288,15 +1243,15 @@ static void ack_apic_level(unsigned int irq) static struct irq_chip ioapic_chip __read_mostly = { .name = "IO-APIC", - .startup = startup_ioapic_vector, - .mask = mask_ioapic_vector, - .unmask = unmask_ioapic_vector, + .startup = startup_ioapic_irq, + .mask = mask_IO_APIC_irq, + .unmask = unmask_IO_APIC_irq, .ack = ack_apic_edge, .eoi = ack_apic_level, #ifdef CONFIG_SMP - .set_affinity = set_ioapic_affinity_vector, + .set_affinity = set_ioapic_affinity_irq, #endif - .retrigger = ioapic_retrigger_vector, + .retrigger = ioapic_retrigger_irq, }; static inline void init_IO_APIC_traps(void) @@ -1316,11 +1271,6 @@ static inline void init_IO_APIC_traps(void) */ for (irq = 0; irq < NR_IRQS ; irq++) { int tmp = irq; - if (use_pci_vector()) { - if (!platform_legacy_irq(tmp)) - if ((tmp = vector_to_irq(tmp)) == -1) - continue; - } if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { /* * Hmm.. We don't have an entry for this, @@ -1695,32 +1645,33 @@ static int __init ioapic_init_sysfs(void) device_initcall(ioapic_init_sysfs); -#ifdef CONFIG_PCI_MSI /* - * Dynamic irq allocate and deallocation for MSI + * Dynamic irq allocate and deallocation */ int create_irq(void) { - /* Hack of the day: irq == vector. - * - * Ultimately this will be be more general, - * and not depend on the irq to vector identity mapping. - * But this version is needed until msi.c can cope with - * the more general form. - */ - int irq, vector; + /* Allocate an unused irq */ + int irq; + int new; + int vector = 0; unsigned long flags; - vector = assign_irq_vector(AUTO_ASSIGN); - irq = vector; - if (vector >= 0) { - spin_lock_irqsave(&vector_lock, flags); - vector_irq[vector] = irq; - irq_vector[irq] = vector; - spin_unlock_irqrestore(&vector_lock, flags); + irq = -ENOSPC; + spin_lock_irqsave(&vector_lock, flags); + for (new = (NR_IRQS - 1); new >= 0; new--) { + if (platform_legacy_irq(new)) + continue; + if (irq_vector[new] != 0) + continue; + vector = __assign_irq_vector(new); + if (likely(vector > 0)) + irq = new; + break; + } + spin_unlock_irqrestore(&vector_lock, flags); + if (irq >= 0) { set_intr_gate(vector, interrupt[irq]); - dynamic_irq_init(irq); } return irq; @@ -1729,17 +1680,13 @@ int create_irq(void) void destroy_irq(unsigned int irq) { unsigned long flags; - unsigned int vector; dynamic_irq_cleanup(irq); spin_lock_irqsave(&vector_lock, flags); - vector = irq_vector[irq]; - vector_irq[vector] = -1; irq_vector[irq] = 0; spin_unlock_irqrestore(&vector_lock, flags); } -#endif /* * MSI mesage composition @@ -1882,7 +1829,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p ioapic_write_entry(ioapic, pin, entry); spin_lock_irqsave(&ioapic_lock, flags); - set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); + set_native_irq_info(irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); return 0; diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h index f5da94af9c..1a8dc185a7 100644 --- a/include/asm-x86_64/hw_irq.h +++ b/include/asm-x86_64/hw_irq.h @@ -75,7 +75,6 @@ #ifndef __ASSEMBLY__ extern u8 irq_vector[NR_IRQ_VECTORS]; #define IO_APIC_VECTOR(irq) (irq_vector[irq]) -#define AUTO_ASSIGN -1 /* * Various low-level irq details needed by irq.c, process.c, diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h index 5d1b5c68e3..df579ac29a 100644 --- a/include/asm-x86_64/io_apic.h +++ b/include/asm-x86_64/io_apic.h @@ -10,45 +10,7 @@ * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar */ -#ifdef CONFIG_PCI_MSI -static inline int use_pci_vector(void) {return 1;} -static inline void disable_edge_ioapic_vector(unsigned int vector) { } -static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { } -static inline void end_edge_ioapic_vector (unsigned int vector) { } -#define startup_level_ioapic startup_level_ioapic_vector -#define shutdown_level_ioapic mask_IO_APIC_vector -#define enable_level_ioapic unmask_IO_APIC_vector -#define disable_level_ioapic mask_IO_APIC_vector -#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector -#define end_level_ioapic end_level_ioapic_vector -#define set_ioapic_affinity set_ioapic_affinity_vector - -#define startup_edge_ioapic startup_edge_ioapic_vector -#define shutdown_edge_ioapic disable_edge_ioapic_vector -#define enable_edge_ioapic unmask_IO_APIC_vector -#define disable_edge_ioapic disable_edge_ioapic_vector -#define ack_edge_ioapic ack_edge_ioapic_vector -#define end_edge_ioapic end_edge_ioapic_vector -#else static inline int use_pci_vector(void) {return 0;} -static inline void disable_edge_ioapic_irq(unsigned int irq) { } -static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { } -static inline void end_edge_ioapic_irq (unsigned int irq) { } -#define startup_level_ioapic startup_level_ioapic_irq -#define shutdown_level_ioapic mask_IO_APIC_irq -#define enable_level_ioapic unmask_IO_APIC_irq -#define disable_level_ioapic mask_IO_APIC_irq -#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq -#define end_level_ioapic end_level_ioapic_irq -#define set_ioapic_affinity set_ioapic_affinity_irq - -#define startup_edge_ioapic startup_edge_ioapic_irq -#define shutdown_edge_ioapic disable_edge_ioapic_irq -#define enable_edge_ioapic unmask_IO_APIC_irq -#define disable_edge_ioapic disable_edge_ioapic_irq -#define ack_edge_ioapic ack_edge_ioapic_irq -#define end_edge_ioapic end_edge_ioapic_irq -#endif #define APIC_MISMATCH_DEBUG @@ -207,8 +169,6 @@ extern int timer_uses_ioapic_pin_0; extern int sis_apic_bug; /* dummy */ -extern int assign_irq_vector(int irq); - void enable_NMI_through_LVT0 (void * dummy); extern spinlock_t i8259A_lock; diff --git a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h index 43469d8ab7..b8f8728784 100644 --- a/include/asm-x86_64/irq.h +++ b/include/asm-x86_64/irq.h @@ -31,13 +31,8 @@ #define FIRST_SYSTEM_VECTOR 0xef /* duplicated in hw_irq.h */ -#ifdef CONFIG_PCI_MSI -#define NR_IRQS FIRST_SYSTEM_VECTOR -#define NR_IRQ_VECTORS NR_IRQS -#else #define NR_IRQS 224 #define NR_IRQ_VECTORS (32 * NR_CPUS) -#endif static __inline__ int irq_canonicalize(int irq) { -- 2.39.5