From 0ed600458640388423a2775e8c5332417914ff12 Mon Sep 17 00:00:00 2001 From: ShenWeilong Date: Wed, 26 Aug 2026 11:41:51 +0800 Subject: [PATCH] fix(bt): fixed mempool deinit crash issue for esp32s31 --- components/bt/controller/esp32h4/bt.c | 3 ++ components/bt/controller/esp32s31/bt.c | 3 ++ .../bt/controller/lib_esp32h4/esp32h4-bt-lib | 2 +- .../controller/lib_esp32s31/esp32s31-bt-lib | 2 +- components/bt/host/nimble/nimble | 2 +- components/bt/porting/include/os/os_mempool.h | 23 +++++++++++++++ components/bt/porting/mem/os_mempool.c | 23 ++++++++++++++- components/bt/porting_btdm/Kconfig.in | 3 +- .../controller/ble/include/os/os_mempool.h | 28 +++++++++++++++++++ .../btdm_common/include/btdm_mempool.h | 24 ++++++++++++++-- .../controller/btdm_common/src/btdm_mempool.c | 23 ++++++++++++++- .../btdm_common/src/btdm_osal_freertos.c | 5 ++++ .../transport/driver/common/hci_driver_util.c | 1 + 13 files changed, 133 insertions(+), 9 deletions(-) diff --git a/components/bt/controller/esp32h4/bt.c b/components/bt/controller/esp32h4/bt.c index 0f343853d76..825b674a3c9 100644 --- a/components/bt/controller/esp32h4/bt.c +++ b/components/bt/controller/esp32h4/bt.c @@ -21,6 +21,7 @@ #include "btdm_lp.h" #include "btdm_log.h" #include "btdm_external.h" +#include "btdm_mempool.h" /* *************************************************************************************************** @@ -95,6 +96,8 @@ bt_controller_deinit(void) { s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; + btdm_mempool_deinit_all(true); + hci_transport_deinit(); #if UC_BT_CTRL_BR_EDR_IS_ENABLE diff --git a/components/bt/controller/esp32s31/bt.c b/components/bt/controller/esp32s31/bt.c index 0f343853d76..825b674a3c9 100644 --- a/components/bt/controller/esp32s31/bt.c +++ b/components/bt/controller/esp32s31/bt.c @@ -21,6 +21,7 @@ #include "btdm_lp.h" #include "btdm_log.h" #include "btdm_external.h" +#include "btdm_mempool.h" /* *************************************************************************************************** @@ -95,6 +96,8 @@ bt_controller_deinit(void) { s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; + btdm_mempool_deinit_all(true); + hci_transport_deinit(); #if UC_BT_CTRL_BR_EDR_IS_ENABLE diff --git a/components/bt/controller/lib_esp32h4/esp32h4-bt-lib b/components/bt/controller/lib_esp32h4/esp32h4-bt-lib index 1d421a2a046..3bf30d20a76 160000 --- a/components/bt/controller/lib_esp32h4/esp32h4-bt-lib +++ b/components/bt/controller/lib_esp32h4/esp32h4-bt-lib @@ -1 +1 @@ -Subproject commit 1d421a2a046a75998fd5edc98d5d6a32e7506d5c +Subproject commit 3bf30d20a76f32041c6db3c9160016aa366f9b43 diff --git a/components/bt/controller/lib_esp32s31/esp32s31-bt-lib b/components/bt/controller/lib_esp32s31/esp32s31-bt-lib index f8b5deaeda9..1b99d182e6e 160000 --- a/components/bt/controller/lib_esp32s31/esp32s31-bt-lib +++ b/components/bt/controller/lib_esp32s31/esp32s31-bt-lib @@ -1 +1 @@ -Subproject commit f8b5deaeda9eea8d7d639b2b11f066a64d72cdd3 +Subproject commit 1b99d182e6e7587dfe60243e762e35c91646c80e diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 68a6539cc27..916be244a9c 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 68a6539cc2723bc48fa5291776edd2aa0175c3c7 +Subproject commit 916be244a9c646bc16fd65507478cf3fe717d8ed diff --git a/components/bt/porting/include/os/os_mempool.h b/components/bt/porting/include/os/os_mempool.h index 312efa9b26d..c2184684c6f 100644 --- a/components/bt/porting/include/os/os_mempool.h +++ b/components/bt/porting/include/os/os_mempool.h @@ -374,6 +374,29 @@ void os_mempool_flags_set(struct os_mempool *mp, uint8_t flags); */ void os_mempool_flags_clear(struct os_mempool *mp, uint8_t flags); +/** + * @brief Deinitialize a memory pool. + * + * @param mp Pointer to memory pool + */ +void os_mempool_deinit(struct os_mempool *mp); + + /** + * @brief Deinitialize all of memory pools. + * + * @param is_controller Whether called from controller. + * + * @return OS_OK on success; OS_INVALID_PARM if not found corresponding memory pools. + */ +os_error_t os_mempool_deinit_all(bool is_controller); + +/** + * @brief Check if there are any live memory pools. + * + * @return true if there are any live memory pools; false otherwise. + */ +bool os_mempool_has_live_pool(void); + #ifdef __cplusplus } #endif diff --git a/components/bt/porting/mem/os_mempool.c b/components/bt/porting/mem/os_mempool.c index 6f8314c69dc..03b2e599d0a 100644 --- a/components/bt/porting/mem/os_mempool.c +++ b/components/bt/porting/mem/os_mempool.c @@ -735,6 +735,11 @@ os_mempool_module_init(void) static os_error_t os_mempool_mem_free(struct os_mempool *mp) { + /* Extended mempool has its own free logic */ + if (mp->mp_flags & OS_MEMPOOL_F_EXT) { + return OS_OK; + } + /* For runtime allocation mode, check whether all blocks have been freed */ if (!(mp->mp_flags & OS_MEMPOOL_F_RUNTIME)) { return OS_EINVAL; @@ -767,8 +772,15 @@ os_mempool_mem_free(struct os_mempool *mp) #endif void -os_mempool_deinit(bool is_controller) +os_mempool_deinit(struct os_mempool *mp) { + os_mempool_unregister(mp); +} + +os_error_t +os_mempool_deinit_all(bool is_controller) +{ + os_error_t err = OS_INVALID_PARM; struct os_mempool *mp = NULL; struct os_mempool *next = NULL; @@ -780,8 +792,17 @@ os_mempool_deinit(bool is_controller) next = STAILQ_NEXT(mp, mp_list); os_mempool_unregister(mp); mp = next; + err = OS_OK; } else { mp = STAILQ_NEXT(mp, mp_list); } } + + return err; +} + +bool +os_mempool_has_live_pool(void) +{ + return !STAILQ_EMPTY(&g_os_mempool_list); } diff --git a/components/bt/porting_btdm/Kconfig.in b/components/bt/porting_btdm/Kconfig.in index 35fb7713a79..956a0d69078 100644 --- a/components/bt/porting_btdm/Kconfig.in +++ b/components/bt/porting_btdm/Kconfig.in @@ -28,7 +28,8 @@ config BT_CTRL_TASK_STACK_SIZE This configures stack size of NimBLE controller task config BT_CTRL_ALLOW_MALLOC_FROM_SPIRAM - bool "Allow allocating BT memory from SPIRAM" + depends on SOC_SPIRAM_SUPPORTED + bool "Allow allocating controller memory from SPIRAM (EXPERIMENTAL)" default n help Allocate part of memory from SPIRAM. Need to enable CONFIG_SPIRAM first. diff --git a/components/bt/porting_btdm/controller/ble/include/os/os_mempool.h b/components/bt/porting_btdm/controller/ble/include/os/os_mempool.h index 8ba0235d8a6..92a5bd7a1fa 100644 --- a/components/bt/porting_btdm/controller/ble/include/os/os_mempool.h +++ b/components/bt/porting_btdm/controller/ble/include/os/os_mempool.h @@ -355,6 +355,22 @@ void os_mempool_flags_set(struct os_mempool *mp, uint8_t flags); */ void os_mempool_flags_clear(struct os_mempool *mp, uint8_t flags); +/** + * @brief Deinitialize a memory pool. + * + * @param mp Pointer to memory pool + */ +void os_mempool_deinit(struct os_mempool *mp); + + /** + * @brief Deinitialize all of memory pools. + * + * @param is_controller Whether called from controller. + * + * @return OS_OK on success; OS_INVALID_PARM if not found corresponding memory pools. + */ +os_error_t os_mempool_deinit_all(bool is_controller); + #else /* !CONFIG_BT_DUAL_MODE_ARCH */ #include "btdm_mempool.h" @@ -446,6 +462,18 @@ os_mempool_flags_clear(struct os_mempool *mp, uint8_t flags) btdm_mempool_flags_clear((struct btdm_mempool *)mp, flags); } +static inline void +os_mempool_deinit(struct os_mempool *mp) +{ + btdm_mempool_deinit((struct btdm_mempool *)mp); +} + +static inline os_error_t +os_mempool_deinit_all(bool is_controller) +{ + return (os_error_t)btdm_mempool_deinit_all(is_controller); +} + #endif /* !CONFIG_BT_DUAL_MODE_ARCH */ diff --git a/components/bt/porting_btdm/controller/btdm_common/include/btdm_mempool.h b/components/bt/porting_btdm/controller/btdm_common/include/btdm_mempool.h index 5cbd575949b..3579bc19900 100644 --- a/components/bt/porting_btdm/controller/btdm_common/include/btdm_mempool.h +++ b/components/bt/porting_btdm/controller/btdm_common/include/btdm_mempool.h @@ -330,12 +330,30 @@ void e_btdm_mempool_module_init(void); #define btdm_mempool_module_init BTDM_MEMPOOL_EXT_FUNC(btdm_mempool_module_init) /** - * Deinitialize the memory pool module. + * Deinitialize a memory pool. + * + * @param mp Pointer to memory pool + */ +void e_btdm_mempool_deinit(struct btdm_mempool *mp); +#define btdm_mempool_deinit BTDM_MEMPOOL_EXT_FUNC(btdm_mempool_deinit) + +/** + * Deinitialize all of memory pools. * * @param is_controller Whether called from controller. + * + * @return BTDM_OSAL_OK on success; BTDM_OSAL_INVALID_PARM if not found corresponding memory pools. */ -void e_btdm_mempool_deinit(bool is_controller); -#define btdm_mempool_deinit BTDM_MEMPOOL_EXT_FUNC(btdm_mempool_deinit) +btdm_osal_error_t e_btdm_mempool_deinit_all(bool is_controller); +#define btdm_mempool_deinit_all BTDM_MEMPOOL_EXT_FUNC(btdm_mempool_deinit_all) + +/** + * Check if there are any live memory pools. + * + * @return true if there are any live memory pools; false otherwise. + */ +bool e_btdm_mempool_has_live_pool(void); +#define btdm_mempool_has_live_pool BTDM_MEMPOOL_EXT_FUNC(btdm_mempool_has_live_pool) #ifdef __cplusplus } diff --git a/components/bt/porting_btdm/controller/btdm_common/src/btdm_mempool.c b/components/bt/porting_btdm/controller/btdm_common/src/btdm_mempool.c index 509fb853c25..d3147becebd 100644 --- a/components/bt/porting_btdm/controller/btdm_common/src/btdm_mempool.c +++ b/components/bt/porting_btdm/controller/btdm_common/src/btdm_mempool.c @@ -18,6 +18,11 @@ static STAILQ_HEAD(, btdm_mempool) s_btdm_osal_mempool_list = STAILQ_HEAD_INITIA static btdm_osal_error_t e_btdm_mempool_mem_free(struct btdm_mempool *mp) { + /* Extended mempool has its own free logic */ + if (mp->mp_flags & BTDM_MEMPOOL_F_EXT) { + return BTDM_OSAL_OK; + } + /* For runtime allocation mode, check whether all blocks have been freed */ if (!(mp->mp_flags & BTDM_MEMPOOL_F_RUNTIME)) { return BTDM_OSAL_EINVAL; @@ -588,8 +593,15 @@ e_btdm_mempool_module_init(void) } void -e_btdm_mempool_deinit(bool is_controller) +e_btdm_mempool_deinit(struct btdm_mempool *mp) { + btdm_mempool_unregister(mp); +} + +btdm_osal_error_t +e_btdm_mempool_deinit_all(bool is_controller) +{ + btdm_osal_error_t err = BTDM_OSAL_INVALID_PARM; struct btdm_mempool *mp = NULL; struct btdm_mempool *next = NULL; @@ -601,8 +613,17 @@ e_btdm_mempool_deinit(bool is_controller) next = STAILQ_NEXT(mp, mp_list); btdm_mempool_unregister(mp); mp = next; + err = BTDM_OSAL_OK; } else { mp = STAILQ_NEXT(mp, mp_list); } } + + return err; +} + +bool +e_btdm_mempool_has_live_pool(void) +{ + return !STAILQ_EMPTY(&s_btdm_osal_mempool_list); } diff --git a/components/bt/porting_btdm/controller/btdm_common/src/btdm_osal_freertos.c b/components/bt/porting_btdm/controller/btdm_common/src/btdm_osal_freertos.c index 3c4c4300704..39cb9832de2 100644 --- a/components/bt/porting_btdm/controller/btdm_common/src/btdm_osal_freertos.c +++ b/components/bt/porting_btdm/controller/btdm_common/src/btdm_osal_freertos.c @@ -1174,6 +1174,7 @@ btdm_osal_elem_mempool_init(btdm_osal_elem_num_t *elem_num) if (rc) { return -2; } + btdm_mempool_flags_set(&s_btdm_osal_ev_pool, BTDM_MEMPOOL_F_CONTROLLER); } if (elem_num->co_count) { @@ -1190,6 +1191,7 @@ btdm_osal_elem_mempool_init(btdm_osal_elem_num_t *elem_num) if (rc) { return -4; } + btdm_mempool_flags_set(&s_btdm_osal_co_pool, BTDM_MEMPOOL_F_CONTROLLER); } return 0; @@ -1200,12 +1202,15 @@ btdm_osal_elem_mempool_deinit(void) { if (s_btdm_osal_ev_buf) { BTDM_OSAL_ASSERT(s_btdm_osal_ev_pool.mp_num_free == s_btdm_osal_ev_pool.mp_num_blocks); + btdm_mempool_deinit(&s_btdm_osal_ev_pool); btdm_osal_free(s_btdm_osal_ev_buf); s_btdm_osal_ev_buf = NULL; } + if (s_btdm_osal_co_buf) { BTDM_OSAL_ASSERT(s_btdm_osal_co_pool.mp_num_free == s_btdm_osal_co_pool.mp_num_blocks); + btdm_mempool_deinit(&s_btdm_osal_co_pool); btdm_osal_free(s_btdm_osal_co_buf); s_btdm_osal_co_buf = NULL; } diff --git a/components/bt/porting_btdm/transport/driver/common/hci_driver_util.c b/components/bt/porting_btdm/transport/driver/common/hci_driver_util.c index 2ba3819d87e..68c1a5e9062 100644 --- a/components/bt/porting_btdm/transport/driver/common/hci_driver_util.c +++ b/components/bt/porting_btdm/transport/driver/common/hci_driver_util.c @@ -102,6 +102,7 @@ hci_driver_util_memory_init(void) ESP_LOGE(TAG, "Failed to initialize tx pool"); goto init_err; } + btdm_mempool_flags_set(s_hci_driver_util_env.tx_entry_pool, BTDM_MEMPOOL_F_CONTROLLER); return 0;