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 2 of 3] xl, implement pci-list-assignable-devices

To: "Gianni Tedesco (3P)" <gianni.tedesco@xxxxxxxxxx>
Subject: [Xen-devel] Re: [PATCH 2 of 3] xl, implement pci-list-assignable-devices
From: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Date: Wed, 28 Jul 2010 18:39:55 +0100
Cc: Xen Devel <xen-devel@xxxxxxxxxxxxxxxxxxx>, Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>, Stefano Stabellini <Stefano.Stabellini@xxxxxxxxxxxxx>
Delivery-date: Wed, 28 Jul 2010 10:39:55 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <2147337494701090c1c0.1280247872@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: <patchbomb.1280247870@xxxxxxxxxxxxxxxxxxxxxx> <2147337494701090c1c0.1280247872@xxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Alpine 2.00 (DEB 1167 2008-08-23)
On Tue, 27 Jul 2010, Gianni Tedesco (3P) wrote:
>  tools/libxl/libxl.h       |    1 +
>  tools/libxl/libxl_pci.c   |  123 
> ++++++++++++++++++++++++++++++++++++++++++++++
>  tools/libxl/xl.h          |    1 +
>  tools/libxl/xl_cmdimpl.c  |   34 ++++++++++++
>  tools/libxl/xl_cmdtable.c |    5 +
>  5 files changed, 164 insertions(+), 0 deletions(-)
> 
> 
> diff -r 20b2e15131c7 -r 214733749470 tools/libxl/libxl.h
> --- a/tools/libxl/libxl.h     Tue Jul 27 17:13:35 2010 +0100
> +++ b/tools/libxl/libxl.h     Tue Jul 27 17:17:31 2010 +0100
> @@ -496,6 +496,7 @@ int libxl_device_pci_add(struct libxl_ct
>  int libxl_device_pci_remove(struct libxl_ctx *ctx, uint32_t domid, 
> libxl_device_pci *pcidev);
>  int libxl_device_pci_shutdown(struct libxl_ctx *ctx, uint32_t domid);
>  libxl_device_pci *libxl_device_pci_list(struct libxl_ctx *ctx, uint32_t 
> domid, int *num);
> +libxl_device_pci *libxl_device_pci_list_assignable(struct libxl_ctx *ctx, 
> int *num);
>  int libxl_device_pci_init(libxl_device_pci *pcidev, unsigned int domain,
>                            unsigned int bus, unsigned int dev,
>                            unsigned int func, unsigned int vdevfn);
> diff -r 20b2e15131c7 -r 214733749470 tools/libxl/libxl_pci.c
> --- a/tools/libxl/libxl_pci.c Tue Jul 27 17:13:35 2010 +0100
> +++ b/tools/libxl/libxl_pci.c Tue Jul 27 17:17:31 2010 +0100
> @@ -28,6 +28,7 @@
>  #include <unistd.h> /* for write, unlink and close */
>  #include <stdint.h>
>  #include <inttypes.h>
> +#include <dirent.h>
>  #include <assert.h>
>  
>  #include "libxl.h"
> @@ -258,6 +259,75 @@ retry_transaction2:
>      return 0;
>  }
>  
> +static libxl_device_pci *get_all_assigned_devices(struct libxl_ctx *ctx, int 
> *num)
> +{
> +    libxl_device_pci *new, *pcidevs = NULL;
> +    char **domlist;
> +    unsigned int nd, i;
> +
> +    *num = 0;
> +
> +    domlist = libxl_xs_directory(ctx, XBT_NULL, "/local/domain", &nd);
> +    for(i = 0; i < nd; i++) {
> +        char *path, *num_devs;
> +
> +        path = libxl_sprintf(ctx, 
> "/local/domain/0/backend/pci/%s/0/num_devs", domlist[i]);
> +        num_devs = libxl_xs_read(ctx, XBT_NULL, path);
> +        if ( num_devs ) {
> +            int ndev = atoi(num_devs), j;
> +            char *devpath, *bdf;
> +
> +            for(j = 0; j < ndev; j++) {
> +                devpath = libxl_sprintf(ctx, 
> "/local/domain/0/backend/pci/%s/0/dev-%u",
> +                                        domlist[i], j);
> +                bdf = libxl_xs_read(ctx, XBT_NULL, devpath);
> +                if ( bdf ) {
> +                    unsigned dom, bus, dev, func;
> +                    if ( sscanf(bdf, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
> +                        continue;
> +
> +                    new = realloc(pcidevs, ((*num) + 1) * sizeof(*new));
> +                    if ( NULL == new )
> +                        continue;
> +
> +                    pcidevs = new;
> +                    new = pcidevs + *num;
> +
> +                    libxl_device_pci_init(new, dom, bus, dev, func, ~0);
> +                    (*num)++;
> +                }
> +                libxl_free(ctx, bdf);
> +                libxl_free(ctx, devpath);
> +            }
> +            libxl_free(ctx, num_devs);
> +        }
> +        libxl_free(ctx, path);
> +    }
> +    libxl_free(ctx, domlist);
> +
> +    return pcidevs;
> +}

You shouldn't use libxl_free explicitly on variables allocated in the
context. Actually I like explicit free's but we have to keep the style
consistent, so the memory management refactoring should come in as a
separate patch, and here there shouldn't be any libxl_free's.
The realloc is correct because it is used on a variable that is going
to be returned to the caller.

Also I would prefer this function to return an integer and take the
libxl_device_pci array as a parameter.


> +
> +static int is_assigned(libxl_device_pci *assigned, int num_assigned,
> +                       int dom, int bus, int dev, int func)
> +{
> +    int i;
> +
> +    for(i = 0; i < num_assigned; i++) {
> +        if ( assigned[i].domain != dom )
> +            continue;
> +        if ( assigned[i].bus != bus )
> +            continue;
> +        if ( assigned[i].dev != dev )
> +            continue;
> +        if ( assigned[i].func != func )
> +            continue;
> +        return 1;
> +    }
> +
> +    return 0;
> +}
> +
>  int libxl_device_pci_add(struct libxl_ctx *ctx, uint32_t domid, 
> libxl_device_pci *pcidev)
>  {
>      char *path;
> @@ -466,6 +536,59 @@ out:
>      return 0;
>  }
>  
> +static libxl_device_pci *scan_sys_pcidir(libxl_device_pci *pcidevs, 
> libxl_device_pci *assigned,
> +                                         int num_assigned, const char *path, 
> int *num)
> +{
> +    libxl_device_pci *new;
> +    struct dirent *de;
> +    DIR *dir;
> +
> +    dir = opendir(path);
> +    if ( NULL == dir )
> +        return pcidevs;
> +
> +    while( (de = readdir(dir)) ) {
> +        unsigned dom, bus, dev, func;
> +        if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
> +            continue;
> +
> +        if ( is_assigned(assigned, num_assigned, dom, bus, dev, func) )
> +            continue;
> +
> +        new = realloc(pcidevs, ((*num) + 1) * sizeof(*new));
> +        if ( NULL == new )
> +            continue;
> +
> +        pcidevs = new;
> +        new = pcidevs + *num;
> +
> +        libxl_device_pci_init(new, dom, bus, dev, func, ~0);
> +        (*num)++;
> +    }
> +
> +    closedir(dir);
> +    return pcidevs;
> +}
> +
> +libxl_device_pci *libxl_device_pci_list_assignable(struct libxl_ctx *ctx, 
> int *num)
> +{
> +    libxl_device_pci *pcidevs = NULL;
> +    libxl_device_pci *assigned;
> +    int num_assigned;
> +
> +    *num = 0;
> +
> +    assigned = get_all_assigned_devices(ctx, &num_assigned);
> +
> +    pcidevs = scan_sys_pcidir(pcidevs, assigned, num_assigned,
> +                              "/sys/bus/pci/drivers/pciback", num);
> +    pcidevs = scan_sys_pcidir(pcidevs, assigned, num_assigned,
> +                              "/sys/bus/pci/drivers/pcistub", num);
> +
> +    free(assigned);
> +    return pcidevs;
> +}
> +

Same comment about returning an integer, also I don't like the way you
are "assuming" scan_sys_pcidir is going to use realloc on pcidevs: that
should be an implementation detail of scan_sys_pcidir that callers
shouldn't rely upon.
Consider that devices bound to pcistub cannot be assigned to PV guests,
so I would remove scan_sys_pcidir on pcistub from here.
Please define "/sys/bus/pci/drivers/pciback" in a macro.


>  libxl_device_pci *libxl_device_pci_list(struct libxl_ctx *ctx, uint32_t 
> domid, int *num)
>  {
>      char *be_path, *num_devs, *xsdev, *xsvdevfn, *xsopts;
> diff -r 20b2e15131c7 -r 214733749470 tools/libxl/xl.h
> --- a/tools/libxl/xl.h        Tue Jul 27 17:13:35 2010 +0100
> +++ b/tools/libxl/xl.h        Tue Jul 27 17:17:31 2010 +0100
> @@ -32,6 +32,7 @@ int main_cd_insert(int argc, char **argv
>  int main_console(int argc, char **argv);
>  int main_vncviewer(int argc, char **argv);
>  int main_pcilist(int argc, char **argv);
> +int main_pcilist_assignable(int argc, char **argv);
>  int main_pcidetach(int argc, char **argv);
>  int main_pciattach(int argc, char **argv);
>  int main_restore(int argc, char **argv);
> diff -r 20b2e15131c7 -r 214733749470 tools/libxl/xl_cmdimpl.c
> --- a/tools/libxl/xl_cmdimpl.c        Tue Jul 27 17:13:35 2010 +0100
> +++ b/tools/libxl/xl_cmdimpl.c        Tue Jul 27 17:17:31 2010 +0100
> @@ -1706,6 +1706,40 @@ int main_vncviewer(int argc, char **argv
>      exit(0);
>  }
>  
> +void pcilist_assignable(void)
> +{
> +    libxl_device_pci *pcidevs;
> +    int num, i;
> +
> +    pcidevs = libxl_device_pci_list_assignable(&ctx, &num);
> +    if (!num)
> +        return;
> +    for (i = 0; i < num; i++) {
> +        printf("%04x:%02x:%02x:%01x\n",
> +                pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, 
> pcidevs[i].func);
> +    }
> +    free(pcidevs);
> +}
> +
> +int main_pcilist_assignable(int argc, char **argv)
> +{
> +    int opt;
> +
> +    while ((opt = getopt(argc, argv, "h")) != -1) {
> +        switch (opt) {
> +        case 'h':
> +            help("pci-list-assignable-devices");
> +            exit(0);
> +        default:
> +            fprintf(stderr, "option not supported\n");
> +            break;
> +        }
> +    }
> +
> +    pcilist_assignable();
> +    exit(0);
> +}
> +
>  void pcilist(char *dom)
>  {
>      libxl_device_pci *pcidevs;
> diff -r 20b2e15131c7 -r 214733749470 tools/libxl/xl_cmdtable.c
> --- a/tools/libxl/xl_cmdtable.c       Tue Jul 27 17:13:35 2010 +0100
> +++ b/tools/libxl/xl_cmdtable.c       Tue Jul 27 17:17:31 2010 +0100
> @@ -68,6 +68,11 @@ struct cmd_spec cmd_table[] = {
>        "List pass-through pci devices for a domain",
>        "<Domain>",
>      },
> +    { "pci-list-assignable-devices",
> +      &main_pcilist_assignable,
> +      "List all the assignable pci devices",
> +      "",
> +    },
>      { "pause",
>        &main_pause,
>        "Pause execution of a domain",
> 

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