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-devel

[Xen-devel] [PATCH 07/12] xen: events: separate MSI PIRQ allocation from

To: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Subject: [Xen-devel] [PATCH 07/12] xen: events: separate MSI PIRQ allocation from PIRQ binding to IRQ
From: Ian Campbell <ian.campbell@xxxxxxxxxx>
Date: Fri, 18 Feb 2011 16:43:32 +0000
Cc: Jeremy Fitzhardinge <jeremy@xxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx, Ian Campbell <ian.campbell@xxxxxxxxxx>, Stefano Stabellini <Stefano.Stabellini@xxxxxxxxxxxxx>
Delivery-date: Fri, 18 Feb 2011 08:52:03 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1298047386.16356.3620.camel@xxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1298047386.16356.3620.camel@xxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Split the binding aspect of xen_allocate_pirq_msi out into a new
xen_bind_pirq_to_irq function.

In xen_hvm_setup_msi_irq when allocating a pirq write the MSI message
to signal the PIRQ as soon as the pirq is obtained. There is no way to
free the pirq back so if the subsequent binding to an IRQ fails we
want to ensure that we will reuse the PIRQ next time rather than leak
it.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 arch/x86/pci/xen.c   |   68 +++++++++++++++++++------------------------------
 drivers/xen/events.c |   30 ++++++++++-----------
 include/xen/events.h |    4 ++-
 3 files changed, 43 insertions(+), 59 deletions(-)

diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index b734358..2b915c1 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -86,7 +86,7 @@ static void xen_msi_compose_msg(struct pci_dev *pdev, 
unsigned int pirq,
 
 static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
-       int irq, pirq, ret = 0;
+       int irq, pirq;
        struct msi_desc *msidesc;
        struct msi_msg msg;
 
@@ -94,39 +94,32 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int 
nvec, int type)
                __read_msi_msg(msidesc, &msg);
                pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
                        ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
-               if (xen_irq_from_pirq(pirq) >= 0 && msg.data == 
XEN_PIRQ_MSI_DATA) {
-                       irq = xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ?
-                                                   "msi-x" : "msi", &pirq, 0);
-                       if (irq < 0)
+               if (msg.data != XEN_PIRQ_MSI_DATA ||
+                   xen_irq_from_pirq(pirq) < 0) {
+                       pirq = xen_allocate_pirq_msi(dev, msidesc);
+                       if (pirq < 0)
                                goto error;
-                       ret = set_irq_msi(irq, msidesc);
-                       if (ret < 0)
-                               goto error_while;
-                       printk(KERN_DEBUG "xen: msi already setup: msi --> 
irq=%d"
-                                       " pirq=%d\n", irq, pirq);
-                       return 0;
+                       xen_msi_compose_msg(dev, pirq, &msg);
+                       __write_msi_msg(msidesc, &msg);
+                       dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
+               } else {
+                       dev_dbg(&dev->dev,
+                               "xen: msi already bound to pirq=%d\n", pirq);
                }
-               irq = xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ?
-                                           "msi-x" : "msi", &pirq, 1);
-               if (irq < 0 || pirq < 0)
+               irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
+                                              (type == PCI_CAP_ID_MSIX) ?
+                                              "msi-x" : "msi");
+               if (irq < 0)
                        goto error;
-               printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq);
-               xen_msi_compose_msg(dev, pirq, &msg);
-               ret = set_irq_msi(irq, msidesc);
-               if (ret < 0)
-                       goto error_while;
-               write_msi_msg(irq, &msg);
+               dev_dbg(&dev->dev,
+                       "xen: msi --> pirq=%d --> irq=%d\n", pirq, irq);
        }
        return 0;
 
-error_while:
-       unbind_from_irqhandler(irq, NULL);
 error:
