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

[Xen-devel] [PATCH][RFC] fix some spinlock issues in vmsi



Hi,

This patch fixes some spinlock issues related to changeset:
 19246:9bc5799566be "passthrough MSI-X mask bit acceleration"
 19263:9c5b4efc934d "hvm: passthrough MSI-X: fix ia64 link and MSI-X clean up"

Without this patch, I got:
(XEN) Assertion '_spin_is_locked(&pcidevs_lock)' failed at vmsi.c:389
or
(XEN) Xen BUG at spinlock.c:25


I'm not sure this fix is right. Please review it.

- d->arch.hvm_domain.msixtbl_list_lock is redundant.
  irq_desc->lock covers it, thus remove the spinlock.

- ASSERT(spin_is_locked(&pcidevs_lock)) is not needed.
  At first, I intended to add the enclosure of pcidevs_lock.
  But this assertion seems pointless. pcidevs_lock is
  for alldevs_list and msixtbl_pt_xxx functions never refer it.

- In "debug=y" environment, xmalloc must not be called from both
  irq_enable and irq_disable state. Otherwise, 
  the assertion failure occurs in check_lock().
  So, in msixtbl_pt_register, xmalloc is called beforehand.
  I thinks this is ugly, though.


Thanks,
Kouya

Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>

diff -r cff29d694a89 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Thu Mar 05 17:50:05 2009 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Fri Mar 06 11:01:43 2009 +0900
@@ -309,7 +309,6 @@ int hvm_domain_initialise(struct domain 
     spin_lock_init(&d->arch.hvm_domain.uc_lock);
 
     INIT_LIST_HEAD(&d->arch.hvm_domain.msixtbl_list);
-    spin_lock_init(&d->arch.hvm_domain.msixtbl_list_lock);
 
     hvm_init_guest_time(d);
 
diff -r cff29d694a89 xen/arch/x86/hvm/vmsi.c
--- a/xen/arch/x86/hvm/vmsi.c   Thu Mar 05 17:50:05 2009 +0000
+++ b/xen/arch/x86/hvm/vmsi.c   Fri Mar 06 11:01:43 2009 +0900
@@ -336,16 +336,12 @@ struct hvm_mmio_handler msixtbl_mmio_han
     .write_handler = msixtbl_write
 };
 
-static struct msixtbl_entry *add_msixtbl_entry(struct domain *d,
-                                               struct pci_dev *pdev,
-                                               uint64_t gtable)
+static void add_msixtbl_entry(struct domain *d,
+                             struct pci_dev *pdev,
+                             uint64_t gtable,
+                             struct msixtbl_entry *entry)
 {
-    struct msixtbl_entry *entry;
     u32 len;
-
-    entry = xmalloc(struct msixtbl_entry);
-    if ( !entry )
-        return NULL;
 
     memset(entry, 0, sizeof(struct msixtbl_entry));
         
@@ -359,8 +355,6 @@ static struct msixtbl_entry *add_msixtbl
     entry->gtable = (unsigned long) gtable;
 
     list_add_rcu(&entry->list, &d->arch.hvm_domain.msixtbl_list);
-
-    return entry;
 }
 
 static void free_msixtbl_entry(struct rcu_head *rcu)
@@ -383,12 +377,17 @@ int msixtbl_pt_register(struct domain *d
     irq_desc_t *irq_desc;
     struct msi_desc *msi_desc;
     struct pci_dev *pdev;
-    struct msixtbl_entry *entry;
+    struct msixtbl_entry *entry, *new_entry;
     int r = -EINVAL;
 
-    ASSERT(spin_is_locked(&pcidevs_lock));
+    /* XXX: beforehand allocation is needed since check_lock() fails. */
+    new_entry = xmalloc(struct msixtbl_entry);
+    if ( !new_entry )
+        return r;
 
     irq_desc = domain_spin_lock_irq_desc(d, pirq, NULL);
+    if ( !irq_desc )
+        return r;
 
     if ( irq_desc->handler != &pci_msi_type )
         goto out;
@@ -399,28 +398,22 @@ int msixtbl_pt_register(struct domain *d
 
     pdev = msi_desc->dev;
 
-    spin_lock(&d->arch.hvm_domain.msixtbl_list_lock);
-
     list_for_each_entry( entry, &d->arch.hvm_domain.msixtbl_list, list )
         if ( pdev == entry->pdev )
             goto found;
 
-    entry = add_msixtbl_entry(d, pdev, gtable);
-    if ( !entry )
-    {
-        spin_unlock(&d->arch.hvm_domain.msixtbl_list_lock);
-        goto out;
-    }
+    entry = new_entry;
+    new_entry = NULL;
+    add_msixtbl_entry(d, pdev, gtable, entry);
 
 found:
     atomic_inc(&entry->refcnt);
-    spin_unlock(&d->arch.hvm_domain.msixtbl_list_lock);
     r = 0;
 
 out:
     spin_unlock_irq(&irq_desc->lock);
+    xfree(new_entry);
     return r;
-
 }
 
 void msixtbl_pt_unregister(struct domain *d, int pirq)
@@ -430,9 +423,9 @@ void msixtbl_pt_unregister(struct domain
     struct pci_dev *pdev;
     struct msixtbl_entry *entry;
 
-    ASSERT(spin_is_locked(&pcidevs_lock));
-
     irq_desc = domain_spin_lock_irq_desc(d, pirq, NULL);
+    if ( !irq_desc )
+        return;
 
     if ( irq_desc->handler != &pci_msi_type )
         goto out;
@@ -443,36 +436,33 @@ void msixtbl_pt_unregister(struct domain
 
     pdev = msi_desc->dev;
 
-    spin_lock(&d->arch.hvm_domain.msixtbl_list_lock);
-
     list_for_each_entry( entry, &d->arch.hvm_domain.msixtbl_list, list )
         if ( pdev == entry->pdev )
             goto found;
 
-    spin_unlock(&d->arch.hvm_domain.msixtbl_list_lock);
-
-
 out:
-    spin_unlock(&irq_desc->lock);
+    spin_unlock_irq(&irq_desc->lock);
     return;
 
 found:
     if ( !atomic_dec_and_test(&entry->refcnt) )
         del_msixtbl_entry(entry);
 
-    spin_unlock(&d->arch.hvm_domain.msixtbl_list_lock);
-    spin_unlock(&irq_desc->lock);
+    spin_unlock_irq(&irq_desc->lock);
 }
 
 void msixtbl_pt_cleanup(struct domain *d, int pirq)
 {
+    irq_desc_t *irq_desc;
     struct msixtbl_entry *entry, *temp;
 
-    spin_lock(&d->arch.hvm_domain.msixtbl_list_lock);
+    irq_desc = domain_spin_lock_irq_desc(d, pirq, NULL);
+    if ( !irq_desc )
+        return;
 
     list_for_each_entry_safe( entry, temp,
                               &d->arch.hvm_domain.msixtbl_list, list )
         del_msixtbl_entry(entry);
 
-    spin_unlock(&d->arch.hvm_domain.msixtbl_list_lock);
+    spin_unlock_irq(&irq_desc->lock);
 }
diff -r cff29d694a89 xen/include/asm-x86/hvm/domain.h
--- a/xen/include/asm-x86/hvm/domain.h  Thu Mar 05 17:50:05 2009 +0000
+++ b/xen/include/asm-x86/hvm/domain.h  Fri Mar 06 11:01:43 2009 +0900
@@ -77,7 +77,6 @@ struct hvm_domain {
 
     /* hypervisor intercepted msix table */
     struct list_head       msixtbl_list;
-    spinlock_t             msixtbl_list_lock;
 
     struct viridian_domain viridian;
 
_______________________________________________
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®.