2018-09-19 16:03:31 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
* Copyright 2018 Gaëtan Rivet
|
|
|
|
*/
|
|
|
|
|
eal: remove sys/queue.h from public headers
Currently there are some public headers that include 'sys/queue.h', which
is not POSIX, but usually provided by the Linux/BSD system library.
(Not in POSIX.1, POSIX.1-2001, or POSIX.1-2008. Present on the BSDs.)
The file is missing on Windows. During the Windows build, DPDK uses a
bundled copy, so building a DPDK library works fine. But when OVS or other
applications use DPDK as a library, because some DPDK public headers
include 'sys/queue.h', on Windows, it triggers an error due to no such
file.
One solution is to install the 'lib/eal/windows/include/sys/queue.h' into
Windows environment, such as [1]. However, this means DPDK exports the
functionalities of 'sys/queue.h' into the environment, which might cause
symbols, macros, headers clashing with other applications.
The patch fixes it by removing the "#include <sys/queue.h>" from
DPDK public headers, so programs including DPDK headers don't depend
on the system to provide 'sys/queue.h'. When these public headers use
macros such as TAILQ_xxx, we replace it by the ones with RTE_ prefix.
For Windows, we copy the definitions from <sys/queue.h> to rte_os.h
in Windows EAL. Note that these RTE_ macros are compatible with
<sys/queue.h>, both at the level of API (to use with <sys/queue.h>
macros in C files) and ABI (to avoid breaking it).
Additionally, the TAILQ_FOREACH_SAFE is not part of <sys/queue.h>,
the patch replaces it with RTE_TAILQ_FOREACH_SAFE.
[1] http://mails.dpdk.org/archives/dev/2021-August/216304.html
Suggested-by: Nick Connolly <nick.connolly@mayadata.io>
Suggested-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Signed-off-by: William Tu <u9012063@gmail.com>
Acked-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Acked-by: Narcisa Vasile <navasile@linux.microsoft.com>
2021-08-24 16:21:03 +00:00
|
|
|
#include <sys/queue.h>
|
|
|
|
|
2018-09-19 16:03:31 +00:00
|
|
|
#include <rte_bus.h>
|
2018-09-19 16:03:32 +00:00
|
|
|
#include <rte_bus_pci.h>
|
2018-09-19 16:03:31 +00:00
|
|
|
#include <rte_dev.h>
|
|
|
|
#include <rte_errno.h>
|
|
|
|
#include <rte_kvargs.h>
|
bus: add device arguments name parsing
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>
2021-04-13 03:14:11 +00:00
|
|
|
#include <rte_devargs.h>
|
2018-09-19 16:03:31 +00:00
|
|
|
#include <rte_pci.h>
|
bus: add device arguments name parsing
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>
2021-04-13 03:14:11 +00:00
|
|
|
#include <rte_debug.h>
|
2018-09-19 16:03:31 +00:00
|
|
|
|
|
|
|
#include "private.h"
|
|
|
|
|
|
|
|
enum pci_params {
|
2018-10-03 12:55:11 +00:00
|
|
|
RTE_PCI_PARAM_ADDR,
|
|
|
|
RTE_PCI_PARAM_MAX,
|
2018-09-19 16:03:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const char * const pci_params_keys[] = {
|
2018-10-03 12:55:11 +00:00
|
|
|
[RTE_PCI_PARAM_ADDR] = "addr",
|
|
|
|
[RTE_PCI_PARAM_MAX] = NULL,
|
2018-09-19 16:03:31 +00:00
|
|
|
};
|
|
|
|
|
2018-09-19 16:03:32 +00:00
|
|
|
static int
|
|
|
|
pci_addr_kv_cmp(const char *key __rte_unused,
|
|
|
|
const char *value,
|
|
|
|
void *_addr2)
|
|
|
|
{
|
|
|
|
struct rte_pci_addr _addr1;
|
|
|
|
struct rte_pci_addr *addr1 = &_addr1;
|
|
|
|
struct rte_pci_addr *addr2 = _addr2;
|
|
|
|
|
|
|
|
if (rte_pci_addr_parse(value, addr1))
|
|
|
|
return -1;
|
|
|
|
return -abs(rte_pci_addr_cmp(addr1, addr2));
|
|
|
|
}
|
|
|
|
|
2018-09-19 16:03:31 +00:00
|
|
|
static int
|
|
|
|
pci_dev_match(const struct rte_device *dev,
|
|
|
|
const void *_kvlist)
|
|
|
|
{
|
|
|
|
const struct rte_kvargs *kvlist = _kvlist;
|
2018-09-19 16:03:32 +00:00
|
|
|
const struct rte_pci_device *pdev;
|
2018-09-19 16:03:31 +00:00
|
|
|
|
2018-09-19 16:03:32 +00:00
|
|
|
if (kvlist == NULL)
|
|
|
|
/* Empty string matches everything. */
|
|
|
|
return 0;
|
|
|
|
pdev = RTE_DEV_TO_PCI_CONST(dev);
|
|
|
|
/* if any field does not match. */
|
2018-10-03 12:55:11 +00:00
|
|
|
if (rte_kvargs_process(kvlist, pci_params_keys[RTE_PCI_PARAM_ADDR],
|
2018-09-19 16:03:32 +00:00
|
|
|
&pci_addr_kv_cmp,
|
|
|
|
(void *)(intptr_t)&pdev->addr))
|
|
|
|
return 1;
|
2018-09-19 16:03:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
rte_pci_dev_iterate(const void *start,
|
|
|
|
const char *str,
|
|
|
|
const struct rte_dev_iterator *it __rte_unused)
|
|
|
|
{
|
|
|
|
rte_bus_find_device_t find_device;
|
|
|
|
struct rte_kvargs *kvargs = NULL;
|
|
|
|
struct rte_device *dev;
|
|
|
|
|
|
|
|
if (str != NULL) {
|
|
|
|
kvargs = rte_kvargs_parse(str, pci_params_keys);
|
|
|
|
if (kvargs == NULL) {
|
|
|
|
RTE_LOG(ERR, EAL, "cannot parse argument list\n");
|
|
|
|
rte_errno = EINVAL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
find_device = rte_pci_bus.bus.find_device;
|
|
|
|
dev = find_device(start, pci_dev_match, kvargs);
|
|
|
|
rte_kvargs_free(kvargs);
|
|
|
|
return dev;
|
|
|
|
}
|
bus: add device arguments name parsing
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>
2021-04-13 03:14:11 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|