[PATCH v8 26/26] drivers: memory free in destructor

Hemant Agrawal hemant.agrawal at nxp.com
Tue Aug 11 13:57:31 CEST 2026


From: Jun Yang <jun.yang at nxp.com>

Don't free eal memory in destructor.
User should invoke dpaax_enter_destructor in
it's destructorto mark current context if there
is eal memory to be freed.

Signed-off-by: Jun Yang <jun.yang at nxp.com>
---
 drivers/bus/dpaa/dpaa_bus.c             |  1 +
 drivers/common/dpaax/compat.h           | 22 +++++++++++++++++-----
 drivers/common/dpaax/dpaax_iova_table.c | 25 ++++++++++++++++++++++++-
 drivers/mempool/dpaa/dpaa_mempool.c     |  2 ++
 drivers/net/dpaa/dpaa_ethdev.c          |  1 +
 5 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 16892b5247..01bfaacbf7 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -915,6 +915,7 @@ RTE_FINI_PRIO(dpaa_cleanup, 102)
 	if (!dpaa_bus_global_init)
 		return;
 
+	dpaax_enter_destructor();
 	/* cleanup portals in case non-graceful exit */
 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
 		/* Check for non zero id */
diff --git a/drivers/common/dpaax/compat.h b/drivers/common/dpaax/compat.h
index d0635255da..b826a55de2 100644
--- a/drivers/common/dpaax/compat.h
+++ b/drivers/common/dpaax/compat.h
@@ -2,7 +2,7 @@
  *
  * Copyright 2011 Freescale Semiconductor, Inc.
  * All rights reserved.
- * Copyright 2019-2020 NXP
+ * Copyright 2019-2020, 2026 NXP
  *
  */
 
@@ -336,11 +336,23 @@ static inline void copy_bytes(void *dest, const void *src, size_t sz)
 #define copy_bytes memcpy
 #endif
 
-/* Allocator stuff */
-#define kmalloc(sz, t)	rte_malloc(NULL, sz, 0)
-#define kzalloc(sz, t)  rte_zmalloc(NULL, sz, 0)
+__rte_internal
+void dpaax_enter_destructor(void);
+__rte_internal
+int is_dpaax_in_destructor(void);
+
+/* Allocator stuff, make sure the eal memory pool is available when calling.*/
+#define kmalloc(sz, _t) ((void)(_t), rte_malloc(NULL, sz, 0))
+#define kzalloc(sz, _t) ((void)(_t), rte_zmalloc(NULL, sz, 0))
 #define vmalloc(sz)	rte_malloc(NULL, sz, 0)
-#define kfree(p)	rte_free(p)
+
+#define kfree(p) \
+({ \
+	if (!is_dpaax_in_destructor()) \
+		rte_free(p); \
+	else \
+		pr_debug("Eal memory has been destroyed.\n"); \
+})
 
 static inline unsigned long get_zeroed_page(gfp_t __foo __rte_unused)
 {
diff --git a/drivers/common/dpaax/dpaax_iova_table.c b/drivers/common/dpaax/dpaax_iova_table.c
index 1220d9654b..d53b24d4f4 100644
--- a/drivers/common/dpaax/dpaax_iova_table.c
+++ b/drivers/common/dpaax/dpaax_iova_table.c
@@ -1,17 +1,40 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2018-2023 NXP
+ * Copyright 2018-2023,2026 NXP
  */
 
 #include <eal_export.h>
 #include <rte_memory.h>
 
 #include "dpaax_iova_table.h"
+#include "compat.h"
 #include "dpaax_logs.h"
 
 /* Global table reference */
 RTE_EXPORT_INTERNAL_SYMBOL(dpaax_iova_table_p)
 struct dpaax_iova_table *dpaax_iova_table_p;
 
+/*
+ * Track whether the process is executing DPDK destructors. During
+ * teardown the EAL memory subsystem may already be gone, so freeing
+ * EAL memory from a DPAAx destructor is unsafe. Drivers mark the
+ * destructor context via dpaax_enter_destructor() so that kfree()
+ * (see compat.h) can skip rte_free() in that window.
+ */
+static int s_dpaax_in_destructor;
+
+RTE_EXPORT_INTERNAL_SYMBOL(dpaax_enter_destructor)
+void dpaax_enter_destructor(void)
+{
+	s_dpaax_in_destructor = 1;
+}
+
+RTE_EXPORT_INTERNAL_SYMBOL(is_dpaax_in_destructor)
+int is_dpaax_in_destructor(void)
+{
+	return s_dpaax_in_destructor;
+}
+
+
 static int dpaax_handle_memevents(void);
 
 /* A structure representing the device-tree node available in /proc/device-tree.
diff --git a/drivers/mempool/dpaa/dpaa_mempool.c b/drivers/mempool/dpaa/dpaa_mempool.c
index 25f37bab51..edcb8dfacb 100644
--- a/drivers/mempool/dpaa/dpaa_mempool.c
+++ b/drivers/mempool/dpaa/dpaa_mempool.c
@@ -531,6 +531,8 @@ RTE_FINI_PRIO(dpaa_mpool_finish, RTE_PRIORITY_104)
 {
 	uint16_t bpid;
 
+	dpaax_enter_destructor();
+
 	for (bpid = 0; bpid < DPAA_MAX_BPOOLS; bpid++) {
 		if (s_dpaa_bpid_allocated_flag[bpid].used) {
 			bman_free_bpid(bpid, s_dpaa_bpid_allocated_flag[bpid].flags);
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 4eb1f635bb..a07c73cf47 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -2811,6 +2811,7 @@ RTE_FINI_PRIO(dpaa_finish, 103)
 	struct rte_eth_dev *dev;
 
 	PMD_INIT_FUNC_TRACE();
+	dpaax_enter_destructor();
 	/* For secondary, primary will do all the cleanup */
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return;
-- 
2.25.1



More information about the dev mailing list