patches for DPDK stable branches
 help / color / mirror / Atom feed
* [PATCH v1] raw/ifpga: remove vdev when ifpga is closed
@ 2022-03-11  2:39 Wei Huang
  2022-03-15  1:17 ` [PATCH v2] " Wei Huang
  0 siblings, 1 reply; 9+ messages in thread
From: Wei Huang @ 2022-03-11  2:39 UTC (permalink / raw)
  To: dev, thomas, rosen.xu, nipun.gupta, hemant.agrawal
  Cc: stable, tianfei.zhang, qi.z.zhang, ferruh.yigit, Wei Huang

Virtual devices created on ifpga raw device are not removed when
ifpga is closed. To avoid such problem, ifpga virtual device remove
function is implemented, virtual device is removed in raw device
close function.

Signed-off-by: Wei Huang <wei.huang@intel.com>
Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
Acked-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/raw/ifpga/ifpga_rawdev.c | 137 +++++++++++++++++++++++++++++----------
 drivers/raw/ifpga/ifpga_rawdev.h |   8 +++
 2 files changed, 109 insertions(+), 36 deletions(-)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index 26c1366..9f4a3ce 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -134,6 +134,8 @@ struct ifpga_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;
 }
@@ -735,10 +737,24 @@ static int set_surprise_link_check_aer(
 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 (!rte_vdev_uninit(vdev_name)) {
+					rte_free(vdev_name);
+					ifpga_rdev->vdev_name[i] = NULL;
+				}
+			}
+			ifpga_monitor_stop_func(ifpga_rdev);
+			ifpga_rdev->rawdev = NULL;
+		}
 		adapter = ifpga_rawdev_get_priv(dev);
 		if (adapter) {
 			opae_adapter_destroy(adapter);
@@ -1637,8 +1653,6 @@ static int fme_clean_fme_error(struct opae_manager *mgr)
 		return -EINVAL;
 	}
 	dev = ifpga_rawdev_get(rawdev);
-	if (dev)
-		dev->rawdev = NULL;
 
 	adapter = ifpga_rawdev_get_priv(rawdev);
 	if (!adapter)
@@ -1713,73 +1727,113 @@ static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
 
 	return 0;
 }
+
 static int
-ifpga_cfg_probe(struct rte_vdev_device *dev)
+ifpga_vdev_parse_devargs(struct rte_devargs *devargs,
+	struct ifpga_vdev_args *args)
 {
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	struct rte_rawdev *rawdev = NULL;
-	struct ifpga_rawdev *ifpga_dev;
-	int port;
+	struct rte_kvargs *kvlist;
 	char *name = NULL;
-	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
-	int ret = -1;
+	int port = 0;
+	int ret = -EINVAL;
 
-	devargs = dev->device.devargs;
+	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];
+	int i, n, ret = 0;
+
+	IFPGA_RAWDEV_PMD_INFO("probe ifpga_rawdev_cfg %s", vdev->device.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;
 
-	memset(dev_name, 0, sizeof(dev_name));
-	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
-	port, name);
+	for (i = 0; i < IFPGA_MAX_VDEV; i++) {
+		if (ifpga_dev->vdev_name[i] == NULL) {
+			n = strlen(vdev->device.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->device.name, n);
+			break;
+		}
+	}
+
+	if (i >= IFPGA_MAX_VDEV) {
+		IFPGA_RAWDEV_PMD_ERR("Can't create more virtual device!");
+		return -ENOENT;
+	}
 
+	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
+		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;
 }
@@ -1787,10 +1841,21 @@ static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
 static int
 ifpga_cfg_remove(struct rte_vdev_device *vdev)
 {
-	IFPGA_RAWDEV_PMD_INFO("Remove ifpga_cfg %p",
-		vdev);
+	struct ifpga_vdev_args args;
+	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
+	int ret = 0;
 
-	return 0;
+	IFPGA_RAWDEV_PMD_INFO("remove ifpga_rawdev_cfg %s", vdev->device.name);
+
+	ret = ifpga_vdev_parse_devargs(vdev->device.devargs, &args);
+	if (ret)
+		return ret;
+
+	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);
+
+	return ret;
 }
 
 static struct rte_vdev_driver ifpga_cfg_driver = {
diff --git a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
index 857b734..eb9a9a5 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.h
+++ b/drivers/raw/ifpga/ifpga_rawdev.h
@@ -50,6 +50,7 @@ enum ifpga_rawdev_device_state {
 
 #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[8];
+	int port;
 };
 
 struct ifpga_rawdev *
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] raw/ifpga: remove vdev when ifpga is closed
  2022-03-11  2:39 [PATCH v1] raw/ifpga: remove vdev when ifpga is closed Wei Huang
@ 2022-03-15  1:17 ` Wei Huang
  2022-03-18  8:57   ` [PATCH v3] " Wei Huang
  0 siblings, 1 reply; 9+ messages in thread
From: Wei Huang @ 2022-03-15  1:17 UTC (permalink / raw)
  To: dev, thomas, rosen.xu, nipun.gupta, hemant.agrawal
  Cc: stable, tianfei.zhang, qi.z.zhang, ferruh.yigit, Wei Huang

Virtual devices created on ifpga raw device are not removed when
ifpga is closed. To avoid such problem, ifpga virtual device remove
function is implemented, virtual device is removed in raw device
close function.

Signed-off-by: Wei Huang <wei.huang@intel.com>
Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
Acked-by: Rosen Xu <rosen.xu@intel.com>
---
v2: cleanup vdev_name no matter rte_vdev_uninit succeed or not
---
 drivers/raw/ifpga/ifpga_rawdev.c | 138 +++++++++++++++++++++++++++++----------
 drivers/raw/ifpga/ifpga_rawdev.h |   8 +++
 2 files changed, 110 insertions(+), 36 deletions(-)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index 26c1366..eac0b90 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -134,6 +134,8 @@ struct ifpga_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;
 }
@@ -735,10 +737,25 @@ static int set_surprise_link_check_aer(
 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);
+					rte_free(vdev_name);
+					ifpga_rdev->vdev_name[i] = NULL;
+				}
+			}
+			ifpga_monitor_stop_func(ifpga_rdev);
+			ifpga_rdev->rawdev = NULL;
+		}
 		adapter = ifpga_rawdev_get_priv(dev);
 		if (adapter) {
 			opae_adapter_destroy(adapter);
@@ -1637,8 +1654,6 @@ static int fme_clean_fme_error(struct opae_manager *mgr)
 		return -EINVAL;
 	}
 	dev = ifpga_rawdev_get(rawdev);
-	if (dev)
-		dev->rawdev = NULL;
 
 	adapter = ifpga_rawdev_get_priv(rawdev);
 	if (!adapter)
@@ -1713,73 +1728,113 @@ static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
 
 	return 0;
 }
+
 static int
-ifpga_cfg_probe(struct rte_vdev_device *dev)
+ifpga_vdev_parse_devargs(struct rte_devargs *devargs,
+	struct ifpga_vdev_args *args)
 {
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	struct rte_rawdev *rawdev = NULL;
-	struct ifpga_rawdev *ifpga_dev;
-	int port;
+	struct rte_kvargs *kvlist;
 	char *name = NULL;
-	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
-	int ret = -1;
+	int port = 0;
+	int ret = -EINVAL;
 
-	devargs = dev->device.devargs;
+	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];
+	int i, n, ret = 0;
+
+	IFPGA_RAWDEV_PMD_INFO("probe ifpga_rawdev_cfg %s", vdev->device.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;
 
-	memset(dev_name, 0, sizeof(dev_name));
-	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
-	port, name);
+	for (i = 0; i < IFPGA_MAX_VDEV; i++) {
+		if (ifpga_dev->vdev_name[i] == NULL) {
+			n = strlen(vdev->device.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->device.name, n);
+			break;
+		}
+	}
+
+	if (i >= IFPGA_MAX_VDEV) {
+		IFPGA_RAWDEV_PMD_ERR("Can't create more virtual device!");
+		return -ENOENT;
+	}
 
+	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
+		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;
 }
@@ -1787,10 +1842,21 @@ static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
 static int
 ifpga_cfg_remove(struct rte_vdev_device *vdev)
 {
-	IFPGA_RAWDEV_PMD_INFO("Remove ifpga_cfg %p",
-		vdev);
+	struct ifpga_vdev_args args;
+	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
+	int ret = 0;
 
-	return 0;
+	IFPGA_RAWDEV_PMD_INFO("remove ifpga_rawdev_cfg %s", vdev->device.name);
+
+	ret = ifpga_vdev_parse_devargs(vdev->device.devargs, &args);
+	if (ret)
+		return ret;
+
+	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);
+
+	return ret;
 }
 
 static struct rte_vdev_driver ifpga_cfg_driver = {
diff --git a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
index 857b734..eb9a9a5 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.h
+++ b/drivers/raw/ifpga/ifpga_rawdev.h
@@ -50,6 +50,7 @@ enum ifpga_rawdev_device_state {
 
 #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[8];
+	int port;
 };
 
 struct ifpga_rawdev *
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
  2022-03-15  1:17 ` [PATCH v2] " Wei Huang
@ 2022-03-18  8:57   ` Wei Huang
  2022-03-29  1:55     ` Huang, Wei
  2022-04-21  1:34     ` [PATCH v4] " Wei Huang
  0 siblings, 2 replies; 9+ messages in thread
From: Wei Huang @ 2022-03-18  8:57 UTC (permalink / raw)
  To: dev, thomas, rosen.xu, nipun.gupta, hemant.agrawal
  Cc: stable, tianfei.zhang, qi.z.zhang, ferruh.yigit, Wei Huang

Virtual devices created on ifpga raw device are not removed when
ifpga is closed. To avoid such problem, ifpga virtual device remove
function is implemented, virtual device is removed in raw device
close function.

Signed-off-by: Wei Huang <wei.huang@intel.com>
Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
Acked-by: Rosen Xu <rosen.xu@intel.com>
---
v2: cleanup vdev_name no matter rte_vdev_uninit succeed or not
---
v3: cleanup vdev_name in ifpga_cfg_remove
---
 drivers/raw/ifpga/ifpga_rawdev.c | 166 ++++++++++++++++++++++++++++++---------
 drivers/raw/ifpga/ifpga_rawdev.h |   8 ++
 2 files changed, 138 insertions(+), 36 deletions(-)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index 6d4117c..fe3fc43 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -134,6 +134,8 @@ struct ifpga_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 @@ static int set_surprise_link_check_aer(
 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 @@ static int fme_clean_fme_error(struct opae_manager *mgr)
 		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)
+ifpga_vdev_parse_devargs(struct rte_devargs *devargs,
+	struct ifpga_vdev_args *args)
 {
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	struct rte_rawdev *rawdev = NULL;
-	struct ifpga_rawdev *ifpga_dev;
-	int port;
+	struct rte_kvargs *kvlist;
 	char *name = NULL;
-	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
-	int ret = -1;
+	int port = 0;
+	int ret = -EINVAL;
 
-	devargs = dev->device.devargs;
+	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;
 
-	memset(dev_name, 0, sizeof(dev_name));
-	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
-	port, name);
+	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;
+	}
+
+	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
+		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 @@ static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
 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 = {
diff --git a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
index 857b734..eb9a9a5 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.h
+++ b/drivers/raw/ifpga/ifpga_rawdev.h
@@ -50,6 +50,7 @@ enum ifpga_rawdev_device_state {
 
 #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[8];
+	int port;
 };
 
 struct ifpga_rawdev *
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
  2022-03-18  8:57   ` [PATCH v3] " Wei Huang
