* [patch] x86: handle legacy PIC interrupts on all the cpu's
@ 2010-03-15 22:33 Suresh Siddha
2010-03-15 21:51 ` Yinghai Lu
2010-03-16 6:00 ` [tip:x86/urgent] x86: Handle " tip-bot for Suresh Siddha
0 siblings, 2 replies; 10+ messages in thread
From: Suresh Siddha @ 2010-03-15 22:33 UTC (permalink / raw)
To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner, Yinghai Lu
Cc: LKML, Eric W. Biederman
Ingo Molnar reported that with the recent changes of not statically blocking
IRQ0_VECTOR..IRQ15_VECTOR's on all the cpu's, broke an AMD platform
(with Nvidia chipset) boot when "noapic" boot option is used.
On this platform, legacy PIC interrupts are getting delivered to all the
cpu's instead of just the boot cpu. Thus not initializing the vector to irq
mapping for the legacy irq's resulted in not handling certain interrupts
causing boot hang.
Fix this by initializing the vector to irq mapping on all the logical cpu's,
if the legacy IRQ is handled by the legacy PIC.
Reported-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index a929c9e..46c0fe0 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -133,6 +133,7 @@ extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
typedef int vector_irq_t[NR_VECTORS];
DECLARE_PER_CPU(vector_irq_t, vector_irq);
+extern void setup_vector_irq(int cpu);
#ifdef CONFIG_X86_IO_APIC
extern void lock_vector_lock(void);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e4e0ddc..10f0a1a 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1268,6 +1268,14 @@ void __setup_vector_irq(int cpu)
/* Mark the inuse vectors */
for_each_irq_desc(irq, desc) {
cfg = desc->chip_data;
+
+ /*
+ * If it is a legacy IRQ handled by the legacy PIC, this cpu
+ * will be part of the irq_cfg's domain.
+ */
+ if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq))
+ cpumask_set_cpu(cpu, cfg->domain);
+
if (!cpumask_test_cpu(cpu, cfg->domain))
continue;
vector = cfg->vector;
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index ef257fc..daaf413 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -141,6 +141,27 @@ void __init init_IRQ(void)
x86_init.irqs.intr_init();
}
+/*
+ * Setup the vector to irq mappings.
+ */
+void setup_vector_irq(int cpu)
+{
+ int irq;
+
+ /*
+ * On most of the platforms, legacy PIC delivers the interrupts on the
+ * boot cpu. But there are certain platforms where PIC interrupts are
+ * delivered to multiple cpu's. If the legacy IRQ is handled by the
+ * legacy PIC, for the new cpu that is coming online, setup the static
+ * legacy vector to irq mapping.
+ */
+ for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
+ if (!IO_APIC_IRQ(irq))
+ per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
+
+ __setup_vector_irq(cpu);
+}
+
static void __init smp_intr_init(void)
{
#ifdef CONFIG_SMP
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index a02e80c..06d98ae 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -247,7 +247,7 @@ static void __cpuinit smp_callin(void)
/*
* Need to setup vector mappings before we enable interrupts.
*/
- __setup_vector_irq(smp_processor_id());
+ setup_vector_irq(smp_processor_id());
/*
* Get our bogomips.
*
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [patch] x86: handle legacy PIC interrupts on all the cpu's
2010-03-15 22:33 [patch] x86: handle legacy PIC interrupts on all the cpu's Suresh Siddha
@ 2010-03-15 21:51 ` Yinghai Lu
2010-03-15 22:56 ` Suresh Siddha
2010-03-16 6:00 ` [tip:x86/urgent] x86: Handle " tip-bot for Suresh Siddha
1 sibling, 1 reply; 10+ messages in thread
From: Yinghai Lu @ 2010-03-15 21:51 UTC (permalink / raw)
To: Suresh Siddha
Cc: Ingo Molnar, H. Peter Anvin, Thomas Gleixner, LKML,
Eric W. Biederman
On 03/15/2010 03:33 PM, Suresh Siddha wrote:
> Ingo Molnar reported that with the recent changes of not statically blocking
> IRQ0_VECTOR..IRQ15_VECTOR's on all the cpu's, broke an AMD platform
> (with Nvidia chipset) boot when "noapic" boot option is used.
>
> On this platform, legacy PIC interrupts are getting delivered to all the
> cpu's instead of just the boot cpu. Thus not initializing the vector to irq
> mapping for the legacy irq's resulted in not handling certain interrupts
> causing boot hang.
>
> Fix this by initializing the vector to irq mapping on all the logical cpu's,
> if the legacy IRQ is handled by the legacy PIC.
>
> Reported-by: Ingo Molnar <mingo@elte.hu>
> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
> ---
>
> diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
> index a929c9e..46c0fe0 100644
> --- a/arch/x86/include/asm/hw_irq.h
> +++ b/arch/x86/include/asm/hw_irq.h
> @@ -133,6 +133,7 @@ extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
>
> typedef int vector_irq_t[NR_VECTORS];
> DECLARE_PER_CPU(vector_irq_t, vector_irq);
> +extern void setup_vector_irq(int cpu);
>
> #ifdef CONFIG_X86_IO_APIC
> extern void lock_vector_lock(void);
> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> index e4e0ddc..10f0a1a 100644
> --- a/arch/x86/kernel/apic/io_apic.c
> +++ b/arch/x86/kernel/apic/io_apic.c
> @@ -1268,6 +1268,14 @@ void __setup_vector_irq(int cpu)
> /* Mark the inuse vectors */
> for_each_irq_desc(irq, desc) {
> cfg = desc->chip_data;
> +
> + /*
> + * If it is a legacy IRQ handled by the legacy PIC, this cpu
> + * will be part of the irq_cfg's domain.
> + */
> + if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq))
> + cpumask_set_cpu(cpu, cfg->domain);
> +
> if (!cpumask_test_cpu(cpu, cfg->domain))
> continue;
> vector = cfg->vector;
> diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
> index ef257fc..daaf413 100644
> --- a/arch/x86/kernel/irqinit.c
> +++ b/arch/x86/kernel/irqinit.c
> @@ -141,6 +141,27 @@ void __init init_IRQ(void)
> x86_init.irqs.intr_init();
> }
>
> +/*
> + * Setup the vector to irq mappings.
> + */
> +void setup_vector_irq(int cpu)
> +{
> + int irq;
> +
> + /*
> + * On most of the platforms, legacy PIC delivers the interrupts on the
> + * boot cpu. But there are certain platforms where PIC interrupts are
> + * delivered to multiple cpu's. If the legacy IRQ is handled by the
> + * legacy PIC, for the new cpu that is coming online, setup the static
> + * legacy vector to irq mapping.
> + */
> + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> + if (!IO_APIC_IRQ(irq))
> + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
seems those three lines are not needed...
YH
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [patch] x86: handle legacy PIC interrupts on all the cpu's
2010-03-15 21:51 ` Yinghai Lu
@ 2010-03-15 22:56 ` Suresh Siddha
2010-03-15 22:15 ` Yinghai Lu
0 siblings, 1 reply; 10+ messages in thread
From: Suresh Siddha @ 2010-03-15 22:56 UTC (permalink / raw)
To: Yinghai Lu
Cc: Ingo Molnar, H. Peter Anvin, Thomas Gleixner, LKML,
Eric W. Biederman
On Mon, 2010-03-15 at 14:51 -0700, Yinghai Lu wrote:
> > + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> > + if (!IO_APIC_IRQ(irq))
> > + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
>
> seems those three lines are not needed...
Those are needed for !CONFIG_X86_IO_APIC case.
thanks,
suresh
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [patch] x86: handle legacy PIC interrupts on all the cpu's
2010-03-15 22:56 ` Suresh Siddha
@ 2010-03-15 22:15 ` Yinghai Lu
2010-03-16 5:37 ` Ingo Molnar
0 siblings, 1 reply; 10+ messages in thread
From: Yinghai Lu @ 2010-03-15 22:15 UTC (permalink / raw)
To: Suresh Siddha
Cc: Ingo Molnar, H. Peter Anvin, Thomas Gleixner, LKML,
Eric W. Biederman
On 03/15/2010 03:56 PM, Suresh Siddha wrote:
> On Mon, 2010-03-15 at 14:51 -0700, Yinghai Lu wrote:
>>> + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
>>> + if (!IO_APIC_IRQ(irq))
>>> + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
>>
>> seems those three lines are not needed...
>
> Those are needed for !CONFIG_X86_IO_APIC case.
>
then we can have
+#ifndef CONFIG_X86_IO_APIC
+ for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
+ per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
+#endif
then we don't punish most setup with ioapic controller.
Yinghai
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [patch] x86: handle legacy PIC interrupts on all the cpu's
2010-03-15 22:15 ` Yinghai Lu
@ 2010-03-16 5:37 ` Ingo Molnar
2010-03-16 5:57 ` Ingo Molnar
2010-03-16 6:54 ` Suresh Siddha
0 siblings, 2 replies; 10+ messages in thread
From: Ingo Molnar @ 2010-03-16 5:37 UTC (permalink / raw)
To: Yinghai Lu
Cc: Suresh Siddha, H. Peter Anvin, Thomas Gleixner, LKML,
Eric W. Biederman
* Yinghai Lu <yinghai@kernel.org> wrote:
> On 03/15/2010 03:56 PM, Suresh Siddha wrote:
> > On Mon, 2010-03-15 at 14:51 -0700, Yinghai Lu wrote:
> >>> + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> >>> + if (!IO_APIC_IRQ(irq))
> >>> + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
> >>
> >> seems those three lines are not needed...
> >
> > Those are needed for !CONFIG_X86_IO_APIC case.
> >
> then we can have
>
> +#ifndef CONFIG_X86_IO_APIC
> + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
> +#endif
>
> then we don't punish most setup with ioapic controller.
Ok - i've simplified the code with the above and have added your Acked-by - is
that is fine by you?
Thanks,
Ingo
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [patch] x86: handle legacy PIC interrupts on all the cpu's
2010-03-16 5:37 ` Ingo Molnar
@ 2010-03-16 5:57 ` Ingo Molnar
2010-03-16 6:54 ` Suresh Siddha
1 sibling, 0 replies; 10+ messages in thread
From: Ingo Molnar @ 2010-03-16 5:57 UTC (permalink / raw)
To: Yinghai Lu
Cc: Suresh Siddha, H. Peter Anvin, Thomas Gleixner, LKML,
Eric W. Biederman
* Ingo Molnar <mingo@elte.hu> wrote:
>
> * Yinghai Lu <yinghai@kernel.org> wrote:
>
> > On 03/15/2010 03:56 PM, Suresh Siddha wrote:
> > > On Mon, 2010-03-15 at 14:51 -0700, Yinghai Lu wrote:
> > >>> + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> > >>> + if (!IO_APIC_IRQ(irq))
> > >>> + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
> > >>
> > >> seems those three lines are not needed...
> > >
> > > Those are needed for !CONFIG_X86_IO_APIC case.
> > >
> > then we can have
> >
> > +#ifndef CONFIG_X86_IO_APIC
> > + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> > + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
> > +#endif
> >
> > then we don't punish most setup with ioapic controller.
>
> Ok - i've simplified the code with the above and have added your Acked-by - is
> that is fine by you?
btw., the patch fixes the regression on the testbox - thanks Suresh!
Ingo
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [patch] x86: handle legacy PIC interrupts on all the cpu's
2010-03-16 5:37 ` Ingo Molnar
2010-03-16 5:57 ` Ingo Molnar
@ 2010-03-16 6:54 ` Suresh Siddha
2010-03-16 6:35 ` Yinghai Lu
1 sibling, 1 reply; 10+ messages in thread
From: Suresh Siddha @ 2010-03-16 6:54 UTC (permalink / raw)
To: Ingo Molnar
Cc: Yinghai Lu, H. Peter Anvin, Thomas Gleixner, LKML,
Eric W. Biederman
On Mon, 2010-03-15 at 22:37 -0700, Ingo Molnar wrote:
> * Yinghai Lu <yinghai@kernel.org> wrote:
>
> > On 03/15/2010 03:56 PM, Suresh Siddha wrote:
> > > On Mon, 2010-03-15 at 14:51 -0700, Yinghai Lu wrote:
> > >>> + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> > >>> + if (!IO_APIC_IRQ(irq))
> > >>> + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
> > >>
> > >> seems those three lines are not needed...
> > >
> > > Those are needed for !CONFIG_X86_IO_APIC case.
> > >
> > then we can have
> >
> > +#ifndef CONFIG_X86_IO_APIC
> > + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> > + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
> > +#endif
> >
> > then we don't punish most setup with ioapic controller.
>
> Ok - i've simplified the code with the above and have added your Acked-by - is
> that is fine by you?
Ingo, Probably appended one is a better version. Yinghai can you please
Ack if it is ok. Thanks.
---
From: Suresh Siddha <suresh.b.siddha@intel.com>
Subject: x86: handle legacy PIC interrupts on all the cpu's
Ingo Molnar reported that with the recent changes of not statically blocking
IRQ0_VECTOR..IRQ15_VECTOR's on all the cpu's, broke an AMD platform
(with Nvidia chipset) boot when "noapic" boot option is used.
On this platform, legacy PIC interrupts are getting delivered to all the
cpu's instead of just the boot cpu. Thus not initializing the vector to irq
mapping for the legacy irq's resulted in not handling certain interrupts
causing boot hang.
Fix this by initializing the vector to irq mapping on all the logical cpu's,
if the legacy IRQ is handled by the legacy PIC.
Reported-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---
arch/x86/include/asm/hw_irq.h | 3 +--
arch/x86/kernel/apic/io_apic.c | 9 +++++++++
arch/x86/kernel/irqinit.c | 20 ++++++++++++++++++++
3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index a929c9e..564a7a1 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -133,15 +133,14 @@ extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
typedef int vector_irq_t[NR_VECTORS];
DECLARE_PER_CPU(vector_irq_t, vector_irq);
+extern void __setup_vector_irq(int cpu);
#ifdef CONFIG_X86_IO_APIC
extern void lock_vector_lock(void);
extern void unlock_vector_lock(void);
-extern void __setup_vector_irq(int cpu);
#else
static inline void lock_vector_lock(void) {}
static inline void unlock_vector_lock(void) {}
-static inline void __setup_vector_irq(int cpu) {}
#endif
#endif /* !ASSEMBLY_ */
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e4e0ddc..fd3cecd 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1268,6 +1268,15 @@ void __setup_vector_irq(int cpu)
/* Mark the inuse vectors */
for_each_irq_desc(irq, desc) {
cfg = desc->chip_data;
+
+ /*
+ * If it is a legacy IRQ handled by the legacy PIC, be ready
+ * to handle it on any CPU, as the PIC interrupts are delivered
+ * to multiple cpu's on some platforms.
+ */
+ if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq))
+ cpumask_set_cpu(cpu, cfg->domain);
+
if (!cpumask_test_cpu(cpu, cfg->domain))
continue;
vector = cfg->vector;
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index ef257fc..afc3b31 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -141,6 +141,26 @@ void __init init_IRQ(void)
x86_init.irqs.intr_init();
}
+#ifndef CONFIG_X86_IO_APIC
+/*
+ * Setup the vector to irq mappings.
+ */
+void __setup_vector_irq(int cpu)
+{
+ int irq;
+
+ /*
+ * On most of the platforms, legacy PIC delivers the interrupts on the
+ * boot cpu. But there are certain platforms where PIC interrupts are
+ * delivered to multiple cpu's. For the new cpu that is coming online,
+ * setup the static legacy vector to irq mapping.
+ */
+ for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
+ per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
+
+}
+#endif
+
static void __init smp_intr_init(void)
{
#ifdef CONFIG_SMP
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [patch] x86: handle legacy PIC interrupts on all the cpu's
2010-03-16 6:54 ` Suresh Siddha
@ 2010-03-16 6:35 ` Yinghai Lu
2010-03-16 7:29 ` Ingo Molnar
0 siblings, 1 reply; 10+ messages in thread
From: Yinghai Lu @ 2010-03-16 6:35 UTC (permalink / raw)
To: Suresh Siddha
Cc: Ingo Molnar, H. Peter Anvin, Thomas Gleixner, LKML,
Eric W. Biederman
On 03/15/2010 11:54 PM, Suresh Siddha wrote:
> On Mon, 2010-03-15 at 22:37 -0700, Ingo Molnar wrote:
>> * Yinghai Lu <yinghai@kernel.org> wrote:
>>
>>> On 03/15/2010 03:56 PM, Suresh Siddha wrote:
>>>> On Mon, 2010-03-15 at 14:51 -0700, Yinghai Lu wrote:
>>>>>> + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
>>>>>> + if (!IO_APIC_IRQ(irq))
>>>>>> + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
>>>>>
>>>>> seems those three lines are not needed...
>>>>
>>>> Those are needed for !CONFIG_X86_IO_APIC case.
>>>>
>>> then we can have
>>>
>>> +#ifndef CONFIG_X86_IO_APIC
>>> + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
>>> + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
>>> +#endif
>>>
>>> then we don't punish most setup with ioapic controller.
>>
>> Ok - i've simplified the code with the above and have added your Acked-by - is
>> that is fine by you?
>
> Ingo, Probably appended one is a better version. Yinghai can you please
> Ack if it is ok. Thanks.
>
> ---
> From: Suresh Siddha <suresh.b.siddha@intel.com>
> Subject: x86: handle legacy PIC interrupts on all the cpu's
>
> Ingo Molnar reported that with the recent changes of not statically blocking
> IRQ0_VECTOR..IRQ15_VECTOR's on all the cpu's, broke an AMD platform
> (with Nvidia chipset) boot when "noapic" boot option is used.
>
> On this platform, legacy PIC interrupts are getting delivered to all the
> cpu's instead of just the boot cpu. Thus not initializing the vector to irq
> mapping for the legacy irq's resulted in not handling certain interrupts
> causing boot hang.
>
> Fix this by initializing the vector to irq mapping on all the logical cpu's,
> if the legacy IRQ is handled by the legacy PIC.
>
> Reported-by: Ingo Molnar <mingo@elte.hu>
> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
> ---
>
> arch/x86/include/asm/hw_irq.h | 3 +--
> arch/x86/kernel/apic/io_apic.c | 9 +++++++++
> arch/x86/kernel/irqinit.c | 20 ++++++++++++++++++++
> 3 files changed, 30 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
> index a929c9e..564a7a1 100644
> --- a/arch/x86/include/asm/hw_irq.h
> +++ b/arch/x86/include/asm/hw_irq.h
> @@ -133,15 +133,14 @@ extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
>
> typedef int vector_irq_t[NR_VECTORS];
> DECLARE_PER_CPU(vector_irq_t, vector_irq);
> +extern void __setup_vector_irq(int cpu);
>
> #ifdef CONFIG_X86_IO_APIC
> extern void lock_vector_lock(void);
> extern void unlock_vector_lock(void);
> -extern void __setup_vector_irq(int cpu);
> #else
> static inline void lock_vector_lock(void) {}
> static inline void unlock_vector_lock(void) {}
> -static inline void __setup_vector_irq(int cpu) {}
> #endif
>
> #endif /* !ASSEMBLY_ */
> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> index e4e0ddc..fd3cecd 100644
> --- a/arch/x86/kernel/apic/io_apic.c
> +++ b/arch/x86/kernel/apic/io_apic.c
> @@ -1268,6 +1268,15 @@ void __setup_vector_irq(int cpu)
> /* Mark the inuse vectors */
> for_each_irq_desc(irq, desc) {
> cfg = desc->chip_data;
> +
> + /*
> + * If it is a legacy IRQ handled by the legacy PIC, be ready
> + * to handle it on any CPU, as the PIC interrupts are delivered
> + * to multiple cpu's on some platforms.
> + */
> + if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq))
> + cpumask_set_cpu(cpu, cfg->domain);
> +
> if (!cpumask_test_cpu(cpu, cfg->domain))
> continue;
> vector = cfg->vector;
> diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
> index ef257fc..afc3b31 100644
> --- a/arch/x86/kernel/irqinit.c
> +++ b/arch/x86/kernel/irqinit.c
> @@ -141,6 +141,26 @@ void __init init_IRQ(void)
> x86_init.irqs.intr_init();
> }
>
> +#ifndef CONFIG_X86_IO_APIC
> +/*
> + * Setup the vector to irq mappings.
> + */
> +void __setup_vector_irq(int cpu)
> +{
> + int irq;
> +
> + /*
> + * On most of the platforms, legacy PIC delivers the interrupts on the
> + * boot cpu. But there are certain platforms where PIC interrupts are
> + * delivered to multiple cpu's. For the new cpu that is coming online,
> + * setup the static legacy vector to irq mapping.
> + */
> + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
> +
> +}
> +#endif
> +
> static void __init smp_intr_init(void)
> {
> #ifdef CONFIG_SMP
>
yes, less one one function prototype.
Acked-by: Yinghai Lu <yinghai@kernel.org>
Yinghai
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [patch] x86: handle legacy PIC interrupts on all the cpu's
2010-03-16 6:35 ` Yinghai Lu
@ 2010-03-16 7:29 ` Ingo Molnar
0 siblings, 0 replies; 10+ messages in thread
From: Ingo Molnar @ 2010-03-16 7:29 UTC (permalink / raw)
To: Yinghai Lu
Cc: Suresh Siddha, H. Peter Anvin, Thomas Gleixner, LKML,
Eric W. Biederman
* Yinghai Lu <yinghai@kernel.org> wrote:
> On 03/15/2010 11:54 PM, Suresh Siddha wrote:
> > On Mon, 2010-03-15 at 22:37 -0700, Ingo Molnar wrote:
> >> * Yinghai Lu <yinghai@kernel.org> wrote:
> >>
> >>> On 03/15/2010 03:56 PM, Suresh Siddha wrote:
> >>>> On Mon, 2010-03-15 at 14:51 -0700, Yinghai Lu wrote:
> >>>>>> + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> >>>>>> + if (!IO_APIC_IRQ(irq))
> >>>>>> + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
> >>>>>
> >>>>> seems those three lines are not needed...
> >>>>
> >>>> Those are needed for !CONFIG_X86_IO_APIC case.
> >>>>
> >>> then we can have
> >>>
> >>> +#ifndef CONFIG_X86_IO_APIC
> >>> + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> >>> + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
> >>> +#endif
> >>>
> >>> then we don't punish most setup with ioapic controller.
> >>
> >> Ok - i've simplified the code with the above and have added your Acked-by - is
> >> that is fine by you?
> >
> > Ingo, Probably appended one is a better version. Yinghai can you please
> > Ack if it is ok. Thanks.
> >
> > ---
> > From: Suresh Siddha <suresh.b.siddha@intel.com>
> > Subject: x86: handle legacy PIC interrupts on all the cpu's
> >
> > Ingo Molnar reported that with the recent changes of not statically blocking
> > IRQ0_VECTOR..IRQ15_VECTOR's on all the cpu's, broke an AMD platform
> > (with Nvidia chipset) boot when "noapic" boot option is used.
> >
> > On this platform, legacy PIC interrupts are getting delivered to all the
> > cpu's instead of just the boot cpu. Thus not initializing the vector to irq
> > mapping for the legacy irq's resulted in not handling certain interrupts
> > causing boot hang.
> >
> > Fix this by initializing the vector to irq mapping on all the logical cpu's,
> > if the legacy IRQ is handled by the legacy PIC.
> >
> > Reported-by: Ingo Molnar <mingo@elte.hu>
> > Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
> > ---
> >
> > arch/x86/include/asm/hw_irq.h | 3 +--
> > arch/x86/kernel/apic/io_apic.c | 9 +++++++++
> > arch/x86/kernel/irqinit.c | 20 ++++++++++++++++++++
> > 3 files changed, 30 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
> > index a929c9e..564a7a1 100644
> > --- a/arch/x86/include/asm/hw_irq.h
> > +++ b/arch/x86/include/asm/hw_irq.h
> > @@ -133,15 +133,14 @@ extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
> >
> > typedef int vector_irq_t[NR_VECTORS];
> > DECLARE_PER_CPU(vector_irq_t, vector_irq);
> > +extern void __setup_vector_irq(int cpu);
> >
> > #ifdef CONFIG_X86_IO_APIC
> > extern void lock_vector_lock(void);
> > extern void unlock_vector_lock(void);
> > -extern void __setup_vector_irq(int cpu);
> > #else
> > static inline void lock_vector_lock(void) {}
> > static inline void unlock_vector_lock(void) {}
> > -static inline void __setup_vector_irq(int cpu) {}
> > #endif
> >
> > #endif /* !ASSEMBLY_ */
> > diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> > index e4e0ddc..fd3cecd 100644
> > --- a/arch/x86/kernel/apic/io_apic.c
> > +++ b/arch/x86/kernel/apic/io_apic.c
> > @@ -1268,6 +1268,15 @@ void __setup_vector_irq(int cpu)
> > /* Mark the inuse vectors */
> > for_each_irq_desc(irq, desc) {
> > cfg = desc->chip_data;
> > +
> > + /*
> > + * If it is a legacy IRQ handled by the legacy PIC, be ready
> > + * to handle it on any CPU, as the PIC interrupts are delivered
> > + * to multiple cpu's on some platforms.
> > + */
> > + if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq))
> > + cpumask_set_cpu(cpu, cfg->domain);
> > +
> > if (!cpumask_test_cpu(cpu, cfg->domain))
> > continue;
> > vector = cfg->vector;
> > diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
> > index ef257fc..afc3b31 100644
> > --- a/arch/x86/kernel/irqinit.c
> > +++ b/arch/x86/kernel/irqinit.c
> > @@ -141,6 +141,26 @@ void __init init_IRQ(void)
> > x86_init.irqs.intr_init();
> > }
> >
> > +#ifndef CONFIG_X86_IO_APIC
> > +/*
> > + * Setup the vector to irq mappings.
> > + */
> > +void __setup_vector_irq(int cpu)
> > +{
> > + int irq;
> > +
> > + /*
> > + * On most of the platforms, legacy PIC delivers the interrupts on the
> > + * boot cpu. But there are certain platforms where PIC interrupts are
> > + * delivered to multiple cpu's. For the new cpu that is coming online,
> > + * setup the static legacy vector to irq mapping.
> > + */
> > + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
> > + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
> > +
> > +}
> > +#endif
> > +
> > static void __init smp_intr_init(void)
> > {
> > #ifdef CONFIG_SMP
> >
>
> yes, less one one function prototype.
>
> Acked-by: Yinghai Lu <yinghai@kernel.org>
Please submit the cleanup bit separately, we try to keep x86/urgent patches as
small as possible.
Thanks,
Ingo
^ permalink raw reply [flat|nested] 10+ messages in thread
* [tip:x86/urgent] x86: Handle legacy PIC interrupts on all the cpu's
2010-03-15 22:33 [patch] x86: handle legacy PIC interrupts on all the cpu's Suresh Siddha
2010-03-15 21:51 ` Yinghai Lu
@ 2010-03-16 6:00 ` tip-bot for Suresh Siddha
1 sibling, 0 replies; 10+ messages in thread
From: tip-bot for Suresh Siddha @ 2010-03-16 6:00 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, yinghai, ebiederm, suresh.b.siddha,
tglx, mingo
Commit-ID: 36e9e1eab777e077f7484d309ff676d0568e27d1
Gitweb: http://git.kernel.org/tip/36e9e1eab777e077f7484d309ff676d0568e27d1
Author: Suresh Siddha <suresh.b.siddha@intel.com>
AuthorDate: Mon, 15 Mar 2010 14:33:06 -0800
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Tue, 16 Mar 2010 06:36:35 +0100
x86: Handle legacy PIC interrupts on all the cpu's
Ingo Molnar reported that with the recent changes of not
statically blocking IRQ0_VECTOR..IRQ15_VECTOR's on all the
cpu's, broke an AMD platform (with Nvidia chipset) boot when
"noapic" boot option is used.
On this platform, legacy PIC interrupts are getting delivered to
all the cpu's instead of just the boot cpu. Thus not
initializing the vector to irq mapping for the legacy irq's
resulted in not handling certain interrupts causing boot hang.
Fix this by initializing the vector to irq mapping on all the
logical cpu's, if the legacy IRQ is handled by the legacy PIC.
Reported-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
[ -v2: io-apic-enabled improvement ]
Acked-by: Yinghai Lu <yinghai@kernel.org>
Cc: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1268692386.3296.43.camel@sbs-t61.sc.intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
arch/x86/include/asm/hw_irq.h | 1 +
arch/x86/kernel/apic/io_apic.c | 8 ++++++++
arch/x86/kernel/irqinit.c | 22 ++++++++++++++++++++++
arch/x86/kernel/smpboot.c | 2 +-
4 files changed, 32 insertions(+), 1 deletions(-)
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index a929c9e..46c0fe0 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -133,6 +133,7 @@ extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
typedef int vector_irq_t[NR_VECTORS];
DECLARE_PER_CPU(vector_irq_t, vector_irq);
+extern void setup_vector_irq(int cpu);
#ifdef CONFIG_X86_IO_APIC
extern void lock_vector_lock(void);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e4e0ddc..463de9a 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1268,6 +1268,14 @@ void __setup_vector_irq(int cpu)
/* Mark the inuse vectors */
for_each_irq_desc(irq, desc) {
cfg = desc->chip_data;
+
+ /*
+ * If it is a legacy IRQ handled by the legacy PIC, this cpu
+ * will be part of the irq_cfg's domain.
+ */
+ if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq))
+ cpumask_set_cpu(cpu, cfg->domain);
+
if (!cpumask_test_cpu(cpu, cfg->domain))
continue;
vector = cfg->vector;
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index ef257fc..f01d390 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -141,6 +141,28 @@ void __init init_IRQ(void)
x86_init.irqs.intr_init();
}
+/*
+ * Setup the vector to irq mappings.
+ */
+void setup_vector_irq(int cpu)
+{
+#ifndef CONFIG_X86_IO_APIC
+ int irq;
+
+ /*
+ * On most of the platforms, legacy PIC delivers the interrupts on the
+ * boot cpu. But there are certain platforms where PIC interrupts are
+ * delivered to multiple cpu's. If the legacy IRQ is handled by the
+ * legacy PIC, for the new cpu that is coming online, setup the static
+ * legacy vector to irq mapping:
+ */
+ for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
+ per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
+#endif
+
+ __setup_vector_irq(cpu);
+}
+
static void __init smp_intr_init(void)
{
#ifdef CONFIG_SMP
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index a02e80c..06d98ae 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -247,7 +247,7 @@ static void __cpuinit smp_callin(void)
/*
* Need to setup vector mappings before we enable interrupts.
*/
- __setup_vector_irq(smp_processor_id());
+ setup_vector_irq(smp_processor_id());
/*
* Get our bogomips.
*
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2010-03-16 7:29 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-15 22:33 [patch] x86: handle legacy PIC interrupts on all the cpu's Suresh Siddha
2010-03-15 21:51 ` Yinghai Lu
2010-03-15 22:56 ` Suresh Siddha
2010-03-15 22:15 ` Yinghai Lu
2010-03-16 5:37 ` Ingo Molnar
2010-03-16 5:57 ` Ingo Molnar
2010-03-16 6:54 ` Suresh Siddha
2010-03-16 6:35 ` Yinghai Lu
2010-03-16 7:29 ` Ingo Molnar
2010-03-16 6:00 ` [tip:x86/urgent] x86: Handle " tip-bot for Suresh Siddha
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox