The patch titled genirq: x86_64 irq: Remove the msi assumption that irq == vector has been added to the -mm tree. Its filename is genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: genirq: x86_64 irq: Remove the msi assumption that irq == vector From: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx> 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 <ebiederm@xxxxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Benjamin Herrenschmidt <benh@xxxxxxxxxxxxxxxxxxx> Cc: Rajesh Shah <rajesh.shah@xxxxxxxxx> Cc: Andi Kleen <ak@xxxxxx> Cc: "Protasevich, Natalie" <Natalie.Protasevich@xxxxxxxxxx> Cc: "Luck, Tony" <tony.luck@xxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- 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, 45 insertions(+), 148 deletions(-) diff -puN arch/x86_64/kernel/io_apic.c~genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector arch/x86_64/kernel/io_apic.c --- a/arch/x86_64/kernel/io_apic.c~genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector +++ a/arch/x86_64/kernel/io_apic.c @@ -44,6 +44,8 @@ #include <asm/nmi.h> #include <asm/msidef.h> +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) \ \ { \ @@ -135,7 +129,7 @@ static void set_ioapic_affinity_irq(unsi 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 @@ -834,18 +828,14 @@ static inline int IO_APIC_irq_trigger(in /* 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: @@ -860,10 +850,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; @@ -879,18 +877,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) @@ -1110,17 +1104,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) @@ -1523,42 +1512,8 @@ static unsigned int startup_ioapic_irq(u 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) +static int ioapic_retrigger_irq(unsigned int irq) { - 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) -{ - int irq = vector_to_irq(vector); - send_IPI_self(IO_APIC_VECTOR(irq)); return 1; @@ -1605,15 +1560,15 @@ static void ack_apic_level(unsigned int 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) @@ -1633,11 +1588,6 @@ static inline void init_IO_APIC_traps(vo */ 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, @@ -2014,34 +1964,31 @@ 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, new, vector; unsigned long flags; - vector = assign_irq_vector(AUTO_ASSIGN); - irq = vector; - if (vector >= 0) { - struct irq_desc *desc; - - 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; @@ -2050,17 +1997,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 @@ -2216,7 +2159,7 @@ int io_apic_set_pci_routing (int ioapic, spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); - 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 -puN include/asm-x86_64/hw_irq.h~genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector include/asm-x86_64/hw_irq.h --- a/include/asm-x86_64/hw_irq.h~genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector +++ a/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 -puN include/asm-x86_64/io_apic.h~genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector include/asm-x86_64/io_apic.h --- a/include/asm-x86_64/io_apic.h~genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector +++ a/include/asm-x86_64/io_apic.h @@ -12,45 +12,7 @@ #ifdef CONFIG_X86_IO_APIC -#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 @@ -213,8 +175,6 @@ extern int sis_apic_bug; /* dummy */ #define io_apic_assign_pci_irqs 0 #endif -extern int assign_irq_vector(int irq); - void enable_NMI_through_LVT0 (void * dummy); extern spinlock_t i8259A_lock; diff -puN include/asm-x86_64/irq.h~genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector include/asm-x86_64/irq.h --- a/include/asm-x86_64/irq.h~genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector +++ a/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) { _ Patches currently in -mm which might be from ebiederm@xxxxxxxxxxxx are add-a-sysfs-file-to-determine-if-a-kexec-kernel-is-loaded.patch avoid-tasklist_lock-at-getrusage-for-multithreaded-case-too.patch ptrace-document-the-locking-rules.patch proc-fix-the-inode-number-on-proc-pid-fd.patch proc-remove-useless-bkl-in-proc_pid_readlink.patch proc-remove-unnecessary-and-misleading-assignments.patch proc-simplify-the-ownership-rules-for-proc.patch proc-replace-proc_inodetype-with-proc_inodefd.patch proc-remove-bogus-proc_task_permission.patch proc-kill-proc_mem_inode_operations.patch proc-properly-filter-out-files-that-are-not-visible.patch proc-fix-the-link-count-for-proc-pid-task.patch proc-move-proc_maps_operations-into-task_mmuc.patch proc-rewrite-the-proc-dentry-flush-on-exit.patch proc-close-the-race-of-a-process-dying-durning.patch proc-refactor-reading-directories-of-tasks.patch proc-remove-tasklist_lock-from-proc_pid_readdir.patch proc-remove-tasklist_lock-from-proc_pid_lookup-and.patch proc-remove-tasklist_lock-from-proc_pid_readdir-simply-fix-first_tgid.patch proc-make-proc_numbuf-the-buffer-size-for-holding-a.patch proc-dont-lock-task_structs-indefinitely.patch proc-dont-lock-task_structs-indefinitely-task_mmu-small-fixes.patch proc-use-struct-pid-not-struct-task_ref.patch proc-optimize-proc_check_dentry_visible.patch proc-use-sane-permission-checks-on-the-proc-pid-fd.patch proc-cleanup-proc_fd_access_allowed.patch proc-remove-tasklist_lock-from-proc_task_readdir.patch simplify-fix-first_tid.patch cleanup-next_tid.patch de_thread-fix-lockless-do_each_thread.patch coredump-optimize-mm-users-traversal.patch coredump-speedup-sigkill-sending.patch coredump-kill-ptrace-related-stuff.patch coredump-kill-ptrace-related-stuff-fix.patch coredump-dont-take-tasklist_lock.patch proc-sysctl-add-_proc_do_string-helper.patch namespaces-add-nsproxy.patch namespaces-add-nsproxy-dont-include-compileh.patch namespaces-incorporate-fs-namespace-into-nsproxy.patch namespaces-utsname-introduce-temporary-helpers.patch namespaces-utsname-switch-to-using-uts-namespaces.patch namespaces-utsname-switch-to-using-uts-namespaces-alpha-fix.patch namespaces-utsname-switch-to-using-uts-namespaces-cleanup.patch namespaces-utsname-use-init_utsname-when-appropriate.patch namespaces-utsname-use-init_utsname-when-appropriate-cifs-update.patch namespaces-utsname-implement-utsname-namespaces.patch namespaces-utsname-implement-utsname-namespaces-export.patch namespaces-utsname-implement-utsname-namespaces-dont-include-compileh.patch namespaces-utsname-sysctl-hack.patch namespaces-utsname-sysctl-hack-cleanup.patch namespaces-utsname-sysctl-hack-cleanup-2.patch namespaces-utsname-sysctl-hack-cleanup-2-fix.patch namespaces-utsname-remove-system_utsname.patch namespaces-utsname-implement-clone_newuts-flag.patch uts-copy-nsproxy-only-when-needed.patch ipc-namespace-core-fix.patch ipc-namespace-core-unshare-fix.patch ipc-namespace-utils-compilation-fix.patch genirq-irq-convert-the-move_irq-flag-from-a-32bit-word-to-a-single-bit.patch genirq-irq-add-moved_masked_irq.patch genirq-x86_64-irq-reenable-migrating-irqs-to-other-cpus.patch genirq-msi-simplify-msi-enable-and-disable.patch genirq-msi-simplify-msi-enable-and-disable-fix.patch genirq-msi-make-the-msi-boolean-tests-return-either-0-or-1.patch genirq-msi-implement-helper-functions-read_msi_msg-and-write_msi_msg.patch genirq-msi-refactor-the-msi_ops.patch genirq-msi-simplify-the-msi-irq-limit-policy.patch genirq-irq-add-a-dynamic-irq-creation-api.patch genirq-ia64-irq-dynamic-irq-support.patch genirq-i386-irq-dynamic-irq-support.patch genirq-i386-irq-dynamic-irq-support-fix.patch genirq-x86_64-irq-dynamic-irq-support.patch genirq-msi-make-the-msi-code-irq-based-and-not-vector-based.patch genirq-x86_64-irq-move-msi-message-composition-into-io_apicc.patch genirq-i386-irq-move-msi-message-composition-into-io_apicc.patch genirq-msi-only-build-msi-apicc-on-ia64.patch genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector.patch genirq-i386-irq-remove-the-msi-assumption-that-irq-==-vector.patch genirq-i386-irq-remove-the-msi-assumption-that-irq-==-vector-fix.patch genirq-irq-remove-msi-hacks.patch genirq-irq-generalize-the-check-for-hardirq_bits.patch genirq-x86_64-irq-make-the-external-irq-handlers-report-their-vector-not-the-irq-number.patch genirq-x86_64-irq-make-vector_irq-per-cpu.patch genirq-x86_64-irq-kill-gsi_irq_sharing.patch genirq-x86_64-irq-kill-irq-compression.patch genirq-irq-document-what-an-irq-is.patch pidhash-temporary-debug-checks.patch genirq-i386-irq-remove-the-msi-assumption-that-irq-==-vector-fix-tidies.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html