@ 2022-03-29  1:55     ` Huang, Wei
  2022-03-29  2:14       ` Zhang, Qi Z
  2022-04-21  1:34     ` [PATCH v4] " Wei Huang
  1 sibling, 1 reply; 9+ messages in thread
From: Huang, Wei @ 2022-03-29  1:55 UTC (permalink / raw)
  To: dev, thomas, Xu, Rosen, nipun.gupta, hemant.agrawal
  Cc: stable, Zhang, Tianfei, Zhang, Qi Z, Yigit, Ferruh

Hi Thomas,

Would you please check this patch is acceptable ?

> -----Original Message-----
> From: Huang, Wei <wei.huang@intel.com>
> Sent: Friday, March 18, 2022 16:58
> To: dev@dpdk.org; thomas@monjalon.net; Xu, Rosen
> <rosen.xu@intel.com>; nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Huang, Wei
> <wei.huang@intel.com>
> Subject: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> 
> Virtual devices created on ifpga raw device are not removed when ifpga is
> closed. To avoid such problem, ifpga virtual device remove function is
> implemented, virtual device is removed in raw device close function.
> 
> Signed-off-by: Wei Huang <wei.huang@intel.com>
> Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
> Acked-by: Rosen Xu <rosen.xu@intel.com>
> ---
> v2: cleanup vdev_name no matter rte_vdev_uninit succeed or not
> ---
> v3: cleanup vdev_name in ifpga_cfg_remove
> ---
>  drivers/raw/ifpga/ifpga_rawdev.c | 166
> ++++++++++++++++++++++++++++++---------
>  drivers/raw/ifpga/ifpga_rawdev.h |   8 ++
>  2 files changed, 138 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/raw/ifpga/ifpga_rawdev.c
> b/drivers/raw/ifpga/ifpga_rawdev.c
> index 6d4117c..fe3fc43 100644
> --- a/drivers/raw/ifpga/ifpga_rawdev.c
> +++ b/drivers/raw/ifpga/ifpga_rawdev.c
> @@ -134,6 +134,8 @@ struct ifpga_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 @@ static int set_surprise_link_check_aer(  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 @@ static int fme_clean_fme_error(struct
> opae_manager *mgr)
>  		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)
> +ifpga_vdev_parse_devargs(struct rte_devargs *devargs,
> +	struct ifpga_vdev_args *args)
>  {
> -	struct rte_devargs *devargs;
> -	struct rte_kvargs *kvlist = NULL;
> -	struct rte_rawdev *rawdev = NULL;
> -	struct ifpga_rawdev *ifpga_dev;
> -	int port;
> +	struct rte_kvargs *kvlist;
>  	char *name = NULL;
> -	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
> -	int ret = -1;
> +	int port = 0;
> +	int ret = -EINVAL;
> 
> -	devargs = dev->device.devargs;
> +	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;
> 
> -	memset(dev_name, 0, sizeof(dev_name));
> -	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
> -	port, name);
> +	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;
> +	}
> +
> +	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
> +		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 @@ static int ifpga_rawdev_get_string_arg(const
> char *key __rte_unused,  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 = { diff --git
> a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
> index 857b734..eb9a9a5 100644
> --- a/drivers/raw/ifpga/ifpga_rawdev.h
> +++ b/drivers/raw/ifpga/ifpga_rawdev.h
> @@ -50,6 +50,7 @@ enum ifpga_rawdev_device_state {
> 
>  #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[8];
> +	int port;
>  };
> 
>  struct ifpga_rawdev *
> --
> 1.8.3.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
  2022-03-29  1:55     ` Huang, Wei
