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] Re: [PATCH 20/23] xen-pcifront: Xen PCI frontend driver.

To: "Konrad Rzeszutek Wilk" <konrad.wilk@xxxxxxxxxx>
Subject: [Xen-devel] Re: [PATCH 20/23] xen-pcifront: Xen PCI frontend driver.
From: "Jan Beulich" <JBeulich@xxxxxxxxxx>
Date: Wed, 13 Oct 2010 10:36:59 +0100
Cc: Jeremy Fitzhardinge <jeremy@xxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx, Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>, linux-kernel@xxxxxxxxxxxxxxx, Ryan Wilson <hap9@xxxxxxxxxx>, Konrad Rzeszutek Wilk <konrad@xxxxxxxxxx>
Delivery-date: Wed, 13 Oct 2010 02:37:53 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1286898271-32018-21-git-send-email-konrad.wilk@xxxxxxxxxx>
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: <1286898271-32018-1-git-send-email-konrad.wilk@xxxxxxxxxx> <1286898271-32018-21-git-send-email-konrad.wilk@xxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
>>> On 12.10.10 at 17:44, Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> wrote:
> --- a/drivers/pci/Kconfig
> +++ b/drivers/pci/Kconfig
> @@ -40,6 +40,21 @@ config PCI_STUB
>  
>         When in doubt, say N.
>  
> +config XEN_PCIDEV_FRONTEND
> +        tristate "Xen PCI Frontend"
> +        depends on PCI && X86 && XEN
> +        select HOTPLUG
> +        select PCI_XEN
> +        default y
> +        help
> +          The PCI device frontend driver allows the kernel to import 
> arbitrary
> +          PCI devices from a PCI backend to support PCI driver domains.
> +
> +config XEN_PCIDEV_FE_DEBUG
> +        bool
> +        depends on PCI_DEBUG
> +        default n

A bool without prompt, (pointlessly) defaulting to 'n', and without
getting selected anywhere has no way to get set to 'y'...

> +
>  config HT_IRQ
>       bool "Interrupts on hypertransport devices"
>       default y
> --- /dev/null
> +++ b/drivers/pci/xen-pcifront.c
> @@ -0,0 +1,1157 @@
> +/*
> + * Xen PCI Frontend.
> + *
> + *   Author: Ryan Wilson <hap9@xxxxxxxxxxxxxx>
> + */
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/mm.h>
> +#include <xen/xenbus.h>
> +#include <xen/events.h>
> +#include <xen/grant_table.h>
> +#include <xen/page.h>
> +#include <linux/spinlock.h>
> +#include <linux/pci.h>
> +#include <linux/msi.h>
> +#include <xen/xenbus.h>
> +#include <xen/interface/io/pciif.h>
> +#include <asm/xen/pci.h>
> +#include <linux/interrupt.h>
> +#include <asm/atomic.h>
> +#include <linux/workqueue.h>
> +#include <linux/bitops.h>
> +#include <linux/time.h>
> +
> +
> +#ifndef __init_refok
> +#define __init_refok
> +#endif

???

> +
> +#define INVALID_GRANT_REF (0)
> +#define INVALID_EVTCHN    (-1)
> +
> +
> +struct pci_bus_entry {
> +     struct list_head list;
> +     struct pci_bus *bus;
> +};
> +
> +#define _PDEVB_op_active             (0)
> +#define PDEVB_op_active                      (1 << (_PDEVB_op_active))
> +
> +struct pcifront_device {
> +     struct xenbus_device *xdev;
> +     struct list_head root_buses;
> +
> +     int evtchn;
> +     int gnt_ref;
> +
> +     int irq;
> +
> +     /* Lock this when doing any operations in sh_info */
> +     spinlock_t sh_info_lock;
> +     struct xen_pci_sharedinfo *sh_info;
> +     struct work_struct op_work;
> +     unsigned long flags;
> +
> +};
> +
> +struct pcifront_sd {
> +     int domain;
> +     struct pcifront_device *pdev;
> +};
> +
> +static inline struct pcifront_device *
> +pcifront_get_pdev(struct pcifront_sd *sd)
> +{
> +     return sd->pdev;
> +}
> +
> +static inline void pcifront_init_sd(struct pcifront_sd *sd,
> +                                 unsigned int domain, unsigned int bus,
> +                                 struct pcifront_device *pdev)
> +{
> +     sd->domain = domain;
> +     sd->pdev = pdev;
> +}
> +
> +static inline void pcifront_setup_root_resources(struct pci_bus *bus,
> +                                              struct pcifront_sd *sd)
> +{
> +}

