WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] x86: Free MSI vector when a pirq is unmap

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: Free MSI vector when a pirq is unmapped.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 08 Oct 2008 18:50:21 -0700
Delivery-date: Wed, 08 Oct 2008 18:51:26 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1223463099 -3600
# Node ID 51a05fb4c6014059058de48b83a9431e7474a456
# Parent  ed398097c03e16dacb1f3af19fa8faddf2deae1f
x86: Free MSI vector when a pirq is unmapped.

Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/domain.c         |    1 
 xen/arch/x86/i8259.c          |    4 +++
 xen/arch/x86/io_apic.c        |   49 ++++++++++++++++++++++++------------------
 xen/arch/x86/irq.c            |   18 +++++++++++++++
 xen/arch/x86/physdev.c        |    7 +++---
 xen/include/asm-x86/io_apic.h |    1 
 xen/include/asm-x86/irq.h     |    5 +++-
 7 files changed, 60 insertions(+), 25 deletions(-)

diff -r ed398097c03e -r 51a05fb4c601 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Oct 08 10:48:48 2008 +0100
+++ b/xen/arch/x86/domain.c     Wed Oct 08 11:51:39 2008 +0100
@@ -459,6 +459,7 @@ void arch_domain_destroy(struct domain *
         hvm_domain_destroy(d);
 
     pci_release_devices(d);
+    free_domain_pirqs(d);
     if ( !is_idle_domain(d) )
         iommu_domain_destroy(d);
 
diff -r ed398097c03e -r 51a05fb4c601 xen/arch/x86/i8259.c
--- a/xen/arch/x86/i8259.c      Wed Oct 08 10:48:48 2008 +0100
+++ b/xen/arch/x86/i8259.c      Wed Oct 08 11:51:39 2008 +0100
@@ -408,6 +408,10 @@ void __init init_IRQ(void)
         irq_desc[LEGACY_VECTOR(i)].handler = &i8259A_irq_type;
     }
 
+    /* Never allocate the hypercall vector or Linux/BSD fast-trap vector. */
+    vector_irq[HYPERCALL_VECTOR] = NEVER_ASSIGN;
+    vector_irq[0x80] = NEVER_ASSIGN;
+
     apic_intr_init();
 
     /* Set the clock to HZ Hz */
diff -r ed398097c03e -r 51a05fb4c601 xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Wed Oct 08 10:48:48 2008 +0100
+++ b/xen/arch/x86/io_apic.c    Wed Oct 08 11:51:39 2008 +0100
@@ -87,7 +87,8 @@ static struct irq_pin_list {
 } irq_2_pin[PIN_MAP_SIZE];
 static int irq_2_pin_free_entry = NR_IRQS;
 