-       if (ret == -ENODEV)
-               dev_err(&dev->dev, "Xen PCI frontend has not registered" \
-                               " MSI/MSI-X support!\n");
-
-       return ret;
+       dev_err(&dev->dev,
+               "Xen PCI frontend has not registered MSI/MSI-X support!\n");
+       return -ENODEV;
 }
 
 /*
@@ -152,28 +145,19 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int 
nvec, int type)
                goto error;
        i = 0;
        list_for_each_entry(msidesc, &dev->msi_list, list) {
-               irq = xen_allocate_pirq_msi(
-                       (type == PCI_CAP_ID_MSIX) ?
-                       "pcifront-msi-x" : "pcifront-msi",
-                       &v[i], 0);
-               if (irq < 0) {
-                       ret = -1;
+               irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i],
+                                              (type == PCI_CAP_ID_MSIX) ?
+                                              "pcifront-msi-x" :
+                                              "pcifront-msi");
+               if (irq < 0)
                        goto free;
-               }
-               ret = set_irq_msi(irq, msidesc);
-               if (ret)
-                       goto error_while;
                i++;
        }
        kfree(v);
        return 0;
 
-error_while:
-       unbind_from_irqhandler(irq, NULL);
 error:
-       if (ret == -ENODEV)
-               dev_err(&dev->dev, "Xen PCI frontend has not registered" \
-                       " MSI/MSI-X support!\n");
+       dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X 
support!\n");
 free:
        kfree(v);
        return ret;
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 9995a1f..6b52beb 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -637,12 +637,12 @@ out:
 #include <linux/msi.h>
 #include "../pci/msi.h"
 
-static int find_unbound_pirq(int type)
+int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc)
 {
        int rc;
        struct physdev_get_free_pirq op_get_free_pirq;
 
-       op_get_free_pirq.type = type;
+       op_get_free_pirq.type = MAP_PIRQ_TYPE_MSI;
        rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq);
 
        WARN_ONCE(rc == -ENOSYS,
@@ -651,9 +651,10 @@ static int find_unbound_pirq(int type)
        return rc ? -1 : op_get_free_pirq.pirq;
 }
 
-int xen_allocate_pirq_msi(char *name, int *pirq, int alloc_pirq)
+int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
+                            int pirq, const char *name)
 {
-       int irq;
+       int irq, ret;
 
        spin_lock(&irq_mapping_update_lock);
 
@@ -661,24 +662,21 @@ int xen_allocate_pirq_msi(char *name, int *pirq, int 
alloc_pirq)
        if (irq == -1)
                goto out;
 
-       if (alloc_pirq) {
-               *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI);
-               if (*pirq == -1) {
-                       xen_free_irq(irq);
-                       irq = -1;
-                       goto out;
-               }
-       }
-
        set_irq_chip_and_handler_name(irq, &xen_pirq_chip,
                                      handle_level_irq, name);
 
-       irq_info[irq] = mk_pirq_info(0, *pirq, 0, 0);
-       pirq_to_irq[*pirq] = irq;
-
+       irq_info[irq] = mk_pirq_info(0, pirq, 0, 0);
+       pirq_to_irq[pirq] = irq;
+       ret = set_irq_msi(irq, msidesc);
+       if (ret < 0)
+               goto error_irq;
 out:
        spin_unlock(&irq_mapping_update_lock);
        return irq;
+error_irq:
+       spin_unlock(&irq_mapping_update_lock);
+       xen_free_irq(irq);
+       return -1;
 }
 
 int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type)
diff --git a/include/xen/events.h b/include/xen/events.h
index 6c0360a..72310ed 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -81,7 +81,9 @@ int xen_allocate_pirq(unsigned gsi, int shareable, char 
*name);
 int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name);
 
 #ifdef CONFIG_PCI_MSI
-int xen_allocate_pirq_msi(char *name, int *pirq, int alloc_pirq);
+int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc);
+int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
+                            int pirq, const char *name);
 int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int 
type);
 #endif
 
-- 
1.5.6.5


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

<Prev in Thread] Current Thread [Next in Thread>