???

> +
> +
> +DEFINE_SPINLOCK(pcifront_dev_lock);

static?

>...
> +void pcifront_do_aer(struct work_struct *data)

static?

>...
> +irqreturn_t pcifront_handler_aer(int irq, void *dev)

static?

>...
> +int pcifront_connect(struct pcifront_device *pdev)

static?

>...
> +void pcifront_disconnect(struct pcifront_device *pdev)

static?

>...
> +static void free_pdev(struct pcifront_device *pdev)
> +{
> +     dev_dbg(&pdev->xdev->dev, "freeing pdev @ 0x%p\n", pdev);
> +
> +     pcifront_free_roots(pdev);
> +
> +     /*For PCIE_AER error handling job*/
> +     flush_scheduled_work();

        if (pdev->irq > 0)

> +     unbind_from_irqhandler(pdev->irq, pdev);
> +
> +     if (pdev->evtchn != INVALID_EVTCHN)
> +             xenbus_free_evtchn(pdev->xdev, pdev->evtchn);
> +
> +     if (pdev->gnt_ref != INVALID_GRANT_REF)
> +             gnttab_end_foreign_access(pdev->gnt_ref, 0 /* r/w page */,
> +                                       (unsigned long)pdev->sh_info);

        else
                free_page((unsigned long)pdev->sh_info);

> +
> +     dev_set_drvdata(&pdev->xdev->dev, NULL);
> +
> +     kfree(pdev);
> +}
> +
> +static int pcifront_publish_info(struct pcifront_device *pdev)
> +{
> +     int err = 0;
> +     struct xenbus_transaction trans;
> +
> +     err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info));
> +     if (err < 0)
> +             goto out;
> +
> +     pdev->gnt_ref = err;
> +
> +     err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn);
> +     if (err)
> +             goto out;
> +
> +     err = bind_evtchn_to_irqhandler(pdev->evtchn, pcifront_handler_aer,
> +             0, "pcifront", pdev);
> +     if (err < 0) {
> +             xenbus_free_evtchn(pdev->xdev, pdev->evtchn);

You're leaking the grant ref here. I think it's better to not do any
cleanup here, and instead call free_pdev() on error in
pcifront_xenbus_probe() (see below).

> +             xenbus_dev_fatal(pdev->xdev, err, "Failed to bind evtchn to "
> +                              "irqhandler.\n");
> +             return err;
> +     }
> +     pdev->irq = err;
>...
> +static int __devinit pcifront_try_connect(struct pcifront_device *pdev)
> +{
> +     int err = -EFAULT;
> +     int i, num_roots, len;
> +     char str[64];
> +     unsigned int domain, bus;
> +

The original code had a per-device lock here and in subsequent
functions. Is this being dropped due to implicit serialization through
only running in the context of the single xenbus thread?

>...
> +static int pcifront_xenbus_probe(struct xenbus_device *xdev,
> +                              const struct xenbus_device_id *id)
> +{
> +     int err = 0;
> +     struct pcifront_device *pdev = alloc_pdev(xdev);
> +
> +     if (pdev == NULL) {
> +             err = -ENOMEM;
> +             xenbus_dev_fatal(xdev, err,
> +                              "Error allocating pcifront_device struct");
> +             goto out;
> +     }
> +
> +     err = pcifront_publish_info(pdev);

        if (err)
                free_pdev(pdev);

> +
> +out:
> +     return err;
> +}
>...

Jan

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

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