raw/ifpga: remove virtual devices on close
Virtual devices created on ifpga raw device will not be removed
when ifpga device has closed. To avoid resource leak problem,
this patch introduces an ifpga virtual device remove function,
virtual devices will be destroyed after the ifpga raw device closed.
Fixes: ef1e8ede3d
("raw/ifpga: add Intel FPGA bus rawdev driver")
Cc: stable@dpdk.org
Signed-off-by: Wei Huang <wei.huang@intel.com>
Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
Reviewed-by: Rosen Xu <rosen.xu@intel.com>
This commit is contained in:
parent
400e6a64cd
commit
ae835aba40
@ -134,6 +134,8 @@ ifpga_rawdev_allocate(struct rte_rawdev *rawdev)
|
||||
for (i = 0; i < IFPGA_MAX_IRQ; i++)
|
||||
dev->intr_handle[i] = NULL;
|
||||
dev->poll_enabled = 0;
|
||||
for (i = 0; i < IFPGA_MAX_VDEV; i++)
|
||||
dev->vdev_name[i] = NULL;
|
||||
|
||||
return dev;
|
||||
}
|
||||
@ -736,10 +738,22 @@ ifpga_rawdev_stop(struct rte_rawdev *dev)
|
||||
static int
|
||||
ifpga_rawdev_close(struct rte_rawdev *dev)
|
||||
{
|
||||
struct ifpga_rawdev *ifpga_rdev = NULL;
|
||||
struct opae_adapter *adapter;
|
||||
char *vdev_name = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (dev) {
|
||||
ifpga_monitor_stop_func(ifpga_rawdev_get(dev));
|
||||
ifpga_rdev = ifpga_rawdev_get(dev);
|
||||
if (ifpga_rdev) {
|
||||
for (i = 0; i < IFPGA_MAX_VDEV; i++) {
|
||||
vdev_name = ifpga_rdev->vdev_name[i];
|
||||
if (vdev_name)
|
||||
rte_vdev_uninit(vdev_name);
|
||||
}
|
||||
ifpga_monitor_stop_func(ifpga_rdev);
|
||||
ifpga_rdev->rawdev = NULL;
|
||||
}
|
||||
adapter = ifpga_rawdev_get_priv(dev);
|
||||
if (adapter) {
|
||||
opae_adapter_destroy(adapter);
|
||||
@ -1638,8 +1652,6 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev)
|
||||
return -EINVAL;
|
||||
}
|
||||
dev = ifpga_rawdev_get(rawdev);
|
||||
if (dev)
|
||||
dev->rawdev = NULL;
|
||||
|
||||
adapter = ifpga_rawdev_get_priv(rawdev);
|
||||
if (!adapter)
|
||||
@ -1714,73 +1726,118 @@ static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
ifpga_cfg_probe(struct rte_vdev_device *dev)
|
||||
{
|
||||
struct rte_devargs *devargs;
|
||||
struct rte_kvargs *kvlist = NULL;
|
||||
struct rte_rawdev *rawdev = NULL;
|
||||
struct ifpga_rawdev *ifpga_dev;
|
||||
int port;
|
||||
char *name = NULL;
|
||||
char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
|
||||
int ret = -1;
|
||||
|
||||
devargs = dev->device.devargs;
|
||||
static int
|
||||
ifpga_vdev_parse_devargs(struct rte_devargs *devargs,
|
||||
struct ifpga_vdev_args *args)
|
||||
{
|
||||
struct rte_kvargs *kvlist;
|
||||
char *name = NULL;
|
||||
int port = 0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!devargs || !args)
|
||||
return ret;
|
||||
|
||||
kvlist = rte_kvargs_parse(devargs->args, valid_args);
|
||||
if (!kvlist) {
|
||||
IFPGA_RAWDEV_PMD_LOG(ERR, "error when parsing param");
|
||||
goto end;
|
||||
IFPGA_RAWDEV_PMD_ERR("error when parsing devargs");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {
|
||||
if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,
|
||||
&ifpga_rawdev_get_string_arg,
|
||||
&name) < 0) {
|
||||
&ifpga_rawdev_get_string_arg, &name) < 0) {
|
||||
IFPGA_RAWDEV_PMD_ERR("error to parse %s",
|
||||
IFPGA_ARG_NAME);
|
||||
IFPGA_ARG_NAME);
|
||||
goto end;
|
||||
} else {
|
||||
strlcpy(args->bdf, name, sizeof(args->bdf));
|
||||
rte_free(name);
|
||||
}
|
||||
} else {
|
||||
IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus",
|
||||
IFPGA_ARG_NAME);
|
||||
IFPGA_ARG_NAME);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) {
|
||||
if (rte_kvargs_process(kvlist,
|
||||
IFPGA_ARG_PORT,
|
||||
&rte_ifpga_get_integer32_arg,
|
||||
&port) < 0) {
|
||||
if (rte_kvargs_process(kvlist, IFPGA_ARG_PORT,
|
||||
&rte_ifpga_get_integer32_arg, &port) < 0) {
|
||||
IFPGA_RAWDEV_PMD_ERR("error to parse %s",
|
||||
IFPGA_ARG_PORT);
|
||||
goto end;
|
||||
} else {
|
||||
args->port = port;
|
||||
}
|
||||
} else {
|
||||
IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus",
|
||||
IFPGA_ARG_PORT);
|
||||
IFPGA_ARG_PORT);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
if (kvlist)
|
||||
rte_kvargs_free(kvlist);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ifpga_cfg_probe(struct rte_vdev_device *vdev)
|
||||
{
|
||||
struct rte_rawdev *rawdev = NULL;
|
||||
struct ifpga_rawdev *ifpga_dev;
|
||||
struct ifpga_vdev_args args;
|
||||
char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
|
||||
const char *vdev_name = NULL;
|
||||
int i, n, ret = 0;
|
||||
|
||||
vdev_name = rte_vdev_device_name(vdev);
|
||||
if (!vdev_name)
|
||||
return -EINVAL;
|
||||
|
||||
IFPGA_RAWDEV_PMD_INFO("probe ifpga virtual device %s", vdev_name);
|
||||
|
||||
ret = ifpga_vdev_parse_devargs(vdev->device.devargs, &args);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memset(dev_name, 0, sizeof(dev_name));
|
||||
snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", name);
|
||||
snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", args.bdf);
|
||||
rawdev = rte_rawdev_pmd_get_named_dev(dev_name);
|
||||
if (!rawdev)
|
||||
goto end;
|
||||
return -ENODEV;
|
||||
ifpga_dev = ifpga_rawdev_get(rawdev);
|
||||
if (!ifpga_dev)
|
||||
goto end;
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < IFPGA_MAX_VDEV; i++) {
|
||||
if (ifpga_dev->vdev_name[i] == NULL) {
|
||||
n = strlen(vdev_name) + 1;
|
||||
ifpga_dev->vdev_name[i] = rte_malloc(NULL, n, 0);
|
||||
if (ifpga_dev->vdev_name[i] == NULL)
|
||||
return -ENOMEM;
|
||||
strlcpy(ifpga_dev->vdev_name[i], vdev_name, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= IFPGA_MAX_VDEV) {
|
||||
IFPGA_RAWDEV_PMD_ERR("Can't create more virtual device!");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
memset(dev_name, 0, sizeof(dev_name));
|
||||
snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
|
||||
port, name);
|
||||
|
||||
args.port, args.bdf);
|
||||
ret = rte_eal_hotplug_add(RTE_STR(IFPGA_BUS_NAME),
|
||||
dev_name, devargs->args);
|
||||
end:
|
||||
rte_kvargs_free(kvlist);
|
||||
free(name);
|
||||
dev_name, vdev->device.devargs->args);
|
||||
if (ret) {
|
||||
rte_free(ifpga_dev->vdev_name[i]);
|
||||
ifpga_dev->vdev_name[i] = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1788,10 +1845,47 @@ ifpga_cfg_probe(struct rte_vdev_device *dev)
|
||||
static int
|
||||
ifpga_cfg_remove(struct rte_vdev_device *vdev)
|
||||
{
|
||||
IFPGA_RAWDEV_PMD_INFO("Remove ifpga_cfg %p",
|
||||
vdev);
|
||||
struct rte_rawdev *rawdev = NULL;
|
||||
struct ifpga_rawdev *ifpga_dev;
|
||||
struct ifpga_vdev_args args;
|
||||
char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
|
||||
const char *vdev_name = NULL;
|
||||
char *tmp_vdev = NULL;
|
||||
int i, ret = 0;
|
||||
|
||||
return 0;
|
||||
vdev_name = rte_vdev_device_name(vdev);
|
||||
if (!vdev_name)
|
||||
return -EINVAL;
|
||||
|
||||
IFPGA_RAWDEV_PMD_INFO("remove ifpga virtual device %s", vdev_name);
|
||||
|
||||
ret = ifpga_vdev_parse_devargs(vdev->device.devargs, &args);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memset(dev_name, 0, sizeof(dev_name));
|
||||
snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", args.bdf);
|
||||
rawdev = rte_rawdev_pmd_get_named_dev(dev_name);
|
||||
if (!rawdev)
|
||||
return -ENODEV;
|
||||
ifpga_dev = ifpga_rawdev_get(rawdev);
|
||||
if (!ifpga_dev)
|
||||
return -ENODEV;
|
||||
|
||||
snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
|
||||
args.port, args.bdf);
|
||||
ret = rte_eal_hotplug_remove(RTE_STR(IFPGA_BUS_NAME), dev_name);
|
||||
|
||||
for (i = 0; i < IFPGA_MAX_VDEV; i++) {
|
||||
tmp_vdev = ifpga_dev->vdev_name[i];
|
||||
if (tmp_vdev && !strcmp(tmp_vdev, vdev_name)) {
|
||||
free(tmp_vdev);
|
||||
ifpga_dev->vdev_name[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct rte_vdev_driver ifpga_cfg_driver = {
|
||||
|
@ -50,6 +50,7 @@ ifpga_rawdev_get_priv(const struct rte_rawdev *rawdev)
|
||||
|
||||
#define IFPGA_RAWDEV_MSIX_IRQ_NUM 7
|
||||
#define IFPGA_RAWDEV_NUM 32
|
||||
#define IFPGA_MAX_VDEV 4
|
||||
#define IFPGA_MAX_IRQ 12
|
||||
|
||||
struct ifpga_rawdev {
|
||||
@ -64,6 +65,13 @@ struct ifpga_rawdev {
|
||||
void *intr_handle[IFPGA_MAX_IRQ];
|
||||
/* enable monitor thread poll device's sensors or not */
|
||||
int poll_enabled;
|
||||
/* name of virtual devices created on raw device */
|
||||
char *vdev_name[IFPGA_MAX_VDEV];
|
||||
};
|
||||
|
||||
struct ifpga_vdev_args {
|
||||
char bdf[PCI_PRI_STR_SIZE];
|
||||
int port;
|
||||
};
|
||||
|
||||
struct ifpga_rawdev *
|
||||
|
Loading…
Reference in New Issue
Block a user