]> git.droids-corp.org - dpdk.git/commitdiff
bus: add device arguments name parsing
authorXueming Li <xuemingl@nvidia.com>
Tue, 13 Apr 2021 03:14:11 +0000 (03:14 +0000)
committerThomas Monjalon <thomas@monjalon.net>
Thu, 2 Sep 2021 14:58:19 +0000 (16:58 +0200)
For device probe and iterator, devargs name was key information,
parsed by rte_devargs_parse. In legacy parser, devargs name was
extracted after bus name:
  bus:name,kv_arguments,,,
Example:
  pci:83:00.0,arguments,...
  vdev:pcap0,...

To be compatible with legacy parser, this patch introduces new
bus driver API devargs_parse to parse devargs and update devargs name.
If devargs_parse not implemented by bus driver, the new syntax parser
rte_devargs_layers_parse default will resolve devargs name from bus's
"name" argument.

Different bus driver might choose different keys from arguments with
unified format. The PCI bus implementation fills the devargs name with
the "addr" argument, example:
 -a bus=pci,addr=83:00.0/class=eth/driver=mlx5,...
    name: 0000:03:00.0
 -a bus=vdev,name=pcap0/class=eth/driver=pcap,...
    name:pcap0

Signed-off-by: Xueming Li <xuemingl@nvidia.com>
Reviewed-by: Gaetan Rivet <grive@u256.net>
drivers/bus/pci/pci_common.c
drivers/bus/pci/pci_params.c
drivers/bus/pci/private.h
lib/eal/common/eal_common_devargs.c
lib/eal/include/rte_bus.h

