From: ebiederm@xmission.com (Eric W. Biederman)
To: "Yinghai Lu" <yinghai.lu@amd.com>
Cc: "Tobias Diedrich" <ranma+kernel@tdiedrich.de>,
"Linus Torvalds" <torvalds@osdl.org>,
"Linux Kernel Mailing List" <linux-kernel@vger.kernel.org>,
"Andi Kleen" <ak@suse.de>, "Andrew Morton" <akpm@osdl.org>
Subject: Re: IO-APIC + timer doesn't work
Date: Thu, 21 Dec 2006 13:46:50 -0700 [thread overview]
Message-ID: <m164c5nfid.fsf@ebiederm.dsl.xmission.com> (raw)
In-Reply-To: <86802c440612192250l50805d40h71baa7ce6f99a3e5@mail.gmail.com> (Yinghai Lu's message of "Tue, 19 Dec 2006 22:50:33 -0800")
"Yinghai Lu" <yinghai.lu@amd.com> writes:
> On 12/19/06, Eric W. Biederman <ebiederm@xmission.com> wrote:
>> So the pin2 case should be tested right after the pin1 case as we do
>> currently. On most new boards that will be a complete noop.
>>
>> But it is better than our current blind guess at using ExtINT mode.
>>
>> I figure after we try what the BIOS has told us about and that
>> has failed we should first try the common irq 0 apic mappings,
>> and then try the common ExtINT mappings.
>
> Please check if this one is ok.
>
> [PATCH] x86_64: check_timer with io apic setup before try_apic_pin
>
> add io apic setup before try_apic_pin
>
> cc: Andi Kleen <ak@suse.de>
> cc: Eric W. Biederman <ebiederm@xmission.com>
> Signed-off-by: Yinghai Lu <yinghai.lu@amd.com>
>
> diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
> index 2a1dcd5..6d09fc0 100644
> --- a/arch/x86_64/kernel/io_apic.c
> +++ b/arch/x86_64/kernel/io_apic.c
> @@ -273,10 +273,17 @@ static void add_pin_to_irq(unsigned int irq, int apic, int
> pin)
> struct irq_pin_list *entry = irq_2_pin + irq;
>
> BUG_ON(irq >= NR_IRQS);
> - while (entry->next)
> + while (entry->next) {
> + if (entry->apic == apic && entry->pin == pin)
> + return;
> + if (entry->pin == -1)
> + break;
> entry = irq_2_pin + entry->next;
> + }
>
> if (entry->pin != -1) {
> + if (entry->apic == apic && entry->pin == pin)
> + return;
> entry->next = first_free_entry;
> entry = irq_2_pin + entry->next;
> if (++first_free_entry >= PIN_MAP_SIZE)
This change to add_pin_to_irq looks dubious.
We especially shouldn't hit a pin == -1 while next is still valid.
The problem is that the code that reads this at irq time does not
skip entries with entry->pin == -1.
Fixing the infrastructure should probably be a separate patch
so we don't get too many concepts confused in here.
> @@ -286,6 +293,24 @@ static void add_pin_to_irq(unsigned int irq, int apic, int
> pin)
> entry->pin = pin;
> }
>
> +static void remove_pin_to_irq(unsigned int irq, int apic, int pin)
> +{
> + struct irq_pin_list *entry = irq_2_pin + irq;
> +
> + BUG_ON(irq >= NR_IRQS);
> +
> + while (entry) {
> + if (entry->apic == apic && entry->pin == pin) {
> + entry->apic = -1;
> + entry->pin = -1;
> + break;
> + }
> + if (entry->next)
> + entry = irq_2_pin + entry->next;
> + }
> +
> +}
> +
This change to remove_pin_to_irq is simply wrong.
> +static int add_irq_entry(int type, int irqflag, int bus, int irq, int apic, int
> pin)
> +{
> + struct mpc_config_intsrc intsrc;
> + int idx;
> +
> + intsrc.mpc_type = MP_INTSRC;
> + intsrc.mpc_irqflag = irqflag; /* conforming */
> + intsrc.mpc_srcbus = bus;
> + intsrc.mpc_dstapic = (apic != -1) ? mp_ioapics[apic].mpc_apicid: MP_APIC_ALL;
> +
> + intsrc.mpc_irqtype = type;
> +
> + intsrc.mpc_srcbusirq = irq;
> + intsrc.mpc_dstirq = pin;
> +
> + mp_irqs [mp_irq_entries] = intsrc;
> + Dprintk("Int: type %d, pol %d, trig %d, bus %d,"
> + " IRQ %02x, APIC ID %x, APIC INT %02x\n",
> + intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3,
> + (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus,
> + intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq);
> + idx = mp_irq_entries;
> + if (++mp_irq_entries >= MAX_IRQ_SOURCES)
> + panic("Max # of irq sources exceeded!!\n");
> + return idx;
This is fairly sane but probably belongs in mptable.c as a helper.
> /*
> * Find the pin to which IRQ[irq] (ISA) is connected
> */
> @@ -1570,6 +1658,22 @@ static inline void unlock_ExtINT_logic(void)
> * fanatically on his truly buggy board.
> */
>
> +static void set_try_apic_pin(int apic, int pin, int type)
> +{
> + int idx;
> + int irq = 0;
> + int bus = 0; /* MP_ISA_BUS */
> + int irqflag = 5; /* MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH */
> +
> + idx = find_irq_entry(apic,pin,type);
> +
> + if (idx == -1)
> + idx = add_irq_entry(type, irqflag, bus, irq, apic, pin);
> +
> + add_pin_to_irq(irq, apic, pin);
> + setup_IO_APIC_irq(apic, pin, idx, irq);
> +}
> +
> static int try_apic_pin(int apic, int pin, char *msg)
> {
> apic_printk(APIC_VERBOSE, KERN_INFO
> @@ -1588,7 +1692,7 @@ static int try_apic_pin(int apic, int pin, char *msg)
> }
> return 1;
> }
> - clear_IO_APIC_pin(apic, pin);
> +
> apic_printk(APIC_QUIET, KERN_ERR " .. failed\n");
> return 0;
> }
> @@ -1599,12 +1703,13 @@ static void check_timer(void)
> int apic1, pin1, apic2, pin2;
> int vector;
> cpumask_t mask;
> + int i;
>
> /*
> * get/set the timer IRQ vector:
> */
> - disable_8259A_irq(0);
> vector = assign_irq_vector(0, TARGET_CPUS, &mask);
> + disable_8259A_irq(0);
Moving disable_8259A_irq(0) appears to be useless code motion.
> /*
> * Subtle, code in do_timer_interrupt() expects an AEOI
> @@ -1621,33 +1726,51 @@ static void check_timer(void)
> pin2 = ioapic_i8259.pin;
> apic2 = ioapic_i8259.apic;
>
> - /* Do this first, otherwise we get double interrupts on ATI boards */
> - if ((pin1 != -1) && try_apic_pin(apic1, pin1,"with 8259 IRQ0 disabled"))
> - return;
> + apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d
> apic2=%d pin2=%d\n",
> + vector, apic1, pin1, apic2, pin2);
>
> - /* Now try again with IRQ0 8259A enabled.
> - Assumes timer is on IO-APIC 0 ?!? */
> - enable_8259A_irq(0);
> - unmask_IO_APIC_irq(0);
> - if (try_apic_pin(apic1, pin1, "with 8259 IRQ0 enabled"))
> - return;
> - disable_8259A_irq(0);
> + if (pin1 != -1) {
> + /* Do this first, otherwise we get double interrupts on ATI boards */
> + /* set_try_apic_pin will call disable_8259A_irq */
> + set_try_apic_pin(apic1, pin1, mp_INT);
> + unmask_IO_APIC_irq(0);
> + if (try_apic_pin(apic1, pin1,"with 8259 IRQ0 disabled"))
> + return;
>
> - /* Always try pin0 and pin2 on APIC 0 to handle buggy timer overrides
> - on Nvidia boards */
> - if (!(apic1 == 0 && pin1 == 0) &&
> - try_apic_pin(0, 0, "fallback with 8259 IRQ0 disabled"))
> - return;
> - if (!(apic1 == 0 && pin1 == 2) &&
> - try_apic_pin(0, 2, "fallback with 8259 IRQ0 disabled"))
> - return;
> + /* Now try again with IRQ0 8259A enabled.
> + Assumes timer is on IO-APIC 0 ?!? */
> + enable_8259A_irq(0);
> + if (try_apic_pin(apic1, pin1, "with 8259 IRQ0 enabled"))
> + return;
> + disable_8259A_irq(0);
I am still trying to understand this enable_8259A_irq(0) case.
As far as I can tell this is a very backwards way of enabling
an ExtINT, as such it shouldn't be used until later.
YH do you have any insight why on some Nvidia chipsets we apic 0 pin 2 doesn't
work for the timer interrupt. I thought that was what we were using in LinuxBIOS
for the mptable.
Eric
next prev parent reply other threads:[~2006-12-21 20:47 UTC|newest]
Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-14 2:06 Linux 2.6.20-rc1 Linus Torvalds
2006-12-14 2:46 ` Gene Heskett
2006-12-14 3:32 ` Linus Torvalds
2006-12-14 5:36 ` Gene Heskett
2006-12-14 17:48 ` ieee1394 in 2.6.20-rc1 (was Re: Linux 2.6.20-rc1) Stefan Richter
2006-12-14 19:08 ` Stefan Richter
2006-12-15 3:17 ` Gene Heskett
2006-12-17 18:11 ` Gene Heskett
2006-12-17 18:31 ` Stefan Richter
2006-12-17 19:04 ` Gene Heskett
2006-12-17 20:21 ` Stefan Richter
2006-12-17 23:34 ` Gene Heskett
2006-12-18 1:05 ` Stefan Richter
2006-12-18 4:29 ` Gene Heskett
2006-12-18 15:45 ` Stefan Richter
2006-12-18 15:54 ` Gene Heskett
2006-12-14 13:59 ` Linux 2.6.20-rc1 Alessandro Suardi
2006-12-14 14:18 ` Steve WIse
2006-12-14 15:48 ` Alan
2006-12-14 19:30 ` Alistair John Strachan
2006-12-14 19:57 ` Linus Torvalds
2006-12-14 20:05 ` Jeff Garzik
2006-12-14 20:26 ` [PATCH] support HDIO_GET_IDENTITY in libata Erik Andersen
2006-12-14 20:31 ` Jeff Garzik
2006-12-14 20:40 ` Erik Andersen
2006-12-16 16:34 ` Jeff Garzik
2006-12-15 18:45 ` Alexey Dobriyan
2006-12-16 16:34 ` Jeff Garzik
2006-12-14 20:16 ` Linux 2.6.20-rc1 Alistair John Strachan
2006-12-14 20:28 ` Jens Axboe
2006-12-14 20:33 ` Jeff Garzik
2006-12-14 20:36 ` Jens Axboe
2006-12-14 20:48 ` Jens Axboe
2006-12-14 21:13 ` Alistair John Strachan
2006-12-14 21:20 ` Jens Axboe
2006-12-15 0:48 ` Alistair John Strachan
2006-12-15 1:41 ` Alistair John Strachan
2006-12-16 21:36 ` Linus Torvalds
2006-12-16 22:28 ` Alistair John Strachan
2006-12-16 22:31 ` Jeff Garzik
2006-12-16 23:00 ` Alistair John Strachan
2006-12-18 18:32 ` Jens Axboe
2006-12-18 18:41 ` Jens Axboe
2006-12-14 21:33 ` Jeff Garzik
2006-12-14 21:44 ` Alistair John Strachan
2006-12-14 21:50 ` Jeff Garzik
2006-12-14 22:33 ` Alistair John Strachan
2006-12-19 12:41 ` Jens Axboe
2006-12-19 14:32 ` Robert Hancock
2006-12-19 14:38 ` Jens Axboe
2006-12-19 14:50 ` Jens Axboe
2006-12-19 17:49 ` Linus Torvalds
2006-12-14 21:53 ` Jeff Garzik
2006-12-14 20:32 ` Nicolas Mailhot
2006-12-14 23:22 ` Jeff Garzik
2006-12-14 23:33 ` Nicolas Mailhot
2006-12-15 16:50 ` Bill Davidsen
2006-12-15 17:28 ` Alan
2006-12-18 21:57 ` Bill Davidsen
[not found] ` <20061216174536.GA2753@melchior.yamamaya.is-a-geek.org>
2006-12-16 18:06 ` IO-APIC + timer doesn't work (was: Linux 2.6.20-rc1) Linus Torvalds
[not found] ` <20061216225338.GA2616@melchior.yamamaya.is-a-geek.org>
[not found] ` <20061216230605.GA2789@melchior.yamamaya.is-a-geek.org>
2006-12-16 23:36 ` Linus Torvalds
[not found] ` <20061216235513.GA2424@melchior.yamamaya.is-a-geek.org>
2006-12-17 0:04 ` IO-APIC + timer doesn't work Linus Torvalds
2006-12-17 5:16 ` Eric W. Biederman
2006-12-17 5:22 ` Eric W. Biederman
2006-12-18 6:16 ` Len Brown
2006-12-17 13:10 ` Tobias Diedrich
2006-12-17 17:26 ` Linus Torvalds
2006-12-17 14:57 ` IO-APIC + timer doesn't work (was: Linux 2.6.20-rc1) Tobias Diedrich
2006-12-18 13:14 ` Eric W. Biederman
2006-12-18 15:23 ` Tobias Diedrich
2006-12-18 15:34 ` Tobias Diedrich
2006-12-18 15:43 ` IO-APIC + timer doesn't work Eric W. Biederman
2006-12-19 8:00 ` Yinghai Lu
2006-12-19 11:27 ` Eric W. Biederman
2006-12-20 6:50 ` Yinghai Lu
2006-12-21 19:15 ` Tobias Diedrich
2006-12-21 20:46 ` Eric W. Biederman [this message]
2006-12-31 8:29 ` Yinghai Lu
2006-12-21 21:24 Lu, Yinghai
2006-12-21 21:40 ` Eric W. Biederman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m164c5nfid.fsf@ebiederm.dsl.xmission.com \
--to=ebiederm@xmission.com \
--cc=ak@suse.de \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ranma+kernel@tdiedrich.de \
--cc=torvalds@osdl.org \
--cc=yinghai.lu@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome