mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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

  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