@ 2022-03-29  2:14       ` Zhang, Qi Z
  2022-03-29  2:19         ` Huang, Wei
                           ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Zhang, Qi Z @ 2022-03-29  2:14 UTC (permalink / raw)
  To: Huang, Wei, dev, thomas, Xu, Rosen, nipun.gupta, hemant.agrawal
  Cc: stable, Zhang, Tianfei, Yigit, Ferruh


> -----Original Message-----
> From: Huang, Wei <wei.huang@intel.com>
> Sent: Tuesday, March 29, 2022 9:56 AM
> To: dev@dpdk.org; thomas@monjalon.net; Xu, Rosen
> <rosen.xu@intel.com>; nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> 
> Hi Thomas,
> 
> Would you please check this patch is acceptable ?

Hi Wei:
	22.07 cycle just begins, It may not necessary to push PMD merge quite early 😊
	Below is the roadmap for your reference

http://core.dpdk.org/roadmap/

Proposal deadline (RFC/v1 patches): 10 April 2022
API freeze (-rc1): 30 May 2022
PMD features freeze (-rc2): 20 June 2022
Builtin applications features freeze (-rc3): 27 June 2022
Release: 13 July 2022

Regards
Qi

> 
> > -----Original Message-----
> > From: Huang, Wei <wei.huang@intel.com>
> > Sent: Friday, March 18, 2022 16:58
> > To: dev@dpdk.org; thomas@monjalon.net; Xu, Rosen
> <rosen.xu@intel.com>;
> > nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> > Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>; Zhang,
> > Qi Z <qi.z.zhang@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> > Huang, Wei <wei.huang@intel.com>
> > Subject: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> >
> > Virtual devices created on ifpga raw device are not removed when ifpga
> > is closed. To avoid such problem, ifpga virtual device remove function
> > is implemented, virtual device is removed in raw device close function.
> >
> > Signed-off-by: Wei Huang <wei.huang@intel.com>
> > Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
> > Acked-by: Rosen Xu <rosen.xu@intel.com>
> > ---
> > v2: cleanup vdev_name no matter rte_vdev_uninit succeed or not
> > ---
> > v3: cleanup vdev_name in ifpga_cfg_remove
> > ---
> >  drivers/raw/ifpga/ifpga_rawdev.c | 166
> > ++++++++++++++++++++++++++++++---------
> >  drivers/raw/ifpga/ifpga_rawdev.h |   8 ++
> >  2 files changed, 138 insertions(+), 36 deletions(-)
> >
> > diff --git a/drivers/raw/ifpga/ifpga_rawdev.c
> > b/drivers/raw/ifpga/ifpga_rawdev.c
> > index 6d4117c..fe3fc43 100644
> > --- a/drivers/raw/ifpga/ifpga_rawdev.c
> > +++ b/drivers/raw/ifpga/ifpga_rawdev.c
> > @@ -134,6 +134,8 @@ struct ifpga_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 @@ static int set_surprise_link_check_aer(  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 @@ static int fme_clean_fme_error(struct
> > opae_manager *mgr)
> >  		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)
> > +ifpga_vdev_parse_devargs(struct rte_devargs *devargs,
> > +	struct ifpga_vdev_args *args)
> >  {
> > -	struct rte_devargs *devargs;
> > -	struct rte_kvargs *kvlist = NULL;
> > -	struct rte_rawdev *rawdev = NULL;
> > -	struct ifpga_rawdev *ifpga_dev;
> > -	int port;
> > +	struct rte_kvargs *kvlist;
> >  	char *name = NULL;
> > -	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
> > -	int ret = -1;
> > +	int port = 0;
> > +	int ret = -EINVAL;
> >
> > -	devargs = dev->device.devargs;
> > +	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;
> >
> > -	memset(dev_name, 0, sizeof(dev_name));
> > -	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
> > -	port, name);
> > +	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;
> > +	}
> > +
> > +	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
> > +		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 @@ static int ifpga_rawdev_get_string_arg(const
> > char *key __rte_unused,  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 = { diff --git
> > a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
> > index 857b734..eb9a9a5 100644
> > --- a/drivers/raw/ifpga/ifpga_rawdev.h
> > +++ b/drivers/raw/ifpga/ifpga_rawdev.h
> > @@ -50,6 +50,7 @@ enum ifpga_rawdev_device_state {
> >
> >  #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[8];
> > +	int port;
> >  };
> >
> >  struct ifpga_rawdev *
> > --
> > 1.8.3.1
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
  2022-03-29  2:14       ` Zhang, Qi Z
@ 2022-03-29  2:19         ` Huang, Wei
  2022-04-13  6:36         ` Huang, Wei
  2022-04-20  9:32         ` Huang, Wei
  2 siblings, 0 replies; 9+ messages in thread
From: Huang, Wei @ 2022-03-29  2:19 UTC (permalink / raw)
  To: Zhang, Qi Z, dev, thomas, Xu, Rosen, nipun.gupta, hemant.agrawal
  Cc: stable, Zhang, Tianfei, Yigit, Ferruh

Got it, thanks.

> -----Original Message-----
> From: Zhang, Qi Z <qi.z.zhang@intel.com>
> Sent: Tuesday, March 29, 2022 10:15
> To: Huang, Wei <wei.huang@intel.com>; dev@dpdk.org;
> thomas@monjalon.net; Xu, Rosen <rosen.xu@intel.com>;
> nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>; Yigit, Ferruh
> <ferruh.yigit@intel.com>
> Subject: RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> 
> 
> > -----Original Message-----
> > From: Huang, Wei <wei.huang@intel.com>
> > Sent: Tuesday, March 29, 2022 9:56 AM
> > To: dev@dpdk.org; thomas@monjalon.net; Xu, Rosen
> <rosen.xu@intel.com>;
> > nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> > Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>; Zhang,
> > Qi Z <qi.z.zhang@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> > Subject: RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> >
> > Hi Thomas,
> >
> > Would you please check this patch is acceptable ?
> 
> Hi Wei:
> 22.07 cycle just begins, It may not necessary to push PMD merge quite early
> 😊
> Below is the roadmap for your reference
> 
> http://core.dpdk.org/roadmap/
> 
> Proposal deadline (RFC/v1 patches): 10 April 2022 API freeze (-rc1): 30 May
> 2022 PMD features freeze (-rc2): 20 June 2022 Builtin applications features
> freeze (-rc3): 27 June 2022
> Release: 13 July 2022
> 
> Regards
> Qi
> 
> >
> > > -----Original Message-----
> > > From: Huang, Wei <wei.huang@intel.com>
> > > Sent: Friday, March 18, 2022 16:58
> > > To: dev@dpdk.org; thomas@monjalon.net; Xu, Rosen
> > <rosen.xu@intel.com>;
> > > nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> > > Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>;
> > > Zhang, Qi Z <qi.z.zhang@intel.com>; Yigit, Ferruh
> > > <ferruh.yigit@intel.com>; Huang, Wei <wei.huang@intel.com>
> > > Subject: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> > >
> > > Virtual devices created on ifpga raw device are not removed when
> > > ifpga is closed. To avoid such problem, ifpga virtual device remove
> > > function is implemented, virtual device is removed in raw device close
> function.
> > >
> > > Signed-off-by: Wei Huang <wei.huang@intel.com>
> > > Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
> > > Acked-by: Rosen Xu <rosen.xu@intel.com>
> > > ---
> > > v2: cleanup vdev_name no matter rte_vdev_uninit succeed or not
> > > ---
> > > v3: cleanup vdev_name in ifpga_cfg_remove
> > > ---
> > >  drivers/raw/ifpga/ifpga_rawdev.c | 166
> > > ++++++++++++++++++++++++++++++---------
> > >  drivers/raw/ifpga/ifpga_rawdev.h |   8 ++
> > >  2 files changed, 138 insertions(+), 36 deletions(-)
> > >
> > > diff --git a/drivers/raw/ifpga/ifpga_rawdev.c
> > > b/drivers/raw/ifpga/ifpga_rawdev.c
> > > index 6d4117c..fe3fc43 100644
> > > --- a/drivers/raw/ifpga/ifpga_rawdev.c
> > > +++ b/drivers/raw/ifpga/ifpga_rawdev.c
> > > @@ -134,6 +134,8 @@ struct ifpga_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 @@ static int set_surprise_link_check_aer(
> > > 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 @@ static int
> > > fme_clean_fme_error(struct opae_manager *mgr)  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)
> > > +ifpga_vdev_parse_devargs(struct rte_devargs *devargs, struct
> > > +ifpga_vdev_args *args)
> > >  {
> > > -struct rte_devargs *devargs;
> > > -struct rte_kvargs *kvlist = NULL;
> > > -struct rte_rawdev *rawdev = NULL;
> > > -struct ifpga_rawdev *ifpga_dev;
> > > -int port;
> > > +struct rte_kvargs *kvlist;
> > >  char *name = NULL;
> > > -char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
> > > -int ret = -1;
> > > +int port = 0;
> > > +int ret = -EINVAL;
> > >
> > > -devargs = dev->device.devargs;
> > > +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;
> > >
> > > -memset(dev_name, 0, sizeof(dev_name)); -snprintf(dev_name,
> > > RTE_RAWDEV_NAME_MAX_LEN, "%d|%s", -port, name);
> > > +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;
> > > +}
> > > +
> > > +snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
> 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 @@ static int ifpga_rawdev_get_string_arg(const
> > > char *key __rte_unused,  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 = { diff --git
> > > a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
> > > index 857b734..eb9a9a5 100644
> > > --- a/drivers/raw/ifpga/ifpga_rawdev.h
> > > +++ b/drivers/raw/ifpga/ifpga_rawdev.h
> > > @@ -50,6 +50,7 @@ enum ifpga_rawdev_device_state {
> > >
> > >  #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[8];
> > > +int port;
> > >  };
> > >
> > >  struct ifpga_rawdev *
> > > --
> > > 1.8.3.1
> >
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
  2022-03-29  2:14       ` Zhang, Qi Z
  2022-03-29  2:19         ` Huang, Wei
@ 2022-04-13  6:36         ` Huang, Wei
  2022-04-20  9:32         ` Huang, Wei
  2 siblings, 0 replies; 9+ messages in thread
From: Huang, Wei @ 2022-04-13  6:36 UTC (permalink / raw)
  To: Zhang, Qi Z, thomas
  Cc: stable, Xu, Rosen, nipun.gupta, hemant.agrawal, Zhang, Tianfei,
	Yigit, Ferruh

Hi Thomas,

Sorry to disturb you, I just want to know when this patch can be reviewed and merged, it may impact DPDK22.07 epic 'intel AFU PMD based on rawdev'.

> -----Original Message-----
> From: Zhang, Qi Z <qi.z.zhang@intel.com>
> Sent: Tuesday, March 29, 2022 10:15
> To: Huang, Wei <wei.huang@intel.com>; dev@dpdk.org;
> thomas@monjalon.net; Xu, Rosen <rosen.xu@intel.com>;
> nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>; Yigit, Ferruh
> <ferruh.yigit@intel.com>
> Subject: RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> 
> 
> > -----Original Message-----
> > From: Huang, Wei <wei.huang@intel.com>
> > Sent: Tuesday, March 29, 2022 9:56 AM
> > To: dev@dpdk.org; thomas@monjalon.net; Xu, Rosen
> <rosen.xu@intel.com>;
> > nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> > Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>; Zhang,
> > Qi Z <qi.z.zhang@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> > Subject: RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> >
> > Hi Thomas,
> >
> > Would you please check this patch is acceptable ?
> 
> Hi Wei:
> 22.07 cycle just begins, It may not necessary to push PMD merge quite early
> 😊
> Below is the roadmap for your reference
> 
> http://core.dpdk.org/roadmap/
> 
> Proposal deadline (RFC/v1 patches): 10 April 2022 API freeze (-rc1): 30 May
> 2022 PMD features freeze (-rc2): 20 June 2022 Builtin applications features
> freeze (-rc3): 27 June 2022
> Release: 13 July 2022
> 
> Regards
> Qi
> 
> >
> > > -----Original Message-----
> > > From: Huang, Wei <wei.huang@intel.com>
> > > Sent: Friday, March 18, 2022 16:58
> > > To: dev@dpdk.org; thomas@monjalon.net; Xu, Rosen
> > <rosen.xu@intel.com>;
> > > nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> > > Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>;
> > > Zhang, Qi Z <qi.z.zhang@intel.com>; Yigit, Ferruh
> > > <ferruh.yigit@intel.com>; Huang, Wei <wei.huang@intel.com>
> > > Subject: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> > >
> > > Virtual devices created on ifpga raw device are not removed when
> > > ifpga is closed. To avoid such problem, ifpga virtual device remove
> > > function is implemented, virtual device is removed in raw device close
> function.
> > >
> > > Signed-off-by: Wei Huang <wei.huang@intel.com>
> > > Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
> > > Acked-by: Rosen Xu <rosen.xu@intel.com>
> > > ---
> > > v2: cleanup vdev_name no matter rte_vdev_uninit succeed or not
> > > ---
> > > v3: cleanup vdev_name in ifpga_cfg_remove
> > > ---
> > >  drivers/raw/ifpga/ifpga_rawdev.c | 166
> > > ++++++++++++++++++++++++++++++---------
> > >  drivers/raw/ifpga/ifpga_rawdev.h |   8 ++
> > >  2 files changed, 138 insertions(+), 36 deletions(-)
> > >
> > > diff --git a/drivers/raw/ifpga/ifpga_rawdev.c
> > > b/drivers/raw/ifpga/ifpga_rawdev.c
> > > index 6d4117c..fe3fc43 100644
> > > --- a/drivers/raw/ifpga/ifpga_rawdev.c
> > > +++ b/drivers/raw/ifpga/ifpga_rawdev.c
> > > @@ -134,6 +134,8 @@ struct ifpga_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 @@ static int set_surprise_link_check_aer(
> > > 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 @@ static int
> > > fme_clean_fme_error(struct opae_manager *mgr)  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)
> > > +ifpga_vdev_parse_devargs(struct rte_devargs *devargs, struct
> > > +ifpga_vdev_args *args)
> > >  {
> > > -struct rte_devargs *devargs;
> > > -struct rte_kvargs *kvlist = NULL;
> > > -struct rte_rawdev *rawdev = NULL;
> > > -struct ifpga_rawdev *ifpga_dev;
> > > -int port;
> > > +struct rte_kvargs *kvlist;
> > >  char *name = NULL;
> > > -char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
> > > -int ret = -1;
> > > +int port = 0;
> > > +int ret = -EINVAL;
> > >
> > > -devargs = dev->device.devargs;
> > > +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;
> > >
> > > -memset(dev_name, 0, sizeof(dev_name)); -snprintf(dev_name,
> > > RTE_RAWDEV_NAME_MAX_LEN, "%d|%s", -port, name);
> > > +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;
> > > +}
> > > +
> > > +snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
> 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 @@ static int ifpga_rawdev_get_string_arg(const
> > > char *key __rte_unused,  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 = { diff --git
> > > a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
> > > index 857b734..eb9a9a5 100644
> > > --- a/drivers/raw/ifpga/ifpga_rawdev.h
> > > +++ b/drivers/raw/ifpga/ifpga_rawdev.h
> > > @@ -50,6 +50,7 @@ enum ifpga_rawdev_device_state {
> > >
> > >  #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[8];
> > > +int port;
> > >  };
> > >
> > >  struct ifpga_rawdev *
> > > --
> > > 1.8.3.1
> >
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
  2022-03-29  2:14       ` Zhang, Qi Z
  2022-03-29  2:19         ` Huang, Wei
  2022-04-13  6:36         ` Huang, Wei
@ 2022-04-20  9:32         ` Huang, Wei
  2 siblings, 0 replies; 9+ messages in thread
From: Huang, Wei @ 2022-04-20  9:32 UTC (permalink / raw)
  To: Zhang, Qi Z, dev, thomas, Xu, Rosen, nipun.gupta, hemant.agrawal
  Cc: stable, Zhang, Tianfei, Yigit, Ferruh

> -----Original Message-----
> From: Zhang, Qi Z <qi.z.zhang@intel.com>
> Sent: Tuesday, March 29, 2022 10:15
> To: Huang, Wei <wei.huang@intel.com>; dev@dpdk.org;
> thomas@monjalon.net; Xu, Rosen <rosen.xu@intel.com>;
> nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>; Yigit, Ferruh
> <ferruh.yigit@intel.com>
> Subject: RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> 
> 
> > -----Original Message-----
> > From: Huang, Wei <wei.huang@intel.com>
> > Sent: Tuesday, March 29, 2022 9:56 AM
> > To: dev@dpdk.org; thomas@monjalon.net; Xu, Rosen
> <rosen.xu@intel.com>;
> > nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> > Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>; Zhang,
> > Qi Z <qi.z.zhang@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> > Subject: RE: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> >
> > Hi Thomas,
> >
> > Would you please check this patch is acceptable ?
> 
> Hi Wei:
> 22.07 cycle just begins, It may not necessary to push PMD merge quite early
> 😊
> Below is the roadmap for your reference
> 
> http://core.dpdk.org/roadmap/
> 
> Proposal deadline (RFC/v1 patches): 10 April 2022 API freeze (-rc1): 30 May
> 2022 PMD features freeze (-rc2): 20 June 2022 Builtin applications features
> freeze (-rc3): 27 June 2022
> Release: 13 July 2022
> 
> Regards
> Qi
> 
Hi Qi and Thomas,
This patch is not new feature, it's a fix, can it be merged now ? 
> >
> > > -----Original Message-----
> > > From: Huang, Wei <wei.huang@intel.com>
> > > Sent: Friday, March 18, 2022 16:58
> > > To: dev@dpdk.org; thomas@monjalon.net; Xu, Rosen
> > <rosen.xu@intel.com>;
> > > nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> > > Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>;
> > > Zhang, Qi Z <qi.z.zhang@intel.com>; Yigit, Ferruh
> > > <ferruh.yigit@intel.com>; Huang, Wei <wei.huang@intel.com>
> > > Subject: [PATCH v3] raw/ifpga: remove vdev when ifpga is closed
> > >
> > > Virtual devices created on ifpga raw device are not removed when
> > > ifpga is closed. To avoid such problem, ifpga virtual device remove
> > > function is implemented, virtual device is removed in raw device close
> function.
> > >
> > > Signed-off-by: Wei Huang <wei.huang@intel.com>
> > > Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
> > > Acked-by: Rosen Xu <rosen.xu@intel.com>
> > > ---
> > > v2: cleanup vdev_name no matter rte_vdev_uninit succeed or not
> > > ---
> > > v3: cleanup vdev_name in ifpga_cfg_remove
> > > ---
> > >  drivers/raw/ifpga/ifpga_rawdev.c | 166
> > > ++++++++++++++++++++++++++++++---------
> > >  drivers/raw/ifpga/ifpga_rawdev.h |   8 ++
> > >  2 files changed, 138 insertions(+), 36 deletions(-)
> > >
> > > diff --git a/drivers/raw/ifpga/ifpga_rawdev.c
> > > b/drivers/raw/ifpga/ifpga_rawdev.c
> > > index 6d4117c..fe3fc43 100644
> > > --- a/drivers/raw/ifpga/ifpga_rawdev.c
> > > +++ b/drivers/raw/ifpga/ifpga_rawdev.c
> > > @@ -134,6 +134,8 @@ struct ifpga_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 @@ static int set_surprise_link_check_aer(
> > > 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 @@ static int
> > > fme_clean_fme_error(struct opae_manager *mgr)  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)
> > > +ifpga_vdev_parse_devargs(struct rte_devargs *devargs, struct
> > > +ifpga_vdev_args *args)
> > >  {
> > > -struct rte_devargs *devargs;
> > > -struct rte_kvargs *kvlist = NULL;
> > > -struct rte_rawdev *rawdev = NULL;
> > > -struct ifpga_rawdev *ifpga_dev;
> > > -int port;
> > > +struct rte_kvargs *kvlist;
> > >  char *name = NULL;
> > > -char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
> > > -int ret = -1;
> > > +int port = 0;
> > > +int ret = -EINVAL;
> > >
> > > -devargs = dev->device.devargs;
> > > +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;
> > >
> > > -memset(dev_name, 0, sizeof(dev_name)); -snprintf(dev_name,
> > > RTE_RAWDEV_NAME_MAX_LEN, "%d|%s", -port, name);
> > > +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;
> > > +}
> > > +
> > > +snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
> 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 @@ static int ifpga_rawdev_get_string_arg(const
> > > char *key __rte_unused,  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 = { diff --git
> > > a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
> > > index 857b734..eb9a9a5 100644
> > > --- a/drivers/raw/ifpga/ifpga_rawdev.h
> > > +++ b/drivers/raw/ifpga/ifpga_rawdev.h
> > > @@ -50,6 +50,7 @@ enum ifpga_rawdev_device_state {
> > >
> > >  #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[8];
> > > +int port;
> > >  };
> > >
> > >  struct ifpga_rawdev *
> > > --
> > > 1.8.3.1
> >
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v4] raw/ifpga: remove vdev when ifpga is closed
  2022-03-18  8:57   ` [PATCH v3] " Wei Huang
  2022-03-29  1:55     ` Huang, Wei
@ 2022-04-21  1:34     ` Wei Huang
  1 sibling, 0 replies; 9+ messages in thread
From: Wei Huang @ 2022-04-21  1:34 UTC (permalink / raw)
  To: dev, thomas, rosen.xu, nipun.gupta, hemant.agrawal
  Cc: stable, tianfei.zhang, qi.z.zhang, Wei Huang

Virtual devices created on ifpga raw device are not removed when
ifpga is closed. To avoid such problem, ifpga virtual device remove
function is implemented, virtual device is removed in raw device
close function.

Fixes: ef1e8ede3da5 ("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>
Acked-by: Rosen Xu <rosen.xu@intel.com>
---
v2: cleanup vdev_name no matter rte_vdev_uninit succeed or not
---
v3: cleanup vdev_name in ifpga_cfg_remove
---
v4: add fix information in log
---
 drivers/raw/ifpga/ifpga_rawdev.c | 166 ++++++++++++++++++++++++++++++---------
 drivers/raw/ifpga/ifpga_rawdev.h |   8 ++
 2 files changed, 138 insertions(+), 36 deletions(-)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index 6d4117c..fe3fc43 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -134,6 +134,8 @@ struct ifpga_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 @@ static int set_surprise_link_check_aer(
 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 @@ static int fme_clean_fme_error(struct opae_manager *mgr)
 		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)
+ifpga_vdev_parse_devargs(struct rte_devargs *devargs,
+	struct ifpga_vdev_args *args)
 {
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	struct rte_rawdev *rawdev = NULL;
-	struct ifpga_rawdev *ifpga_dev;
-	int port;
+	struct rte_kvargs *kvlist;
 	char *name = NULL;
-	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
-	int ret = -1;
+	int port = 0;
+	int ret = -EINVAL;
 
-	devargs = dev->device.devargs;
+	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;
 
-	memset(dev_name, 0, sizeof(dev_name));
-	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
-	port, name);
+	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;
+	}
+
+	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
+		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 @@ static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
 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 = {
diff --git a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
index 857b734..eb9a9a5 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.h
+++ b/drivers/raw/ifpga/ifpga_rawdev.h
@@ -50,6 +50,7 @@ enum ifpga_rawdev_device_state {
 
 #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[8];
+	int port;
 };
 
 struct ifpga_rawdev *
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-04-21  1:37 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-11  2:39 [PATCH v1] raw/ifpga: remove vdev when ifpga is closed Wei Huang
2022-03-15  1:17 ` [PATCH v2] " Wei Huang
2022-03-18  8:57   ` [PATCH v3] " Wei Huang
2022-03-29  1:55     ` Huang, Wei
2022-03-29  2:14       ` Zhang, Qi Z
2022-03-29  2:19         ` Huang, Wei
2022-04-13  6:36         ` Huang, Wei
2022-04-20  9:32         ` Huang, Wei
2022-04-21  1:34     ` [PATCH v4] " Wei Huang

patches for DPDK stable branches

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://inbox.dpdk.org/stable/0 stable/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 stable stable/ http://inbox.dpdk.org/stable \
		stable@dpdk.org
	public-inbox-index stable

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.stable


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git