All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir.xen@gmail.com>,
	"xen-devel@lists.xensource.com" <xen-devel@lists.xensource.com>
Subject: Re: Re: 4.0/4.1 requests - IO-APIC EOI v4 [RFC]
Date: Mon, 12 Sep 2011 11:15:10 +0100	[thread overview]
Message-ID: <4E6DDBAE.6060104@citrix.com> (raw)
In-Reply-To: <4E6DC7D80200007800055AB1@nat28.tlf.novell.com>

On 12/09/11 07:50, Jan Beulich wrote:
>>>> On 09.09.11 at 18:47, Andrew Cooper <andrew.cooper3@citrix.com> wrote:
>> On 09/09/11 17:22, Andrew Cooper wrote:
>>> ---SNIP---
>>>
>>> Version 3.  Applied Jan's suggestions, and extended some of the comments.
>>>
>> V4 - get the BUG_ON logic correct (oops).
>>
>> I have now done a few reboot tests and a kexec test with this patch.
>>
>> Are there any other tests you would suggest, or shall I formally submit
>> the patch for unstable and backporting?
>
> Looks technically good now, but there are a few cosmetic comments still:
>
>> --- a/xen/arch/x86/io_apic.c	Mon Sep 05 15:10:28 2011 +0100
>> +++ b/xen/arch/x86/io_apic.c	Fri Sep 09 17:20:49 2011 +0100
>> @@ -68,6 +68,16 @@ int __read_mostly nr_ioapics;
>> #define MAX_PLUS_SHARED_IRQS nr_irqs_gsi
>> #define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + nr_irqs_gsi)
>>
>> +
>> +#define ioapic_has_eoi_reg(apic) (mp_ioapics[(apic)].mpc_apicver >= 0x20)
>> +
>> +static void __io_apic_eoi(unsigned int apic, unsigned int vector, unsigned int pin);
>> +static void io_apic_eoi(unsigned int apic, unsigned int vector, unsigned int pin);
> No need to declare these here if you move the definitions up before
> the first use (would fit well after ioapic_write_entry()).

Ok

>> +
>> +#define io_apic_eoi_vector(apic, vector) io_apic_eoi((apic), (vector), -1)
>> +#define io_apic_eoi_pin(apic, pin) io_apic_eoi((apic), -1, (pin))
>> +
>> +
>> /*
>>  * This is performance-critical, we want to do it O(1)
>>  *
>> ...
>> @@ -2622,3 +2621,124 @@ void __init init_ioapic_mappings(void)
>>     printk(XENLOG_INFO "IRQ limits: %u GSI, %u MSI/MSI-X\n",
>>            nr_irqs_gsi, nr_irqs - nr_irqs_gsi);
>> }
>> +
>> +/* EOI an IO-APIC entry.  One of vector or pin may be -1, indicating that
>> + * it should be worked out using the other.  This function disables interrupts
>> + * and takes the ioapic_lock */
>> +static void io_apic_eoi(unsigned int apic, unsigned int vector, unsigned int pin)
>> +{
>> +    unsigned int flags;
>> +    spin_lock_irqsave(&ioapic_lock, flags);
>> +    __io_apic_eoi(apic, vector, pin);
>> +    spin_unlock_irqrestore(&ioapic_lock, flags);
>> +}
>> +
>> +/* EOI an IO-APIC entry.  One of vector or pin may be -1, indicating that
>> + * it should be worked out using the other.  This function expect that the
>> + * ioapic_lock is taken, and interrupts are disabled (or there is a good reason
>> + * not to), and that if both pin and vector are passed, that they refer to the
>> + * same redirection entry in the IO-APIC. */
>> +static void __io_apic_eoi(unsigned int apic, unsigned int vector, unsigned int pin)
>> +{
>> +    /* Ensure some useful information is passed in */
>> +    BUG_ON( !(vector == -1 && pin != -1) );
>> +    
>> +    /* Prefer the use of the EOI register if available */
>> +    if ( ioapic_has_eoi_reg(apic) )
>> +    {
>> +        /* If vector is unknown, read it from the IO-APIC */
>> +        if ( vector == -1 )
>> +            vector = __ioapic_read_entry(apic, pin, TRUE).vector;
>> +
>> +        *(IO_APIC_BASE(apic)+16) = vector;
>> +    }
>> +    else
>> +    {
>> +        /* Else fake an EOI by switching to edge triggered mode
>> +         * and back */
>> +        struct IO_APIC_route_entry entry;
>> +        bool_t need_to_unmask = 0;
>> +
>> +        /* If pin is unknown, search for it */
>> +        if ( pin == -1 )
>> +        {
>> +            unsigned int p;
>> +            for ( p = 0; p < nr_ioapic_registers[apic]; ++p )
>> +            {
>> +                entry = __ioapic_read_entry(apic, p, TRUE);
>> +                if ( entry.vector == vector )
>> +                {
>> +                    pin = p;
>> +                    /* break; */
>> +
>> +                    /* Here should be a break out of the loop, but at the 
> ... moment ...
>
>> +                     * Xen code doesn't actually prevent multiple IO-APIC
>> +                     * entries being assigned the same vector, so EOI all
>> +                     * pins which have the correct vector.
>> +                     *
>> +                     * Remove the following code when the above assertion
>> +                     * is fulfilled. */
>> +
> Why don't you just call __io_apic_eoi() recursively here?
>
> Jan

If I call the function recursively, it will loop forever.  Anyway, the
need to clear multiple pins is only temorary until George finishes his
per-device AMD interrupt remap patch which will enforce vector
uniqueness in each IO-APIC.  My expectation is that this issue will be
fixed in the next few weeks.

>> +                    if ( ! entry.mask )
>> +                    {
>> +                        /* If entry is not currently masked, mask it and make
>> +                         * a note to unmask it later */
>> +                        entry.mask = 1;
>> +                        __ioapic_write_entry(apic, pin, TRUE, entry);
>> +                        need_to_unmask = 1;
>> +                    }
>> +
>> +                    /* Flip the trigger mode to edge and back */
>> +                    entry.trigger = 0;
>> +                    __ioapic_write_entry(apic, pin, TRUE, entry);
>> +                    entry.trigger = 1;
>> +                    __ioapic_write_entry(apic, pin, TRUE, entry);
>> +
>> +                    if ( need_to_unmask )
>> +                    {
>> +                        /* Unmask if neccesary */
>> +                        entry.mask = 0;
>> +                        __ioapic_write_entry(apic, pin, TRUE, entry);
>> +                    }
>> +
>> +                }
>> +            }
>> +            
>> +            /* If search fails, nothing to do */
>> +
>> +            /* if ( pin == -1 ) */
>> +
>> +            /* Because the loop wasn't broken out of (see comment above),
>> +             * all relevant pins have been EOI, so we can always return.
>> +             * 
>> +             * Re-instate the if statement above when the Xen logic has been
>> +             * fixed.*/
>> +
>> +            return;
>> +        }
>> +
>> +        entry = __ioapic_read_entry(apic, pin, TRUE);
>> +
>> +        if ( ! entry.mask )
>> +        {
>> +            /* If entry is not currently masked, mask it and make
>> +             * a note to unmask it later */
>> +            entry.mask = 1;
>> +            __ioapic_write_entry(apic, pin, TRUE, entry);
>> +            need_to_unmask = 1;
>> +        }
>> +
>> +        /* Flip the trigger mode to edge and back */
>> +        entry.trigger = 0;
>> +        __ioapic_write_entry(apic, pin, TRUE, entry);
>> +        entry.trigger = 1;
>> +        __ioapic_write_entry(apic, pin, TRUE, entry);
>> +
>> +        if ( need_to_unmask )
>> +        {
>> +            /* Unmask if neccesary */
>> +            entry.mask = 0;
>> +            __ioapic_write_entry(apic, pin, TRUE, entry);
>> +        }
>> +    }
>> +}
>> ...

I will formally submit the patch for inclusion now.

-- 
Andrew Cooper - Dom0 Kernel Engineer, Citrix XenServer
T: +44 (0)1223 225 900, http://www.citrix.com

  reply	other threads:[~2011-09-12 10:15 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-08  9:19 4.0/4.1 requests Jan Beulich
2011-09-08 10:12 ` Jan Beulich
2011-09-08 11:29   ` Keir Fraser
2011-09-08 10:17 ` Keir Fraser
2011-09-08 10:48   ` Andrew Cooper
2011-09-08 11:11     ` Keir Fraser
2011-09-08 11:44     ` Jan Beulich
2011-09-08 13:18       ` 4.0/4.1 requests - IO-APIC EOI [RFC] Andrew Cooper
2011-09-08 13:40         ` Jan Beulich
2011-09-08 13:56           ` Andrew Cooper
2011-09-09 15:06             ` Re: 4.0/4.1 requests - IO-APIC EOI v2 [RFC] Andrew Cooper
2011-09-09 15:39               ` Jan Beulich
2011-09-09 15:55                 ` Andrew Cooper
2011-09-09 16:03                   ` Jan Beulich
2011-09-09 16:22                     ` Re: 4.0/4.1 requests - IO-APIC EOI v3 [RFC] Andrew Cooper
2011-09-09 16:47                       ` Re: 4.0/4.1 requests - IO-APIC EOI v4 [RFC] Andrew Cooper
2011-09-09 16:50                         ` Andrew Cooper
2011-09-12  6:50                         ` Jan Beulich
2011-09-12 10:15                           ` Andrew Cooper [this message]
2011-09-12 10:23                             ` Jan Beulich
2011-09-12 11:30                               ` Keir Fraser

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=4E6DDBAE.6060104@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=JBeulich@suse.com \
    --cc=keir.xen@gmail.com \
    --cc=xen-devel@lists.xensource.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.