index 79a6fcffbd0c15f48f9074e19b478c669125f0d7..3406e03b29119b8d61d2f7a97241240b36b0da5a 100644 (file)
@@ -785,6 +785,7 @@ struct rte_pci_bus rte_pci_bus = {
                .plug = pci_plug,
                .unplug = pci_unplug,
                .parse = pci_parse,
+               .devargs_parse = rte_pci_devargs_parse,
                .dma_map = pci_dma_map,
                .dma_unmap = pci_dma_unmap,
                .get_iommu_class = rte_pci_get_iommu_class,
index 3192e9c967d955aaf3feb1f3503aa30b6578df6d..691b5ea01809db8d535ea6419a71033106f66264 100644 (file)
@@ -7,7 +7,9 @@
 #include <rte_dev.h>
 #include <rte_errno.h>
 #include <rte_kvargs.h>
+#include <rte_devargs.h>
 #include <rte_pci.h>
+#include <rte_debug.h>
 
 #include "private.h"
 
@@ -76,3 +78,48 @@ rte_pci_dev_iterate(const void *start,
        rte_kvargs_free(kvargs);
        return dev;
 }
+
+int
+rte_pci_devargs_parse(struct rte_devargs *da)
+{
+       struct rte_kvargs *kvargs;
+       const char *addr_str;
+       struct rte_pci_addr addr;
+       int ret;
+
+       if (da == NULL)
+               return 0;
+       RTE_ASSERT(da->bus_str != NULL);
+
+       kvargs = rte_kvargs_parse(da->bus_str, NULL);
+       if (kvargs == NULL) {
+               RTE_LOG(ERR, EAL, "cannot parse argument list: %s\n",
+                       da->bus_str);
+               ret = -ENODEV;
+               goto out;
+       }
+
+       addr_str = rte_kvargs_get(kvargs, pci_params_keys[RTE_PCI_PARAM_ADDR]);
+       if (addr_str == NULL) {
+               RTE_LOG(ERR, EAL, "No PCI address specified using '%s=<id>' in: %s\n",
+                       pci_params_keys[RTE_PCI_PARAM_ADDR], da->bus_str);
+               ret = -ENODEV;
+               goto out;
+       }
+
+       ret = rte_pci_addr_parse(addr_str, &addr);
+       if (ret != 0) {
+               RTE_LOG(ERR, EAL, "PCI address invalid: %s\n", da->bus_str);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       rte_pci_device_name(&addr, da->name, sizeof(da->name));
+
+out:
+       if (kvargs != NULL)
+               rte_kvargs_free(kvargs);
+       if (ret != 0)
+               rte_errno = -ret;
+       return ret;
+}
index 4cd9d14ec71a5ada42ca69cb71f8977b736b3db5..0fbef8e1d8588600bc5d683ac2bf2c63473e9b66 100644 (file)
@@ -269,4 +269,18 @@ rte_pci_dev_iterate(const void *start,
                    const char *str,
                    const struct rte_dev_iterator *it);
 
+/*
+ * Parse device arguments and update name.
+ *
+ * @param da
+ *   device arguments to parse.
+ *
+ * @return
+ *   0 on success.
+ *   -EINVAL: kvargs string is invalid and cannot be parsed.
+ *   -ENODEV: no key matching a device ID is found in the kv list.
+ */
+int
+rte_pci_devargs_parse(struct rte_devargs *da);
+
 #endif /* _PCI_PRIVATE_H_ */
index 23aaf8b7e41a5216fbeeb23287b813eae9c66fbf..d0c6d5c2a97976a0e9acc7a55c292bc176469428 100644 (file)
@@ -19,6 +19,7 @@
 #include <rte_kvargs.h>
 #include <rte_log.h>
 #include <rte_tailq.h>
+#include <rte_string_fns.h>
 #include "eal_private.h"
 
 /** user device double-linked queue type definition */
@@ -40,6 +41,28 @@ devargs_layer_count(const char *s)
        return i;
 }
 
+/* Resolve devargs name from bus arguments. */
+static int
+devargs_bus_parse_default(struct rte_devargs *devargs,
+                         struct rte_kvargs *bus_args)
+{
+       const char *name;
+
+       /* Parse devargs name from bus key-value list. */
+       name = rte_kvargs_get(bus_args, "name");
+       if (name == NULL) {
+               RTE_LOG(INFO, EAL, "devargs name not found: %s\n",
+                       devargs->data);
+               return 0;
+       }
+       if (rte_strscpy(devargs->name, name, sizeof(devargs->name)) < 0) {
+               RTE_LOG(ERR, EAL, "devargs name too long: %s\n",
+                       devargs->data);
+               return -E2BIG;
+       }
+       return 0;
+}
+
 int
 rte_devargs_layers_parse(struct rte_devargs *devargs,
                         const char *devstr)
@@ -118,6 +141,8 @@ next_layer:
                if (layers[i].kvlist == NULL)
                        continue;
                kv = &layers[i].kvlist->pairs[0];
+               if (kv->key == NULL)
+                       continue;
                if (strcmp(kv->key, RTE_DEVARGS_KEY_BUS) == 0) {
                        bus = rte_bus_find_by_name(kv->value);
                        if (bus == NULL) {
@@ -160,6 +185,12 @@ next_layer:
                }
        }
 
+       /* Resolve devargs name. */
+       if (bus != NULL && bus->devargs_parse != NULL)
+               ret = bus->devargs_parse(devargs);
+       else if (layers[0].kvlist != NULL)
+               ret = devargs_bus_parse_default(devargs, layers[0].kvlist);
+
 get_out:
        for (i = 0; i < RTE_DIM(layers); i++) {
                if (layers[i].kvlist)
index 80b154fb982c13072544f4342cbcff265ae4ac69..a935ab1be44f0edbe2d603100ec63a0b47377791 100644 (file)
@@ -139,6 +139,22 @@ typedef int (*rte_bus_unplug_t)(struct rte_device *dev);
  */
 typedef int (*rte_bus_parse_t)(const char *name, void *addr);
 
+/**
+ * Parse bus part of the device arguments.
+ *
+ * The field name of the struct rte_devargs will be set.
+ *
+ * @param da
+ *     Pointer to the devargs to parse.
+ *
+ * @return
+ *     0 on successful parsing, otherwise rte_errno is set.
+ *     -EINVAL: on parsing error.
+ *     -ENODEV: if no key matching a device argument is specified.
+ *     -E2BIG: device name is too long.
+ */
+typedef int (*rte_bus_devargs_parse_t)(struct rte_devargs *da);
+
 /**
  * Device level DMA map function.
  * After a successful call, the memory segment will be mapped to the
@@ -258,6 +274,7 @@ struct rte_bus {
        rte_bus_plug_t plug;         /**< Probe single device for drivers */
        rte_bus_unplug_t unplug;     /**< Remove single device from driver */
        rte_bus_parse_t parse;       /**< Parse a device name */
+       rte_bus_devargs_parse_t devargs_parse; /**< Parse bus devargs */
        rte_dev_dma_map_t dma_map;   /**< DMA map for device in the bus */
        rte_dev_dma_unmap_t dma_unmap; /**< DMA unmap for device in the bus */
        struct rte_bus_conf conf;    /**< Bus configuration */