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 v2 [RFC]
Date: Fri, 9 Sep 2011 16:06:39 +0100	[thread overview]
Message-ID: <4E6A2B7F.6060006@citrix.com> (raw)
In-Reply-To: <4E68C9A9.8090707@citrix.com>

[-- Attachment #1: Type: text/plain, Size: 224 bytes --]

---SNIP---

v2 of the EOI patch.

This provides one function to perform EOI'ing, taking a vector or a pin
(or both).

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


[-- Attachment #2: IO-APIC-eoi.patch --]
[-- Type: text/x-patch, Size: 5238 bytes --]

diff -r 0268e7380953 xen/arch/x86/io_apic.c
--- 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 15:58:59 2011 +0100
@@ -357,7 +357,7 @@ static void __eoi_IO_APIC_irq(unsigned i
         pin = entry->pin;
         if (pin == -1)
             break;
-        io_apic_eoi(entry->apic, vector);
+        __io_apic_eoi(entry->apic, vector, pin);
         if (!entry->next)
             break;
         entry = irq_2_pin + entry->next;
@@ -397,18 +397,7 @@ static void clear_IO_APIC_pin(unsigned i
             entry.trigger = 1;
             __ioapic_write_entry(apic, pin, TRUE, entry);
         }
-        if (mp_ioapics[apic].mpc_apicver >= 0x20)
-            io_apic_eoi(apic, entry.vector);
-        else {
-            /*
-             * Mechanism by which we clear remoteIRR in this case is by
-             * changing the trigger mode to edge and back to level.
-             */
-            entry.trigger = 0;
-            __ioapic_write_entry(apic, pin, TRUE, entry);
-            entry.trigger = 1;
-            __ioapic_write_entry(apic, pin, TRUE, entry);
-        }
+        io_apic_eoi(apic, entry.vector, pin);
     }
 
     /*
@@ -1750,7 +1739,7 @@ static void end_level_ioapic_irq (unsign
     {
         int ioapic;
         for (ioapic = 0; ioapic < nr_ioapics; ioapic++)
-            io_apic_eoi(ioapic, i);
+            io_apic_eoi_vector(ioapic, i);
     }
 
     v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
@@ -2622,3 +2611,86 @@ 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 */
+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 */
+void __io_apic_eoi(unsigned int apic, unsigned int vector, unsigned int pin)
+{
+    ASSERT( spin_is_locked(&ioapic_lock) );
+    ASSERT( !local_irq_is_enabled() );
+
+    /* 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 )
+                if ( __ioapic_read_entry(apic, p, TRUE).vector == vector )
+                {
+                    pin = p;
+                    break;
+                }
+            
+            /* If search fails, nothing to do */
+            if ( pin == -1 )
+                return;
+        }
+
+        /* If vector is unknown, read it from the IO-APIC */
+        if ( vector == -1 )
+            vector = __ioapic_read_entry(apic, pin, TRUE).vector;
+
+        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);
+        }
+    }
+}
diff -r 0268e7380953 xen/include/asm-x86/io_apic.h
--- a/xen/include/asm-x86/io_apic.h	Mon Sep 05 15:10:28 2011 +0100
+++ b/xen/include/asm-x86/io_apic.h	Fri Sep 09 15:58:59 2011 +0100
@@ -157,10 +157,13 @@ static inline void io_apic_write(unsigne
 	__io_apic_write(apic, reg, value);
 }
 
-static inline void io_apic_eoi(unsigned int apic, unsigned int vector)
-{
-	*(IO_APIC_BASE(apic)+16) = vector;
-}
+#define ioapic_has_eoi_reg(apic) (mp_ioapics[(apic)].mpc_apicver >= 0x20)
+
+void __io_apic_eoi(unsigned int apic, unsigned int vector, unsigned int pin);
+void io_apic_eoi(unsigned int apic, unsigned int vector, unsigned int pin);
+
+#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))
 
 /*
  * Re-write a value: to be used for read-modify-write

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

  reply	other threads:[~2011-09-09 15:06 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             ` Andrew Cooper [this message]
2011-09-09 15:39               ` Re: 4.0/4.1 requests - IO-APIC EOI v2 [RFC] 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
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=4E6A2B7F.6060006@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.