[PATCH v4-S3 42/65] event/dpaa2: report available DPIO count and fix create cleanup
Prashant Gupta
prashant.gupta_3 at nxp.com
Fri Oct 23 15:43:22 CEST 2026
From: Jun Yang <jun.yang at nxp.com>
max_event_ports was reported as the total number of DPAA2_IO devices,
including DPIOs already claimed by other users(affine portals).
Add an internal helper rte_dpaa2_available_dpio_device() that counts
only DPIOs with a zero reference count, and use it so the eventdev
advertises the number of ports it can actually acquire.
Rework dpaa2_eventdev_create() error handling. The device creation
loop now iterates over a fixed range and, on any DPCI attach failure,
frees the DPCON and DPCI acquired for the current event queue and
breaks out instead of returning with resources leaked. A single done
path releases the DPCON/DPCI of all event queues set up so far when an
error occurred, and the function returns a meaningful error code
rather than a fixed -EFAULT.
Signed-off-by: Jun Yang <jun.yang at nxp.com>
---
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 15 +++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 4 ++
drivers/event/dpaa2/dpaa2_eventdev.c | 52 +++++++++++++++---------
drivers/event/dpaa2/dpaa2_eventdev.h | 23 ++++++++++-
4 files changed, 73 insertions(+), 21 deletions(-)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index 55dcef41d1..654472b284 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
@@ -465,6 +465,21 @@ void rte_dpaa2_free_dpio_device(struct dpaa2_dpio_dev *dpio_dev)
dpaa2_put_qbman_swp(dpio_dev);
}
+RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_available_dpio_device)
+uint16_t
+rte_dpaa2_available_dpio_device(void)
+{
+ struct dpaa2_dpio_dev *dpio_dev = NULL;
+ uint16_t available_num = 0;
+
+ TAILQ_FOREACH(dpio_dev, &dpio_dev_list, next) {
+ if (dpio_dev && !rte_atomic16_read(&dpio_dev->ref_count))
+ available_num++;
+ }
+
+ return available_num;
+}
+
static void
dpaa2_close_dpio_device(int object_id)
{
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
index ae0f5993d6..d28fdb03b7 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
@@ -78,4 +78,8 @@ __rte_internal
void
rte_dpaa2_free_dpio_device(struct dpaa2_dpio_dev *dpio_dev);
+__rte_internal
+uint16_t
+rte_dpaa2_available_dpio_device(void);
+
#endif /* _DPAA2_HW_DPIO_H_ */
diff --git a/drivers/event/dpaa2/dpaa2_eventdev.c b/drivers/event/dpaa2/dpaa2_eventdev.c
index 4c20e26870..5badc17af7 100644
--- a/drivers/event/dpaa2/dpaa2_eventdev.c
+++ b/drivers/event/dpaa2/dpaa2_eventdev.c
@@ -401,7 +401,7 @@ dpaa2_eventdev_info_get(struct rte_eventdev *dev,
DPAA2_EVENT_MAX_QUEUE_PRIORITY_LEVELS;
dev_info->max_event_priority_levels =
DPAA2_EVENT_MAX_EVENT_PRIORITY_LEVELS;
- dev_info->max_event_ports = rte_fslmc_get_device_count(DPAA2_IO);
+ dev_info->max_event_ports = rte_dpaa2_available_dpio_device();
if (dev_info->max_event_ports > dev_info->max_event_queues)
dev_info->max_event_ports = dev_info->max_event_queues;
/* we only support dpio up to number of cores */
@@ -1209,17 +1209,18 @@ static int
dpaa2_eventdev_create(const char *name, struct rte_vdev_device *vdev)
{
struct rte_eventdev *eventdev;
- struct dpaa2_eventdev *priv;
+ struct dpaa2_eventdev *priv = NULL;
struct dpaa2_dpcon_dev *dpcon_dev = NULL;
struct dpaa2_dpci_dev *dpci_dev = NULL;
struct dpaa2_eventq *evq_info;
- int ret;
+ int ret = 0, i;
eventdev = rte_event_pmd_vdev_init(name,
sizeof(struct dpaa2_eventdev), rte_socket_id(), vdev);
if (!eventdev) {
+ ret = -ENOMEM;
DPAA2_EVENTDEV_ERR("Failed to create Event device %s", name);
- goto fail;
+ goto done;
}
eventdev->dev_ops = &dpaa2_eventdev_ops;
@@ -1237,8 +1238,8 @@ dpaa2_eventdev_create(const char *name, struct rte_vdev_device *vdev)
priv = eventdev->data->dev_private;
memset(priv, 0, sizeof(struct dpaa2_eventdev));
- do {
- evq_info = &priv->evq_info[priv->max_event_queues];
+ for (i = 0; i < DPAA2_EVENT_MAX_QUEUES; i++) {
+ evq_info = &priv->evq_info[i];
dpcon_dev = rte_dpaa2_alloc_dpcon_dev();
if (!dpcon_dev)
break;
@@ -1256,10 +1257,8 @@ dpaa2_eventdev_create(const char *name, struct rte_vdev_device *vdev)
dpaa2_eventdev_process_parallel,
&evq_info->dpci_txqs[RTE_SCHED_TYPE_PARALLEL]);
if (ret) {
- rte_dpaa2_free_dpcon_dev(evq_info->dpcon);
- rte_dpaa2_free_dpci_dev(evq_info->dpci);
DPAA2_EVENTDEV_ERR("DPCI attach parallel RX failed: err(%d)", ret);
- break;
+ goto err_break;
}
ret = rte_dpaa2_dpci_link_attach(dpci_dev, DPCI_DEST_DPCON,
@@ -1267,10 +1266,8 @@ dpaa2_eventdev_create(const char *name, struct rte_vdev_device *vdev)
dpaa2_eventdev_process_atomic,
&evq_info->dpci_txqs[RTE_SCHED_TYPE_ATOMIC]);
if (ret) {
- rte_dpaa2_free_dpcon_dev(evq_info->dpcon);
- rte_dpaa2_free_dpci_dev(evq_info->dpci);
DPAA2_EVENTDEV_ERR("DPCI attach atomic RX failed: err(%d)", ret);
- break;
+ goto err_break;
}
/** TO DO: order schedule.*/
@@ -1279,17 +1276,32 @@ dpaa2_eventdev_create(const char *name, struct rte_vdev_device *vdev)
evq_info->event_queue_id = priv->max_event_queues;
priv->max_event_queues++;
- if (priv->max_event_queues >= DPAA2_EVENT_MAX_QUEUES)
- break;
- } while (dpcon_dev && dpci_dev);
-
- DPAA2_EVENTDEV_INFO("%s eventdev created", name);
+ continue;
+err_break:
+ if (evq_info->dpcon)
+ rte_dpaa2_free_dpcon_dev(evq_info->dpcon);
+ if (evq_info->dpci)
+ rte_dpaa2_free_dpci_dev(evq_info->dpci);
+ break;
+ }
done:
+ if (ret && priv) {
+ for (i = 0; i < priv->max_event_queues; i++) {
+ evq_info = &priv->evq_info[i];
+ if (evq_info->dpcon)
+ rte_dpaa2_free_dpcon_dev(evq_info->dpcon);
+ if (evq_info->dpci)
+ rte_dpaa2_free_dpci_dev(evq_info->dpci);
+ }
+ }
event_dev_probing_finish(eventdev);
- return 0;
-fail:
- return -EFAULT;
+ if (ret)
+ DPAA2_EVENTDEV_ERR("Failed(%d) to create event device(%s)", ret, name);
+ else
+ DPAA2_EVENTDEV_INFO("Create event device(%s)", name);
+
+ return ret;
}
static int
diff --git a/drivers/event/dpaa2/dpaa2_eventdev.h b/drivers/event/dpaa2/dpaa2_eventdev.h
index c0ce42c83f..af1c831b92 100644
--- a/drivers/event/dpaa2/dpaa2_eventdev.h
+++ b/drivers/event/dpaa2/dpaa2_eventdev.h
@@ -8,6 +8,9 @@
#include <eventdev_pmd.h>
#include <eventdev_pmd_vdev.h>
#include <rte_atomic.h>
+#include <rte_common.h>
+#include <rte_eventdev.h>
+
#include <mc/fsl_dpcon.h>
#include <mc/fsl_mc_sys.h>
@@ -15,6 +18,7 @@
#define DPAA2_EVENT_DEFAULT_DPCI_PRIO 0
+#define DPAA2_EVENT_MAX_PORTS 16
#define DPAA2_EVENT_MAX_QUEUES 16
#define DPAA2_EVENT_MIN_DEQUEUE_TIMEOUT 1
#define DPAA2_EVENT_MAX_DEQUEUE_TIMEOUT (UINT32_MAX - 1)
@@ -51,7 +55,24 @@ enum {
* the ethdev to eventdev with DPAA2 devices.
*/
-#define DPAA2_EVENTQ_LINK_CONF_MAX 4 /** Max schedule type + 1.*/
+/*
+ * Size of the per-eventq dpci_txqs[] array. It is indexed directly by
+ * event->sched_type, so it must be (largest sched-type value) + 1.
+ * RTE_SCHED_TYPE_{ORDERED,ATOMIC,PARALLEL} are plain macros (0, 1, 2) with
+ * no upstream MAX definition, so compute the maximum explicitly here rather
+ * than assuming PARALLEL is numerically largest. If the sched-type values are
+ * ever renumbered upstream, this expression still yields the correct bound.
+ *
+ * A plain ternary max is used (not RTE_MAX): RTE_MAX expands to a GCC
+ * statement-expression ({ ... }), which is not a constant expression and
+ * cannot size an array at file scope.
+ */
+#define DPAA2_EVENTQ_MAX2(a, b) ((a) > (b) ? (a) : (b))
+#define DPAA2_EVENTQ_LINK_CONF_MAX \
+ (DPAA2_EVENTQ_MAX2(RTE_SCHED_TYPE_ORDERED, \
+ DPAA2_EVENTQ_MAX2(RTE_SCHED_TYPE_ATOMIC, \
+ RTE_SCHED_TYPE_PARALLEL)) + 1)
+
struct dpaa2_eventq {
int valid;
uint8_t link_num;
--
2.43.0
More information about the dev
mailing list