On Fri, Oct 19, 2012 at 3:41 AM, Chuansheng Liu
<chuansheng....@intel.com> wrote:
>
> When debugging our system issues related with __setup_vector_irq(),
> found there is a real wrong code that:
>         for_each_active_irq(irq) {
>                 cfg = irq_get_chip_data(irq);
>                 if (!cfg)
>                         continue;
>
> These codes presume all allocated irqs are ioapic irqs, but it is not
> like that, in our system there are many GPIO interrupts also.
>
> When one irq is not ioapic type irq, the chip_data will not be the
> type of struct irq_cfg in most cases.

impossible !

where is the irq_desc coming from. ?

after alloc_irq_from, alloc_irq_cfg get called too.

>
> So in function __setup_vector_irq(), it will cause some strange issues,
> moreover, if I added some prints(cfg->...) inside it, it can always
> cause system panic.
>
> Here using the struct irq_chip->flags to help identify if the irq
> is ioapic type or not.
>
> Looked forward all codes with for_each_active_irq(), found there is
> a commit 6fd36ba02 indicates the similar case in print_IO_APICs().

that is for not printing wrong for MSI etc.

>
> Signed-off-by: liu chuansheng <chuansheng....@intel.com>
> ---
>  arch/x86/kernel/apic/io_apic.c |   25 ++++++++++++++++++++++---
>  1 files changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> index c265593..f0355e6 100644
> --- a/arch/x86/kernel/apic/io_apic.c
> +++ b/arch/x86/kernel/apic/io_apic.c
> @@ -68,6 +68,18 @@
>  #define for_each_irq_pin(entry, head) \
>         for (entry = head; entry; entry = entry->next)
>
> +/* need more thoughts ... */
> +#define CHIP_FLAG_IOAPIC       0x1000
> +static inline bool is_ioapic_irq(int irq)
> +{
> +       struct irq_chip *chip;
> +       chip = irq_get_chip(irq);
> +       if ((chip) && (chip->flags == CHIP_FLAG_IOAPIC))
> +               return true;
> +
> +       return false;
> +}
> +
>  #ifdef CONFIG_IRQ_REMAP
>  static void irq_remap_modify_chip_defaults(struct irq_chip *chip);
>  static inline bool irq_remapped(struct irq_cfg *cfg)
> @@ -1238,6 +1250,9 @@ void __setup_vector_irq(int cpu)
>         raw_spin_lock(&vector_lock);
>         /* Mark the inuse vectors */
>         for_each_active_irq(irq) {
> +               if (!is_ioapic_irq(irq))
> +                       continue;
> +
>                 cfg = irq_get_chip_data(irq);
>                 if (!cfg)
>                         continue;
> @@ -1641,7 +1656,6 @@ __apicdebuginit(void) print_IO_APICs(void)
>         int ioapic_idx;
>         struct irq_cfg *cfg;
>         unsigned int irq;
> -       struct irq_chip *chip;
>
>         printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
>         for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
> @@ -1662,8 +1676,7 @@ __apicdebuginit(void) print_IO_APICs(void)
>         for_each_active_irq(irq) {
>                 struct irq_pin_list *entry;
>
> -               chip = irq_get_chip(irq);
> -               if (chip != &ioapic_chip)
> +               if (!is_ioapic_irq(irq))
>                         continue;
>
>                 cfg = irq_get_chip_data(irq);

if the irq is not using ioapic_chip such as msi_chip etc, that irq
should be skip.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to