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

[PATCH 9/9] tools/libs/light: Add "reset" and "remove" PCI dev commands to xl pcid daemon and libxl PCI



From: Anastasiia Lukianenko <anastasiia_lukianenko@xxxxxxxx>

Add "reset" command processing to xl pcid daemon.
Make possible sending "reset"/"remove" PCI device requests from libxl PCI
to xl pcid daemon instead of using sysfs on libxl side.

Signed-off-by: Anastasiia Lukianenko <anastasiia_lukianenko@xxxxxxxx>
---
 tools/include/pcid.h          |  1 +
 tools/libs/light/libxl_pci.c  | 94 +++++++++++++++++++----------------
 tools/libs/light/libxl_pcid.c | 63 +++++++++++++++++++++++
 3 files changed, 115 insertions(+), 43 deletions(-)

diff --git a/tools/include/pcid.h b/tools/include/pcid.h
index 3153bafb19..38ea06c602 100644
--- a/tools/include/pcid.h
+++ b/tools/include/pcid.h
@@ -30,6 +30,7 @@
 
 #define PCID_CMD_LIST            "ls"
 #define PCID_CMD_UNBIND          "unbind"
+#define PCID_CMD_RESET           "reset"
 #define PCID_CMD_DIR_ID          "dir_id"
 
 #define PCID_CMD_WRITE           "write"
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 3d9bf4830b..0498baa47e 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1635,37 +1635,26 @@ static int libxl__device_pci_reset(libxl__gc *gc, 
unsigned int domain, unsigned
                                    unsigned int dev, unsigned int func)
 {
     char *reset;
-    int fd, rc;
-
-    reset = GCSPRINTF("%s/do_flr", SYSFS_PCIBACK_DRIVER);
-    fd = open(reset, O_WRONLY);
-    if (fd >= 0) {
-        char *buf = GCSPRINTF(PCI_BDF, domain, bus, dev, func);
-        rc = write(fd, buf, strlen(buf));
-        if (rc < 0)
-            LOGD(ERROR, domain, "write to %s returned %d", reset, rc);
-        close(fd);
-        return rc < 0 ? rc : 0;
-    }
-    if (errno != ENOENT)
-        LOGED(ERROR, domain, "Failed to access pciback path %s", reset);
-    reset = GCSPRINTF("%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, bus, dev, 
func);
-    fd = open(reset, O_WRONLY);
-    if (fd >= 0) {
-        rc = write(fd, "1", 1);
-        if (rc < 0)
-            LOGED(ERROR, domain, "write to %s returned %d", reset, rc);
-        close(fd);
-        return rc < 0 ? rc : 0;
-    }
-    if (errno == ENOENT) {
-        LOGD(ERROR, domain,
-             "The kernel doesn't support reset from sysfs for PCI device 
"PCI_BDF,
-             domain, bus, dev, func);
-    } else {
-        LOGED(ERROR, domain, "Failed to access reset path %s", reset);
+    char *buf;
+    struct vchan_info *vchan;
+    libxl__json_object *args = NULL, *result = NULL;
+
+    vchan = pci_prepare_vchan(gc);
+    if (!vchan)
+        return -1;
+
+    reset = GCSPRINTF("%s", "/do_flr");
+    buf = GCSPRINTF(PCI_BDF, domain, bus, dev, func);
+
+    libxl__vchan_param_add_string(gc, &args, PCID_CMD_PCI_PATH, reset);
+    libxl__vchan_param_add_string(gc, &args, PCID_CMD_PCI_INFO, buf);
+    result = vchan_send_command(gc, vchan, PCID_CMD_RESET, args);
+    if (!result) {
+        LOGD(ERROR, domain, "write to %s returned error", reset);
+        return -1;
     }
-    return -1;
+
+    return 0;
 }
 
 int libxl__device_pci_setdefault(libxl__gc *gc, uint32_t domid,
@@ -2085,20 +2074,35 @@ static void do_pci_remove(libxl__egc *egc, 
pci_remove_state *prs)
             goto out_fail;
         }
     } else {
-        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", 
pci->domain,
+        char *sysfs_path = GCSPRINTF("/"PCI_BDF"/resource", pci->domain,
                                      pci->bus, pci->dev, pci->func);
-        FILE *f = fopen(sysfs_path, "r");
         unsigned int start = 0, end = 0, flags = 0, size = 0;
         int irq = 0;
         int i;
+        struct vchan_info *vchan;
+        libxl__json_object *args = NULL, *result = NULL;
+        const libxl__json_object *addr;
+        int j = 0;
 
-        if (f == NULL) {
-            LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
+        vchan = pci_prepare_vchan(gc);
+        if (!vchan)
+            goto out_fail;
+        libxl__vchan_param_add_string(gc, &args, PCID_CMD_PCI_INFO, 
sysfs_path);
+        result = vchan_send_command(gc, vchan, PCID_CMD_READ_RESOURCES, args);
+        if (!result) {
+            LOGED(ERROR, domainid, "Couldn't get resources from %s", 
sysfs_path);
+            rc = ERROR_FAIL;
             goto skip1;
         }
+
         for (i = 0; i < PROC_PCI_NUM_RESOURCES; i++) {
-            if (fscanf(f, "0x%x 0x%x 0x%x\n", &start, &end, &flags) != 3)
-                continue;
+            addr = libxl__json_array_get(result, j++);
+            start = libxl__json_object_get_integer(addr);
+            addr = libxl__json_array_get(result, j++);
+            end = libxl__json_object_get_integer(addr);
+            addr = libxl__json_array_get(result, j++);
+            flags = libxl__json_object_get_integer(addr);
+
             size = end - start + 1;
             if (start) {
                 if (flags & PCI_BAR_IO) {
@@ -2119,16 +2123,21 @@ static void do_pci_remove(libxl__egc *egc, 
pci_remove_state *prs)
                 }
             }
         }
-        fclose(f);
+
 skip1:
-        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
+        sysfs_path = GCSPRINTF("/"PCI_BDF"/irq", pci->domain,
                                pci->bus, pci->dev, pci->func);
-        f = fopen(sysfs_path, "r");
-        if (f == NULL) {
-            LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
+        libxl__vchan_param_add_string(gc, &args, PCID_CMD_PCI_INFO, 
sysfs_path);
+        libxl__vchan_param_add_string(gc, &args, PCID_CMD_DIR_ID, 
PCID_PCI_DEV);
+        result = vchan_send_command(gc, vchan, PCID_CMD_READ_HEX, args);
+        if (!result) {
+            LOGED(ERROR, domainid, "Couldn't get irq from %s", sysfs_path);
+            rc = ERROR_FAIL;
             goto skip_irq;
         }
-        if ((fscanf(f, "%u", &irq) == 1) && irq) {
+
+        irq = libxl__json_object_get_integer(result);
+        if (irq) {
             rc = xc_physdev_unmap_pirq(ctx->xch, domid, irq);
             if (rc < 0) {
                 LOGED(ERROR, domainid, "xc_physdev_unmap_pirq irq=%d", irq);
@@ -2138,7 +2147,6 @@ skip1:
                 LOGED(ERROR, domainid, "xc_domain_irq_permission irq=%d", irq);
             }
         }
-        fclose(f);
     }
 skip_irq:
     rc = 0;
diff --git a/tools/libs/light/libxl_pcid.c b/tools/libs/light/libxl_pcid.c
index 7dd8f53f78..a4669b9533 100644
--- a/tools/libs/light/libxl_pcid.c
+++ b/tools/libs/light/libxl_pcid.c
@@ -348,6 +348,67 @@ out:
     return result;
 }
 
+static libxl__json_object *process_reset_cmd(libxl__gc *gc,
+                                             const struct libxl__json_object 
*resp)
+{
+    libxl__json_object *result = NULL;
+    const libxl__json_object *args, *pci_path, *pci_info;
+    char *reset;
+    int rc, fd;
+
+    args = libxl__json_map_get(PCID_MSG_FIELD_ARGS, resp, JSON_MAP);
+    if (!args)
+        goto out;
+    pci_info = libxl__json_map_get(PCID_CMD_PCI_INFO, args, JSON_ANY);
+    if (!pci_info)
+        goto out;
+    pci_path = libxl__json_map_get(PCID_CMD_PCI_PATH, args, JSON_ANY);
+
+    reset = libxl__sprintf(gc, SYSFS_PCIBACK_DRIVER"%s", pci_path->u.string);
+    fd = open(reset, O_WRONLY);
+    if (fd >= 0) {
+        rc = write(fd, pci_info->u.string, strlen(pci_info->u.string));
+        if (rc < 0) {
+            LOGE(ERROR, "write to %s returned %d\n", reset, rc);
+            goto out;
+        }
+        close(fd);
+        goto success;
+    }
+    if (errno != ENOENT)
+        LOGE(ERROR, "Failed to access pciback path %s\n", reset);
+
+    reset = libxl__sprintf(gc, "%s/%s/reset", SYSFS_PCI_DEV, 
pci_info->u.string);
+    fd = open(reset, O_WRONLY);
+    if (fd >= 0) {
+        rc = write(fd, "1", 1);
+        if (rc < 0) {
+            LOGE(ERROR, "write to %s returned %d\n", reset, rc);
+            goto out;
+        }
+        close(fd);
+        goto success;
+    }
+    if (errno == ENOENT)
+        LOGE(ERROR,
+                "The kernel doesn't support reset from sysfs for PCI device 
%s\n",
+                pci_info->u.string);
+    else
+        LOGE(ERROR, "Failed to access reset path %s\n", reset);
+    goto out;
+
+success:
+    result = libxl__json_object_alloc(gc, JSON_STRING);
+    if (!result) {
+        LOGE(ERROR, "Memory allocation failed\n");
+        goto out;
+    }
+    result->u.string = pci_path->u.string;
+
+out:
+    return result;
+}
+
 static int pcid_handle_message(libxl__gc *gc, const libxl__json_object 
*request,
                                libxl__json_object **result)
 {
@@ -373,6 +434,8 @@ static int pcid_handle_message(libxl__gc *gc, const 
libxl__json_object *request,
         *result = process_read_rsc_cmd(gc, request);
     else if (strcmp(command_name, PCID_CMD_UNBIND) == 0)
         *result = process_unbind_cmd(gc, request);
+    else if (strcmp(command_name, PCID_CMD_RESET) == 0)
+        *result = process_reset_cmd(gc, request);
     else
         return ERROR_NOTFOUND;
 
-- 
2.17.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.