[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] Re: 4.0/4.1 requests - IO-APIC EOI v4 [RFC]



>>> On 09.09.11 at 18:47, Andrew Cooper <andrew.cooper3@xxxxxxxxxx> 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()).

>+
>+#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 ( ! 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);
>+        }
>+    }
>+}
>...

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.