-int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
+int vector_irq[NR_VECTORS] __read_mostly = {
+    [0 ... NR_VECTORS - 1] = FREE_TO_ASSIGN};
 
 /*
  * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
@@ -666,40 +667,46 @@ static inline int IO_APIC_irq_trigger(in
 /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
 u8 irq_vector[NR_IRQ_VECTORS] __read_mostly;
 
+int free_irq_vector(int vector)
+{
+    int irq;
+
+    BUG_ON((vector > LAST_DYNAMIC_VECTOR) || (vector < FIRST_DYNAMIC_VECTOR));
+
+    spin_lock(&vector_lock);
+    if ((irq = vector_irq[vector]) == AUTO_ASSIGN)
+        vector_irq[vector] = FREE_TO_ASSIGN;
+    spin_unlock(&vector_lock);
+
+    return (irq == AUTO_ASSIGN) ? 0 : -EINVAL;
+}
+
 int assign_irq_vector(int irq)
 {
-    static unsigned current_vector = FIRST_DYNAMIC_VECTOR, offset = 0;
+    static unsigned current_vector = FIRST_DYNAMIC_VECTOR;
     unsigned vector;
 
     BUG_ON(irq >= NR_IRQ_VECTORS);
+
     spin_lock(&vector_lock);
 
-    if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
+    if ((irq != AUTO_ASSIGN) && (IO_APIC_VECTOR(irq) > 0)) {
         spin_unlock(&vector_lock);
         return IO_APIC_VECTOR(irq);
     }
 
-next:
-    current_vector += 8;
-
-    /* Skip the hypercall vector. */
-    if (current_vector == HYPERCALL_VECTOR)
-        goto next;
-
-    /* Skip the Linux/BSD fast-trap vector. */
-    if (current_vector == 0x80)
-        goto next;
-
-    if (current_vector > LAST_DYNAMIC_VECTOR) {
-        offset++;
-        if (!(offset%8)) {
+    vector = current_vector;
+    while (vector_irq[vector] != FREE_TO_ASSIGN) {
+        if (++vector > LAST_DYNAMIC_VECTOR)
+            vector = FIRST_DYNAMIC_VECTOR;
+
+        if (vector == current_vector) {
             spin_unlock(&vector_lock);
             return -ENOSPC;
         }
-        current_vector = FIRST_DYNAMIC_VECTOR + offset;
-    }
-
-    vector = current_vector;
+    }
+
+    current_vector = vector;
     vector_irq[vector] = irq;
     if (irq != AUTO_ASSIGN)
         IO_APIC_VECTOR(irq) = vector;
diff -r ed398097c03e -r 51a05fb4c601 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Wed Oct 08 10:48:48 2008 +0100
+++ b/xen/arch/x86/irq.c        Wed Oct 08 11:51:39 2008 +0100
@@ -861,7 +861,10 @@ int unmap_domain_pirq(struct domain *d, 
         pci_disable_msi(vector);
 
     if ( desc->handler == &pci_msi_type )
+    {
         desc->handler = &no_irq_type;
+        free_irq_vector(vector);
+    }
 
     if ( !forced_unbind )
     {
@@ -883,6 +886,21 @@ int unmap_domain_pirq(struct domain *d, 
 
  done:
     return ret;
+}
+
+void free_domain_pirqs(struct domain *d)
+{
+    int i;
+
+    ASSERT(d->is_dying == DOMDYING_dying);
+
+    spin_lock(&d->evtchn_lock);
+
+    for ( i = 0; i < NR_PIRQS; i++ )
+        if ( d->arch.pirq_vector[i] > 0 )
+            unmap_domain_pirq(d, i);
+
+    spin_unlock(&d->evtchn_lock);
 }
 
 extern void dump_ioapic_irq_info(void);
diff -r ed398097c03e -r 51a05fb4c601 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Wed Oct 08 10:48:48 2008 +0100
+++ b/xen/arch/x86/physdev.c    Wed Oct 08 11:51:39 2008 +0100
@@ -79,7 +79,7 @@ static int physdev_map_pirq(struct physd
             if ( vector < 0 || vector >= NR_VECTORS )
             {
                 dprintk(XENLOG_G_ERR, "dom%d: map irq with wrong vector %d\n",
-                        d->domain_id, map->index);
+                        d->domain_id, vector);
                 ret = -EINVAL;
                 goto free_domain;
             }
@@ -140,13 +140,14 @@ static int physdev_map_pirq(struct physd
             pirq = map->pirq;
     }
 
-
     ret = map_domain_pirq(d, pirq, vector, map->type, map_data);
-    if ( !ret )
+    if ( ret == 0 )
         map->pirq = pirq;
 
 done:
     spin_unlock(&d->evtchn_lock);
+    if ( (ret != 0) && (map->type == MAP_PIRQ_TYPE_MSI) && (map->index == -1) )
+        free_irq_vector(vector);
 free_domain:
     rcu_unlock_domain(d);
     return ret;
diff -r ed398097c03e -r 51a05fb4c601 xen/include/asm-x86/io_apic.h
--- a/xen/include/asm-x86/io_apic.h     Wed Oct 08 10:48:48 2008 +0100
+++ b/xen/include/asm-x86/io_apic.h     Wed Oct 08 11:51:39 2008 +0100
@@ -190,5 +190,6 @@ static inline int ioapic_resume(void) {r
 #endif
 
 extern int assign_irq_vector(int irq);
+extern int free_irq_vector(int vector);
 
 #endif
diff -r ed398097c03e -r 51a05fb4c601 xen/include/asm-x86/irq.h
--- a/xen/include/asm-x86/irq.h Wed Oct 08 10:48:48 2008 +0100
+++ b/xen/include/asm-x86/irq.h Wed Oct 08 11:51:39 2008 +0100
@@ -19,7 +19,9 @@
 
 extern int vector_irq[NR_VECTORS];
 extern u8 irq_vector[NR_IRQ_VECTORS];
-#define AUTO_ASSIGN             -1
+#define AUTO_ASSIGN    -1
+#define NEVER_ASSIGN   -2
+#define FREE_TO_ASSIGN -3
 
 #define platform_legacy_irq(irq)       ((irq) < 16)
 
@@ -56,6 +58,7 @@ int map_domain_pirq(struct domain *d, in
                            void *data);
 int unmap_domain_pirq(struct domain *d, int pirq);
 int get_free_pirq(struct domain *d, int type, int index);
+void free_domain_pirqs(struct domain *d);
 
 #define domain_irq_to_vector(d, irq) ((d)->arch.pirq_vector[(irq)])
 #define domain_vector_to_irq(d, vec) ((d)->arch.vector_pirq[(vec)])

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86: Free MSI vector when a pirq is unmapped., Xen patchbot-unstable <=