From: Jun Yang <[email protected]> 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 <[email protected]> --- 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

