[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v4 10/23] libxl: remove get_all_assigned_devices() from libxl_pci.c
Hi, Paul! On 11/24/20 10:01 AM, Paul Durrant wrote: > From: Paul Durrant <pdurrant@xxxxxxxxxx> > > Use of this function is a very inefficient way to check whether a device > has already been assigned. > > This patch adds code that saves the domain id in xenstore at the point of > assignment, and removes it again when the device id de-assigned (or the > domain is destroyed). It is then straightforward to check whether a device > has been assigned by checking whether a device has a saved domain id. > > NOTE: To facilitate the xenstore check it is necessary to move the > pci_info_xs_read() earlier in libxl_pci.c. To keep related functions > together, the rest of the pci_info_xs_XXX() functions are moved too. > > Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx> Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@xxxxxxxx> Thank you, Oleksandr > --- > Cc: Ian Jackson <iwj@xxxxxxxxxxxxxx> > Cc: Wei Liu <wl@xxxxxxx> > --- > tools/libs/light/libxl_pci.c | 149 > ++++++++++++++++--------------------------- > 1 file changed, 55 insertions(+), 94 deletions(-) > > diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c > index ec101f255f..d3c7a547c3 100644 > --- a/tools/libs/light/libxl_pci.c > +++ b/tools/libs/light/libxl_pci.c > @@ -336,50 +336,6 @@ retry_transaction2: > return 0; > } > > -static int get_all_assigned_devices(libxl__gc *gc, libxl_device_pci **list, > int *num) > -{ > - char **domlist; > - unsigned int nd = 0, i; > - > - *list = NULL; > - *num = 0; > - > - domlist = libxl__xs_directory(gc, XBT_NULL, "/local/domain", &nd); > - for(i = 0; i < nd; i++) { > - char *path, *num_devs; > - > - path = GCSPRINTF("/local/domain/0/backend/%s/%s/0/num_devs", > - > libxl__device_kind_to_string(LIBXL__DEVICE_KIND_PCI), > - domlist[i]); > - num_devs = libxl__xs_read(gc, XBT_NULL, path); > - if ( num_devs ) { > - int ndev = atoi(num_devs), j; > - char *devpath, *bdf; > - > - for(j = 0; j < ndev; j++) { > - devpath = GCSPRINTF("/local/domain/0/backend/%s/%s/0/dev-%u", > - > libxl__device_kind_to_string(LIBXL__DEVICE_KIND_PCI), > - domlist[i], j); > - bdf = libxl__xs_read(gc, XBT_NULL, devpath); > - if ( bdf ) { > - unsigned dom, bus, dev, func; > - if ( sscanf(bdf, PCI_BDF, &dom, &bus, &dev, &func) != 4 ) > - continue; > - > - *list = realloc(*list, sizeof(libxl_device_pci) * > ((*num) + 1)); > - if (*list == NULL) > - return ERROR_NOMEM; > - pci_struct_fill(*list + *num, dom, bus, dev, func, 0); > - (*num)++; > - } > - } > - } > - } > - libxl__ptr_add(gc, *list); > - > - return 0; > -} > - > static int is_pci_in_array(libxl_device_pci *assigned, int num_assigned, > int dom, int bus, int dev, int func) > { > @@ -427,19 +383,58 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * > sysfs_path, > return 0; > } > > +#define PCI_INFO_PATH "/libxl/pci" > + > +static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci, > + const char *node) > +{ > + return node ? > + GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s", > + pci->domain, pci->bus, pci->dev, pci->func, > + node) : > + GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH, > + pci->domain, pci->bus, pci->dev, pci->func); > +} > + > + > +static int pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci, > + const char *node, const char *val) > +{ > + char *path = pci_info_xs_path(gc, pci, node); > + int rc = libxl__xs_printf(gc, XBT_NULL, path, "%s", val); > + > + if (rc) LOGE(WARN, "Write of %s to node %s failed.", val, path); > + > + return rc; > +} > + > +static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci, > + const char *node) > +{ > + char *path = pci_info_xs_path(gc, pci, node); > + > + return libxl__xs_read(gc, XBT_NULL, path); > +} > + > +static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci, > + const char *node) > +{ > + char *path = pci_info_xs_path(gc, pci, node); > + libxl_ctx *ctx = libxl__gc_owner(gc); > + > + /* Remove the xenstore entry */ > + xs_rm(ctx->xsh, XBT_NULL, path); > +} > + > libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num) > { > GC_INIT(ctx); > - libxl_device_pci *pcis = NULL, *new, *assigned; > + libxl_device_pci *pcis = NULL, *new; > struct dirent *de; > DIR *dir; > - int r, num_assigned; > > *num = 0; > > - r = get_all_assigned_devices(gc, &assigned, &num_assigned); > - if (r) goto out; > - > dir = opendir(SYSFS_PCIBACK_DRIVER); > if (NULL == dir) { > if (errno == ENOENT) { > @@ -455,9 +450,6 @@ libxl_device_pci > *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num) > if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4) > continue; > > - if (is_pci_in_array(assigned, num_assigned, dom, bus, dev, func)) > - continue; > - > new = realloc(pcis, ((*num) + 1) * sizeof(*new)); > if (NULL == new) > continue; > @@ -467,6 +459,10 @@ libxl_device_pci > *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num) > > memset(new, 0, sizeof(*new)); > pci_struct_fill(new, dom, bus, dev, func, 0); > + > + if (pci_info_xs_read(gc, new, "domid")) /* already assigned */ > + continue; > + > (*num)++; > } > > @@ -737,48 +733,6 @@ static int pciback_dev_unassign(libxl__gc *gc, > libxl_device_pci *pci) > return 0; > } > > -#define PCI_INFO_PATH "/libxl/pci" > - > -static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci, > - const char *node) > -{ > - return node ? > - GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s", > - pci->domain, pci->bus, pci->dev, pci->func, > - node) : > - GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH, > - pci->domain, pci->bus, pci->dev, pci->func); > -} > - > - > -static void pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci, > - const char *node, const char *val) > -{ > - char *path = pci_info_xs_path(gc, pci, node); > - > - if ( libxl__xs_printf(gc, XBT_NULL, path, "%s", val) < 0 ) { > - LOGE(WARN, "Write of %s to node %s failed.", val, path); > - } > -} > - > -static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci, > - const char *node) > -{ > - char *path = pci_info_xs_path(gc, pci, node); > - > - return libxl__xs_read(gc, XBT_NULL, path); > -} > - > -static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci, > - const char *node) > -{ > - char *path = pci_info_xs_path(gc, pci, node); > - libxl_ctx *ctx = libxl__gc_owner(gc); > - > - /* Remove the xenstore entry */ > - xs_rm(ctx->xsh, XBT_NULL, path); > -} > - > static int libxl__device_pci_assignable_add(libxl__gc *gc, > libxl_device_pci *pci, > int rebind) > @@ -1594,6 +1548,9 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t > domid, > goto out; > } > > + rc = pci_info_xs_write(gc, pci, "domid", GCSPRINTF("%u", domid)); > + if (rc) goto out; > + > libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func); > > stubdomid = libxl_get_stubdom_id(ctx, domid); > @@ -1721,6 +1678,7 @@ static void device_pci_add_done(libxl__egc *egc, > "PCI device %x:%x:%x.%x (rc %d)", > pci->domain, pci->bus, pci->dev, pci->func, > rc); > + pci_info_xs_remove(gc, pci, "domid"); > } > aodev->rc = rc; > aodev->callback(egc, aodev); > @@ -2282,6 +2240,9 @@ out: > libxl__xswait_stop(gc, &prs->xswait); > libxl__ev_time_deregister(gc, &prs->timeout); > libxl__ev_time_deregister(gc, &prs->retry_timer); > + > + if (!rc) pci_info_xs_remove(gc, pci, "domid"); > + > aodev->rc = rc; > aodev->callback(egc, aodev); > }
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |