From f14c6625ec82cb3bdd7aa950a1cf85beb509762b Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Sun, 4 Jan 2026 14:59:24 +0800 Subject: [PATCH 1/3] openamp/libmetal: change the libmetal mutex to rmutex to avoid carsh To avoid the crash when lock are acquired twice, one case is in the destory process: we hold the rpdev->lock to iterate the rpdev->endpoints to destory all the endpoints, but rpmsg_destroy_ept() may send the name service message, and need acquire the rpdev->lock again to lead crash. Signed-off-by: Bowen Wang --- ...et-HAVE_STDATOMIC_H-default-true-in-.patch | 6 +- ...enable-64-bit-atomic-by-toolchain-bu.patch | 4 +- ...-libmetal-nuttx-mutex-to-recursive-m.patch | 80 +++++++++++++++++++ openamp/libmetal.cmake | 2 + openamp/libmetal.defs | 1 + 5 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 openamp/0003-mutex-change-the-libmetal-nuttx-mutex-to-recursive-m.patch diff --git a/openamp/0001-libmetal-cmake-set-HAVE_STDATOMIC_H-default-true-in-.patch b/openamp/0001-libmetal-cmake-set-HAVE_STDATOMIC_H-default-true-in-.patch index 2ca6017b08935..4a7b9385176db 100644 --- a/openamp/0001-libmetal-cmake-set-HAVE_STDATOMIC_H-default-true-in-.patch +++ b/openamp/0001-libmetal-cmake-set-HAVE_STDATOMIC_H-default-true-in-.patch @@ -1,8 +1,8 @@ -From fad5ddc80345f97a0c7b20c545502ac1f8e321a5 Mon Sep 17 00:00:00 2001 +From f959a2b5acccd2045c7277c3f3ddefe9bea08887 Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Thu, 18 Dec 2025 17:26:13 +0800 -Subject: [PATCH] libmetal(cmake):set HAVE_STDATOMIC_H default true in NuttX - platform +Subject: [PATCH 1/3] libmetal(cmake):set HAVE_STDATOMIC_H default true in + NuttX platform Signed-off-by: Bowen Wang --- diff --git a/openamp/0002-libmetal-atomic-enable-64-bit-atomic-by-toolchain-bu.patch b/openamp/0002-libmetal-atomic-enable-64-bit-atomic-by-toolchain-bu.patch index 0f8a3db03c4c9..d305cdf9b21e5 100644 --- a/openamp/0002-libmetal-atomic-enable-64-bit-atomic-by-toolchain-bu.patch +++ b/openamp/0002-libmetal-atomic-enable-64-bit-atomic-by-toolchain-bu.patch @@ -1,7 +1,7 @@ -From 61756465a3dc241297b7a12d5500ac36a5ffa070 Mon Sep 17 00:00:00 2001 +From 4aaf8a78da2ac2e9627fcbbefa72db7330a57909 Mon Sep 17 00:00:00 2001 From: chao an Date: Sat, 29 Jun 2024 09:40:26 +0800 -Subject: [PATCH 2/5] libmetal/atomic: enable 64-bit atomic by toolchain +Subject: [PATCH 2/3] libmetal/atomic: enable 64-bit atomic by toolchain builtin flags Fix compile error: diff --git a/openamp/0003-mutex-change-the-libmetal-nuttx-mutex-to-recursive-m.patch b/openamp/0003-mutex-change-the-libmetal-nuttx-mutex-to-recursive-m.patch new file mode 100644 index 0000000000000..2b9ae675254d5 --- /dev/null +++ b/openamp/0003-mutex-change-the-libmetal-nuttx-mutex-to-recursive-m.patch @@ -0,0 +1,80 @@ +From ef06cf5ac9be793200783f24996d529db715ac43 Mon Sep 17 00:00:00 2001 +From: Bowen Wang +Date: Mon, 25 Nov 2024 23:07:10 +0800 +Subject: [PATCH 3/3] mutex: change the libmetal nuttx mutex to recursive mutex + +To avoid the crash when lock are acquired twice, one case is in the +destroy process: +we hold the rdev->lock to iterate the rdev->endpoints to destroy all +the endpoints, but rpmsg_destroy_ept() may send the name service message, +and need acquire the rdev->lock again to lead crash. + +Signed-off-by: Bowen Wang +--- + lib/system/nuttx/mutex.h | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/lib/system/nuttx/mutex.h libmetal/lib/system/nuttx/mutex.h +index 26ec4f9..d13c9c5 100644 +--- a/lib/system/nuttx/mutex.h ++++ libmetal/lib/system/nuttx/mutex.h +@@ -22,47 +22,47 @@ + extern "C" { + #endif + +-typedef mutex_t metal_mutex_t; ++typedef rmutex_t metal_mutex_t; + + /* + * METAL_MUTEX_INIT - used for initializing an mutex element in a static struct + * or global + */ +-#define METAL_MUTEX_INIT(m) NXMUTEX_INITIALIZER ++#define METAL_MUTEX_INIT(m) NXRMUTEX_INITIALIZER + /* + * METAL_MUTEX_DEFINE - used for defining and initializing a global or + * static singleton mutex + */ +-#define METAL_MUTEX_DEFINE(m) metal_mutex_t m = NXMUTEX_INITIALIZER ++#define METAL_MUTEX_DEFINE(m) metal_mutex_t m = NXRMUTEX_INITIALIZER + + static inline void __metal_mutex_init(metal_mutex_t *mutex) + { +- nxmutex_init(mutex); ++ nxrmutex_init(mutex); + } + + static inline void __metal_mutex_deinit(metal_mutex_t *mutex) + { +- nxmutex_destroy(mutex); ++ nxrmutex_destroy(mutex); + } + + static inline int __metal_mutex_try_acquire(metal_mutex_t *mutex) + { +- return nxmutex_trylock(mutex); ++ return nxrmutex_trylock(mutex); + } + + static inline void __metal_mutex_acquire(metal_mutex_t *mutex) + { +- nxmutex_lock(mutex); ++ nxrmutex_lock(mutex); + } + + static inline void __metal_mutex_release(metal_mutex_t *mutex) + { +- nxmutex_unlock(mutex); ++ nxrmutex_unlock(mutex); + } + + static inline int __metal_mutex_is_acquired(metal_mutex_t *mutex) + { +- return nxmutex_is_locked(mutex); ++ return nxrmutex_is_locked(mutex); + } + + #ifdef __cplusplus +-- +2.34.1 + diff --git a/openamp/libmetal.cmake b/openamp/libmetal.cmake index 8717be7c4c37c..26fbe9ed6374d 100644 --- a/openamp/libmetal.cmake +++ b/openamp/libmetal.cmake @@ -40,6 +40,8 @@ if(NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/libmetal) ${CMAKE_CURRENT_LIST_DIR}/0001-libmetal-cmake-set-HAVE_STDATOMIC_H-default-true-in-.patch && patch -p0 -d ${CMAKE_CURRENT_LIST_DIR} < ${CMAKE_CURRENT_LIST_DIR}/0002-libmetal-atomic-enable-64-bit-atomic-by-toolchain-bu.patch + && patch -p0 -d ${CMAKE_CURRENT_LIST_DIR} < + ${CMAKE_CURRENT_LIST_DIR}/0003-mutex-change-the-libmetal-nuttx-mutex-to-recursive-m.patch DOWNLOAD_NO_PROGRESS true TIMEOUT 30) diff --git a/openamp/libmetal.defs b/openamp/libmetal.defs index 7d4734fa58c9a..fb0065ca6ebea 100644 --- a/openamp/libmetal.defs +++ b/openamp/libmetal.defs @@ -84,6 +84,7 @@ libmetal.zip: mv libmetal-$(LIBMETAL_VERSION) libmetal $(Q) patch -p0 < 0001-libmetal-cmake-set-HAVE_STDATOMIC_H-default-true-in-.patch $(Q) patch -p0 < 0002-libmetal-atomic-enable-64-bit-atomic-by-toolchain-bu.patch + $(Q) patch -p0 < 0003-mutex-change-the-libmetal-nuttx-mutex-to-recursive-m.patch .libmetal_headers: libmetal.zip else From adda0704153a2335a3f45195f529e66be9bd73c8 Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Mon, 25 Nov 2024 22:45:40 +0800 Subject: [PATCH 2/3] drivers/rpmsg: no need check held status after change to rmutex metal_mutex has been changed to rmutex_t, so do not need check the held status again. Signed-off-by: Bowen Wang --- drivers/rpmsg/rpmsg_port.c | 3 +-- drivers/rpmsg/rpmsg_virtio_lite.c | 3 +-- drivers/rptun/rptun.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/rpmsg/rpmsg_port.c b/drivers/rpmsg/rpmsg_port.c index 2d11d243a6722..d3cfd06fe8b7e 100644 --- a/drivers/rpmsg/rpmsg_port.c +++ b/drivers/rpmsg/rpmsg_port.c @@ -812,8 +812,7 @@ static void rpmsg_port_dump(FAR struct rpmsg_s *rpmsg) FAR struct metal_list *node; bool needunlock = false; - if (!up_interrupt_context() && !sched_idletask() && - !nxmutex_is_hold(&rdev->lock)) + if (!up_interrupt_context() && !sched_idletask()) { metal_mutex_acquire(&rdev->lock); needunlock = true; diff --git a/drivers/rpmsg/rpmsg_virtio_lite.c b/drivers/rpmsg/rpmsg_virtio_lite.c index 38eb9d7641f7c..469a5d27f04c4 100644 --- a/drivers/rpmsg/rpmsg_virtio_lite.c +++ b/drivers/rpmsg/rpmsg_virtio_lite.c @@ -496,8 +496,7 @@ static void rpmsg_virtio_lite_dump(FAR struct rpmsg_s *rpmsg) return; } - if (up_interrupt_context() || sched_idletask() || - nxmutex_is_hold(&rdev->lock)) + if (up_interrupt_context() || sched_idletask()) { needlock = false; } diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 4f704ff1cebcd..f372b199ddbf6 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -711,8 +711,7 @@ static void rptun_dump(FAR struct rpmsg_s *rpmsg) return; } - if (up_interrupt_context() || sched_idletask() || - nxmutex_is_hold(&rdev->lock)) + if (up_interrupt_context() || sched_idletask()) { needlock = false; } From f5739e13a228bbd21cb44fac9c52d00a0fa221d9 Mon Sep 17 00:00:00 2001 From: liaoao Date: Wed, 20 Nov 2024 12:22:44 +0800 Subject: [PATCH 3/3] rpmsg: call unbound_cb if service used as server/client when it is destroyed Before this patch, the rpmsg services will not be destroied after call the rpmsg_device_destory(). And will cause error after call rpmsg_device_created() at the secound connecting witt peer. Signed-off-by: liaoao Signed-off-by: Bowen Wang --- drivers/rpmsg/rpmsg.c | 21 ++++++++++++++++++++- drivers/rpmsg/rpmsg_port.c | 25 ++++++------------------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/drivers/rpmsg/rpmsg.c b/drivers/rpmsg/rpmsg.c index 63a4e8102f2dc..70ae9e273ca6a 100644 --- a/drivers/rpmsg/rpmsg.c +++ b/drivers/rpmsg/rpmsg.c @@ -232,6 +232,7 @@ int rpmsg_register_callback(FAR void *priv, cb->ns_bind = ns_bind; nxrmutex_lock(&g_rpmsg_lock); + metal_list_add_tail(&g_rpmsg_cb, &cb->node); metal_list_for_each(&g_rpmsg, node) { FAR struct rpmsg_s *rpmsg = @@ -275,7 +276,6 @@ int rpmsg_register_callback(FAR void *priv, nxrmutex_unlock(&rpmsg->lock); } - metal_list_add_tail(&g_rpmsg_cb, &cb->node); nxrmutex_unlock(&g_rpmsg_lock); return 0; @@ -418,6 +418,7 @@ void rpmsg_device_destory(FAR struct rpmsg_s *rpmsg) { FAR struct metal_list *node; FAR struct metal_list *tmp; + FAR struct rpmsg_endpoint *ept; #ifdef CONFIG_RPMSG_PING rpmsg_ping_deinit(&rpmsg->ping); @@ -450,6 +451,24 @@ void rpmsg_device_destory(FAR struct rpmsg_s *rpmsg) } nxrmutex_unlock(&g_rpmsg_lock); + + /* Release all ept attached to current rpmsg device */ + + metal_mutex_acquire(&rpmsg->rdev->lock); + metal_list_for_each_safe(&rpmsg->rdev->endpoints, tmp, node) + { + ept = metal_container_of(node, struct rpmsg_endpoint, node); + if (ept->ns_unbind_cb) + { + ept->ns_unbind_cb(ept); + } + else + { + rpmsg_destroy_ept(ept); + } + } + + metal_mutex_release(&rpmsg->rdev->lock); } int rpmsg_register(FAR const char *path, FAR struct rpmsg_s *rpmsg, diff --git a/drivers/rpmsg/rpmsg_port.c b/drivers/rpmsg/rpmsg_port.c index d3cfd06fe8b7e..186f0a1aeb966 100644 --- a/drivers/rpmsg/rpmsg_port.c +++ b/drivers/rpmsg/rpmsg_port.c @@ -612,9 +612,6 @@ int rpmsg_port_initialize(FAR struct rpmsg_port_s *port, rdev->support_ack = true; rdev->support_ns = true; - rpmsg_register_endpoint(rdev, &rdev->ns_ept, "NS", RPMSG_NS_EPT_ADDR, - RPMSG_NS_EPT_ADDR, rpmsg_port_ns_callback, NULL, - port); port->ops->register_callback(port, rpmsg_port_rx_callback); return 0; @@ -626,22 +623,9 @@ int rpmsg_port_initialize(FAR struct rpmsg_port_s *port, void rpmsg_port_uninitialize(FAR struct rpmsg_port_s *port) { - FAR struct rpmsg_device *rdev = &port->rdev; - FAR struct metal_list *node; - FAR struct rpmsg_endpoint *ept; - - while (!metal_list_is_empty(&rdev->endpoints)) - { - node = rdev->endpoints.next; - ept = metal_container_of(node, struct rpmsg_endpoint, node); - rpmsg_destroy_ept(ept); - if (ept->ns_unbind_cb) - { - ept->ns_unbind_cb(ept); - } - } + FAR struct rpmsg_s *rpmsg = &port->rpmsg; - metal_mutex_deinit(&rdev->lock); + metal_mutex_deinit(&rpmsg->rdev->lock); rpmsg_port_destroy_queues(port); } @@ -747,6 +731,9 @@ int rpmsg_port_register(FAR struct rpmsg_port_s *port, return ret; } + rpmsg_register_endpoint(&port->rdev, &port->rdev.ns_ept, "NS", + RPMSG_NS_EPT_ADDR, RPMSG_NS_EPT_ADDR, + rpmsg_port_ns_callback, NULL, port); rpmsg_device_created(&port->rpmsg); return ret; } @@ -760,9 +747,9 @@ void rpmsg_port_unregister(FAR struct rpmsg_port_s *port) char name[64]; snprintf(name, sizeof(name), "/dev/rpmsg/%s", port->cpuname); - rpmsg_unregister(name, &port->rpmsg); rpmsg_device_destory(&port->rpmsg); + rpmsg_unregister(name, &port->rpmsg); } /****************************************************************************