The patch titled msi: simplify msi sanity checks by adding with generic irq code has been added to the -mm tree. Its filename is msi-simplify-msi-sanity-checks-by-adding-with-generic-irq-code.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: msi: simplify msi sanity checks by adding with generic irq code From: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx> Currently msi.c is doing sanity checks that make certain before an irq is destroyed it has no more users. By adding irq_has_action I can perform the test is a generic way, instead of relying on a msi specific data structure. By performing the core check in dynamic_irq_cleanup I ensure every user of dynamic irqs has a test present and we don't free resources that are in use. In msi.c this allows me to kill the attrib.state member of msi_desc and all of the assciated code to maintain it. To keep from freeing data structures when irq cleanup code is called to soon changing dyanamic_irq_cleanup is insufficient because there are msi specific data structures that are also not safe to free. Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxx> Cc: Tony Luck <tony.luck@xxxxxxxxx> Cc: Andi Kleen <ak@xxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Greg KH <greg@xxxxxxxxx> Cc: Benjamin Herrenschmidt <benh@xxxxxxxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- drivers/pci/msi.c | 43 +++++++----------------------------------- drivers/pci/msi.h | 2 - include/linux/irq.h | 7 ++++++ kernel/irq/chip.c | 7 ++++++ 4 files changed, 23 insertions(+), 36 deletions(-) diff -puN drivers/pci/msi.c~msi-simplify-msi-sanity-checks-by-adding-with-generic-irq-code drivers/pci/msi.c --- a/drivers/pci/msi.c~msi-simplify-msi-sanity-checks-by-adding-with-generic-irq-code +++ a/drivers/pci/msi.c @@ -188,18 +188,6 @@ static void unmask_MSI_irq(unsigned int static unsigned int startup_msi_irq_wo_maskbit(unsigned int irq) { - struct msi_desc *entry; - unsigned long flags; - - spin_lock_irqsave(&msi_lock, flags); - entry = msi_desc[irq]; - if (!entry || !entry->dev) { - spin_unlock_irqrestore(&msi_lock, flags); - return 0; - } - entry->msi_attrib.state = 1; /* Mark it active */ - spin_unlock_irqrestore(&msi_lock, flags); - return 0; /* never anything pending */ } @@ -212,14 +200,6 @@ static unsigned int startup_msi_irq_w_ma static void shutdown_msi_irq(unsigned int irq) { - struct msi_desc *entry; - unsigned long flags; - - spin_lock_irqsave(&msi_lock, flags); - entry = msi_desc[irq]; - if (entry && entry->dev) - entry->msi_attrib.state = 0; /* Mark it not active */ - spin_unlock_irqrestore(&msi_lock, flags); } static void end_msi_irq_wo_maskbit(unsigned int irq) @@ -671,7 +651,6 @@ static int msi_capability_init(struct pc entry->link.head = irq; entry->link.tail = irq; entry->msi_attrib.type = PCI_CAP_ID_MSI; - entry->msi_attrib.state = 0; /* Mark it not active */ entry->msi_attrib.is_64 = is_64bit_address(control); entry->msi_attrib.entry_nr = 0; entry->msi_attrib.maskbit = is_mask_bit_support(control); @@ -744,7 +723,6 @@ static int msix_capability_init(struct p j = entries[i].entry; entries[i].vector = irq; entry->msi_attrib.type = PCI_CAP_ID_MSIX; - entry->msi_attrib.state = 0; /* Mark it not active */ entry->msi_attrib.is_64 = 1; entry->msi_attrib.entry_nr = j; entry->msi_attrib.maskbit = 1; @@ -897,12 +875,12 @@ void pci_disable_msi(struct pci_dev* dev spin_unlock_irqrestore(&msi_lock, flags); return; } - if (entry->msi_attrib.state) { + if (irq_has_action(dev->irq)) { spin_unlock_irqrestore(&msi_lock, flags); printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " "free_irq() on MSI irq %d\n", pci_name(dev), dev->irq); - BUG_ON(entry->msi_attrib.state > 0); + BUG_ON(irq_has_action(dev->irq)); } else { default_irq = entry->msi_attrib.default_irq; spin_unlock_irqrestore(&msi_lock, flags); @@ -1035,17 +1013,16 @@ void pci_disable_msix(struct pci_dev* de temp = dev->irq; if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { - int state, irq, head, tail = 0, warning = 0; + int irq, head, tail = 0, warning = 0; unsigned long flags; irq = head = dev->irq; dev->irq = temp; /* Restore pin IRQ */ while (head != tail) { spin_lock_irqsave(&msi_lock, flags); - state = msi_desc[irq]->msi_attrib.state; tail = msi_desc[irq]->link.tail; spin_unlock_irqrestore(&msi_lock, flags); - if (state) + if (irq_has_action(irq)) warning = 1; else if (irq != head) /* Release MSI-X irq */ msi_free_irq(dev, irq); @@ -1072,7 +1049,7 @@ void pci_disable_msix(struct pci_dev* de **/ void msi_remove_pci_irq_vectors(struct pci_dev* dev) { - int state, pos, temp; + int pos, temp; unsigned long flags; if (!pci_msi_enable || !dev) @@ -1081,14 +1058,11 @@ void msi_remove_pci_irq_vectors(struct p temp = dev->irq; /* Save IOAPIC IRQ */ pos = pci_find_capability(dev, PCI_CAP_ID_MSI); if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { - spin_lock_irqsave(&msi_lock, flags); - state = msi_desc[dev->irq]->msi_attrib.state; - spin_unlock_irqrestore(&msi_lock, flags); - if (state) { + if (irq_has_action(dev->irq)) { printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " "called without free_irq() on MSI irq %d\n", pci_name(dev), dev->irq); - BUG_ON(state > 0); + BUG_ON(irq_has_action(dev->irq)); } else /* Release MSI irq assigned to this device */ msi_free_irq(dev, dev->irq); dev->irq = temp; /* Restore IOAPIC IRQ */ @@ -1101,11 +1075,10 @@ void msi_remove_pci_irq_vectors(struct p irq = head = dev->irq; while (head != tail) { spin_lock_irqsave(&msi_lock, flags); - state = msi_desc[irq]->msi_attrib.state; tail = msi_desc[irq]->link.tail; base = msi_desc[irq]->mask_base; spin_unlock_irqrestore(&msi_lock, flags); - if (state) + if (irq_has_action(irq)) warning = 1; else if (irq != head) /* Release MSI-X irq */ msi_free_irq(dev, irq); diff -puN drivers/pci/msi.h~msi-simplify-msi-sanity-checks-by-adding-with-generic-irq-code drivers/pci/msi.h --- a/drivers/pci/msi.h~msi-simplify-msi-sanity-checks-by-adding-with-generic-irq-code +++ a/drivers/pci/msi.h @@ -53,7 +53,7 @@ struct msi_desc { struct { __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */ __u8 maskbit : 1; /* mask-pending bit supported ? */ - __u8 state : 1; /* {0: free, 1: busy} */ + __u8 unused : 1; __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ __u8 pos; /* Location of the msi capability */ __u16 entry_nr; /* specific enabled entry */ diff -puN include/linux/irq.h~msi-simplify-msi-sanity-checks-by-adding-with-generic-irq-code include/linux/irq.h --- a/include/linux/irq.h~msi-simplify-msi-sanity-checks-by-adding-with-generic-irq-code +++ a/include/linux/irq.h @@ -373,6 +373,13 @@ set_irq_chained_handler(unsigned int irq extern int create_irq(void); extern void destroy_irq(unsigned int irq); +/* Test to see if a driver has successfully requested an irq */ +static inline int irq_has_action(unsigned int irq) +{ + struct irq_desc *desc = irq_desc + irq; + return desc->action != NULL; +} + /* Dynamic irq helper functions */ extern void dynamic_irq_init(unsigned int irq); extern void dynamic_irq_cleanup(unsigned int irq); diff -puN kernel/irq/chip.c~msi-simplify-msi-sanity-checks-by-adding-with-generic-irq-code kernel/irq/chip.c --- a/kernel/irq/chip.c~msi-simplify-msi-sanity-checks-by-adding-with-generic-irq-code +++ a/kernel/irq/chip.c @@ -151,6 +151,13 @@ void dynamic_irq_cleanup(unsigned int ir desc = irq_desc + irq; spin_lock_irqsave(&desc->lock, flags); + if (desc->action) { + spin_unlock_irqrestore(&desc->lock, flags); + printk(KERN_ERR "Destroying IRQ%d without calling free_irq\n", + irq); + WARN_ON(1); + return; + } desc->handle_irq = handle_bad_irq; desc->chip = &no_irq_chip; spin_unlock_irqrestore(&desc->lock, flags); _ Patches currently in -mm which might be from ebiederm@xxxxxxxxxxxx are origin.patch git-scsi-misc.patch fix-conflict-with-the-is_init-identifier-on-parisc.patch pidspace-is_init.patch simplify-update_times-avoid-jiffies-jiffies_64-aliasing-problem-2.patch kexec-warning-fix.patch kill-extraneous-printk-in-kernel_restart.patch fix-mem_write-return-value.patch kcore-elf-note-namesz-field-fix.patch stack-overflow-safe-kdump-safe_smp_processor_id.patch stack-overflow-safe-kdump-safe_smp_processor_id_voyager.patch stack-overflow-safe-kdump-crash_use_safe_smp_processor_id.patch stack-overflow-safe-kdump-crash_use_safe_smp_processor_id-fix.patch stack-overflow-safe-kdump-safe_smp_send_nmi_allbutself.patch proc-readdir-race-fix-take-3.patch proc-readdir-race-fix-take-3-race-fix.patch proc-reorder-the-functions-in-basec.patch proc-modify-proc_pident_lookup-to-be-completely-table-driven.patch proc-give-the-root-directory-a-task.patch pid-implement-access-helpers-for-a-tacks-various-process-groups.patch pid-add-do_each_pid_task.patch pid-implement-signal-functions-that-take-a-struct-pid.patch pid-export-the-symbols-needed-to-use-struct-pid.patch pid-implement-pid_nr.patch vt-rework-the-console-spawning-variables.patch vt-make-vt_pid-a-struct-pid-making-it-pid-wrap-around-safe.patch file-modify-struct-fown_struct-to-use-a-struct-pid.patch file-modify-struct-fown_struct-to-use-a-struct-pid-fix.patch pids-coding-style-use-struct-pidmap.patch proc-readdir-race-fix-take-3-fix-1.patch simplify-pid-iterators.patch move-pidmap-to-pspaceh.patch move-pidmap-to-pspaceh-fix.patch define-struct-pspace.patch proc-readdir-race-fix-take-3-fix-2.patch update-mq_notify-to-use-a-struct-pid.patch file-add-locking-to-f_getown.patch usb-fixup-usb-so-it-uses-struct-pid.patch s390-update-fs3270-to-use-a-struct-pid.patch proc-sysctl-add-_proc_do_string-helper.patch namespaces-add-nsproxy.patch namespaces-add-nsproxy-move-init_nsproxy-into-kernel-nsproxyc.patch namespaces-incorporate-fs-namespace-into-nsproxy.patch namespaces-incorporate-fs-namespace-into-nsproxy-whitespace.patch namespaces-exit_task_namespaces-invalidates-nsproxy.patch namespaces-utsname-introduce-temporary-helpers.patch namespaces-utsname-switch-to-using-uts-namespaces.patch namespaces-utsname-switch-to-using-uts-namespaces-klibc-bit.patch namespaces-utsname-use-init_utsname-when-appropriate-klibc-bit.patch namespaces-utsname-switch-to-using-uts-namespaces-klibc-bit-2.patch namespaces-utsname-use-init_utsname-when-appropriate.patch namespaces-utsname-implement-utsname-namespaces.patch namespaces-utsname-sysctl-hack.patch namespaces-utsname-remove-system_utsname.patch namespaces-utsname-implement-clone_newuts-flag.patch namespaces-utsname-implement-clone_newuts-flag-fix.patch uts-copy-nsproxy-only-when-needed.patch ipc-namespace-core.patch ipc-namespace-utils.patch proc-make-the-generation-of-the-self-symlink-table-driven.patch proc-factor-out-an-instantiate-method-from-every-lookup-method.patch proc-remove-the-hard-coded-inode-numbers.patch proc-merge-proc_tid_attr-and-proc_tgid_attr.patch proc-use-pid_task-instead-of-open-coding-it.patch proc-convert-task_sig-to-use-lock_task_sighand.patch proc-convert-do_task_stat-to-use-lock_task_sighand.patch proc-drop-tasklist-lock-in-task_state.patch proc-properly-compute-tgid_offset.patch proc-remove-trailing-blank-entry-from-pid_entry-arrays.patch proc-remove-the-useless-smp-safe-comments-from-proc.patch proc-comment-what-proc_fill_cache-does.patch introduce-get_task_pid-to-fix-unsafe-get_pid.patch replace-cad_pid-by-a-struct-pid.patch replace-cad_pid-by-a-struct-pid-fixes.patch genirq-msi-restore-__do_irq-compat-logic-temporarily.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-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-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-msi-only-build-msi-apicc-on-ia64-fix.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-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-make-vector_irq-per-cpu-fix.patch genirq-x86_64-irq-make-vector_irq-per-cpu-warning-fix.patch genirq-x86_64-irq-kill-gsi_irq_sharing.patch genirq-x86_64-irq-kill-irq-compression.patch add-hypertransport-capability-defines.patch add-hypertransport-capability-defines-fix.patch initial-generic-hypertransport-interrupt-support.patch initial-generic-hypertransport-interrupt-support-Kconfig-fix.patch msi-simplify-msi-sanity-checks-by-adding-with-generic-irq-code.patch msi-only-use-a-single-irq_chip-for-msi-interrupts.patch msi-refactor-and-move-the-msi-irq_chip-into-the-arch-code.patch msi-move-the-ia64-code-into-arch-ia64.patch htirq-tidy-up-the-htirq-code.patch pidhash-temporary-debug-checks.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