You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/07/27 12:37:02 UTC

[incubator-nuttx] 05/06: rptun: add ns_match callback to resolve rptun deadlock

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 8a3683fb9ffba5d84d402b009ca4d7cd51556555
Author: ligd <li...@xiaomi.com>
AuthorDate: Mon Jun 6 16:38:11 2022 +0800

    rptun: add ns_match callback to resolve rptun deadlock
    
    thread A: accept -> net_lock -> socket_rpmsg_accept
              -> rpmsg_register_callabck -> rptun_lock
    thread B: ns_bind -> rpmsg_socket_ns_bind -> get_tx_payload_buffer
              -> rptun_wait_tx -> usrsock_rpmsg_ept_cb -> usrsockdev_write
              -> net_lock -> deadlock
    
    fix:
    add ns_match callback
    
    Signed-off-by: ligd <li...@xiaomi.com>
---
 arch/risc-v/src/mpfs/mpfs_ihc.c      |  6 ++-
 drivers/clk/clk_rpmsg.c              | 37 +++++++++++------
 drivers/input/uinput.c               |  2 +-
 drivers/ioexpander/ioe_rpmsg.c       | 42 ++++++++++++--------
 drivers/net/rpmsgdrv.c               |  1 +
 drivers/power/regulator_rpmsg.c      | 37 +++++++++++------
 drivers/rptun/rptun.c                | 77 ++++++++++++++++++++++++------------
 drivers/serial/uart_rpmsg.c          |  1 +
 drivers/syslog/syslog_rpmsg.c        |  1 +
 drivers/syslog/syslog_rpmsg_server.c | 16 +++++---
 drivers/timers/rpmsg_rtc.c           | 15 ++++---
 fs/rpmsgfs/rpmsgfs_client.c          |  2 +
 fs/rpmsgfs/rpmsgfs_server.c          | 16 +++++---
 include/nuttx/rptun/openamp.h        |  5 +++
 net/rpmsg/rpmsg_sockif.c             | 39 ++++++++++++------
 15 files changed, 199 insertions(+), 98 deletions(-)

diff --git a/arch/risc-v/src/mpfs/mpfs_ihc.c b/arch/risc-v/src/mpfs/mpfs_ihc.c
index 5611998f46..c8d3f08240 100755
--- a/arch/risc-v/src/mpfs/mpfs_ihc.c
+++ b/arch/risc-v/src/mpfs/mpfs_ihc.c
@@ -1418,7 +1418,8 @@ int mpfs_ihc_init(void)
 
   /* Register callback to notify when rpmsg device is ready */
 
-  ret = rpmsg_register_callback(NULL, mpfs_rpmsg_device_created, NULL, NULL);
+  ret = rpmsg_register_callback(NULL, mpfs_rpmsg_device_created,
+                                NULL, NULL, NULL);
   if (ret < 0)
     {
       ihcerr("ERROR: Not able to register rpmsg callback\n");
@@ -1438,7 +1439,8 @@ int mpfs_ihc_init(void)
   if (ret < 0)
     {
       ihcerr("ERROR: Not able to create a thread!\n");
-      rpmsg_unregister_callback(NULL, mpfs_rpmsg_device_created, NULL, NULL);
+      rpmsg_unregister_callback(NULL, mpfs_rpmsg_device_created,
+                                NULL, NULL, NULL);
       goto init_error;
     }
 
diff --git a/drivers/clk/clk_rpmsg.c b/drivers/clk/clk_rpmsg.c
index 2d7ff00812..7cf9f6b5bf 100644
--- a/drivers/clk/clk_rpmsg.c
+++ b/drivers/clk/clk_rpmsg.c
@@ -160,6 +160,10 @@ static void clk_rpmsg_client_created(FAR struct rpmsg_device *rdev,
 static void clk_rpmsg_client_destroy(FAR struct rpmsg_device *rdev,
                                      FAR void *priv_);
 
+static bool clk_rpmsg_server_match(FAR struct rpmsg_device *rdev,
+                                   FAR void *priv_,
+                                   FAR const char *name,
+                                   uint32_t dest);
 static void clk_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
                                   FAR void *priv_,
                                   FAR const char *name,
@@ -249,6 +253,7 @@ clk_rpmsg_get_priv(FAR const char *name)
   rpmsg_register_callback(priv,
                           clk_rpmsg_client_created,
                           clk_rpmsg_client_destroy,
+                          NULL,
                           NULL);
   return priv;
 
@@ -495,6 +500,14 @@ static int64_t clk_rpmsg_sendrecv(FAR struct rpmsg_endpoint *ept,
   return cookie.result;
 }
 
+static bool clk_rpmsg_server_match(FAR struct rpmsg_device *rdev,
+                                   FAR void *priv_,
+                                   FAR const char *name,
+                                   uint32_t dest)
+{
+  return !strcmp(name, CLK_RPMSG_EPT_NAME);
+}
+
 static void clk_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
                                   FAR void *priv_,
                                   FAR const char *name,
@@ -502,23 +515,20 @@ static void clk_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
 {
   FAR struct clk_rpmsg_server_s *priv;
 
-  if (!strcmp(name, CLK_RPMSG_EPT_NAME))
+  priv = kmm_zalloc(sizeof(struct clk_rpmsg_server_s));
+  if (!priv)
     {
-      priv = kmm_zalloc(sizeof(struct clk_rpmsg_server_s));
-      if (!priv)
-        {
-          return;
-        }
+      return;
+    }
 
-      priv->ept.priv = priv;
+  priv->ept.priv = priv;
 
-      list_initialize(&priv->clk_list);
+  list_initialize(&priv->clk_list);
 
-      rpmsg_create_ept(&priv->ept, rdev, name,
-                       RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
-                       clk_rpmsg_ept_cb,
-                       clk_rpmsg_server_unbind);
-    }
+  rpmsg_create_ept(&priv->ept, rdev, name,
+                   RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
+                   clk_rpmsg_ept_cb,
+                   clk_rpmsg_server_unbind);
 }
 
 static void clk_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept)
@@ -905,5 +915,6 @@ int clk_rpmsg_server_initialize(void)
   return rpmsg_register_callback(NULL,
                                  NULL,
                                  NULL,
+                                 clk_rpmsg_server_match,
                                  clk_rpmsg_server_bind);
 }
diff --git a/drivers/input/uinput.c b/drivers/input/uinput.c
index d8b84045d7..aedc939347 100644
--- a/drivers/input/uinput.c
+++ b/drivers/input/uinput.c
@@ -258,7 +258,7 @@ static int uinput_rpmsg_initialize(FAR struct uinput_context_s *ctx,
   list_initialize(&ctx->eptlist);
   strlcpy(ctx->name, name, UINPUT_NAME_SIZE);
   return rpmsg_register_callback(ctx, uinput_rpmsg_device_created,
-                                 uinput_rpmsg_device_destroy, NULL);
+                                 uinput_rpmsg_device_destroy, NULL, NULL);
 }
 
 /****************************************************************************
diff --git a/drivers/ioexpander/ioe_rpmsg.c b/drivers/ioexpander/ioe_rpmsg.c
index 8edf148aaa..dff6a28271 100755
--- a/drivers/ioexpander/ioe_rpmsg.c
+++ b/drivers/ioexpander/ioe_rpmsg.c
@@ -613,31 +613,37 @@ static void ioe_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept)
   kmm_free(ept);
 }
 
+static bool ioe_rpmsg_server_match(FAR struct rpmsg_device *rdev,
+                                   FAR void *priv_,
+                                   FAR const char *name,
+                                   uint32_t dest)
+{
+  FAR struct ioe_rpmsg_server_s *priv = priv_;
+  char eptname[RPMSG_NAME_SIZE];
+
+  snprintf(eptname, RPMSG_NAME_SIZE, IOE_RPMSG_EPT_FORMAT, priv->name);
+
+  return !strcmp(name, eptname);
+}
+
 static void ioe_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
                                   FAR void *priv_,
                                   FAR const char *name,
                                   uint32_t dest)
 {
   FAR struct ioe_rpmsg_server_s *priv = priv_;
-  char eptname[RPMSG_NAME_SIZE];
-
-  snprintf(eptname, RPMSG_NAME_SIZE, IOE_RPMSG_EPT_FORMAT, priv->name);
+  FAR struct rpmsg_endpoint *ept;
 
-  if (!strcmp(name, eptname))
+  ept = kmm_zalloc(sizeof(struct rpmsg_endpoint));
+  if (!ept)
     {
-      FAR struct rpmsg_endpoint *ept;
-
-      ept = kmm_zalloc(sizeof(struct rpmsg_endpoint));
-      if (!ept)
-        {
-          return;
-        }
+      return;
+    }
 
-      ept->priv = priv;
+  ept->priv = priv;
 
-      rpmsg_create_ept(ept, rdev, name, RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
-                       ioe_rpmsg_server_ept_cb, ioe_rpmsg_server_unbind);
-    }
+  rpmsg_create_ept(ept, rdev, name, RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
+                   ioe_rpmsg_server_ept_cb, ioe_rpmsg_server_unbind);
 }
 
 /****************************************************************************
@@ -672,7 +678,9 @@ int ioe_rpmsg_server_initialize(FAR const char *name,
   priv->name = name;
   priv->ioe  = ioe;
 
-  ret = rpmsg_register_callback(priv, NULL, NULL, ioe_rpmsg_server_bind);
+  ret = rpmsg_register_callback(priv, NULL, NULL,
+                                ioe_rpmsg_server_match,
+                                ioe_rpmsg_server_bind);
   if (ret < 0)
     {
       kmm_free(priv);
@@ -712,7 +720,7 @@ ioe_rpmsg_client_initialize(FAR const char *cpuname, FAR const char *name)
 
   nxsem_init(&priv->sem, 0, 0);
   ret = rpmsg_register_callback(priv, ioe_rpmsg_client_created,
-                                ioe_rpmsg_client_destroy, NULL);
+                                ioe_rpmsg_client_destroy, NULL, NULL);
   if (ret < 0)
     {
       kmm_free(priv);
diff --git a/drivers/net/rpmsgdrv.c b/drivers/net/rpmsgdrv.c
index 77b4273af9..e704f4c885 100644
--- a/drivers/net/rpmsgdrv.c
+++ b/drivers/net/rpmsgdrv.c
@@ -1200,6 +1200,7 @@ int net_rpmsg_drv_init(FAR const char *cpuname,
   rpmsg_register_callback(dev,
                           net_rpmsg_drv_device_created,
                           net_rpmsg_drv_device_destroy,
+                          NULL,
                           NULL);
 
   /* Register the device with the OS so that socket IOCTLs can be performed */
diff --git a/drivers/power/regulator_rpmsg.c b/drivers/power/regulator_rpmsg.c
index 689e999201..d1fa48be9e 100644
--- a/drivers/power/regulator_rpmsg.c
+++ b/drivers/power/regulator_rpmsg.c
@@ -136,6 +136,10 @@ static void regulator_rpmsg_client_destroy(struct rpmsg_device *rdev,
                                            FAR void *priv_);
 
 static void regulator_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept);
+static bool regulator_rpmsg_server_match(FAR struct rpmsg_device *rdev,
+                                         FAR void *priv_,
+                                         FAR const char *name,
+                                         uint32_t dest);
 static void regulator_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
                                         FAR void *priv_,
                                         FAR const char *name,
@@ -216,6 +220,7 @@ regulator_rpmsg_get_priv(FAR const char *name)
   rpmsg_register_callback(priv,
                           regulator_rpmsg_client_created,
                           regulator_rpmsg_client_destroy,
+                          NULL,
                           NULL);
 
   return priv;
@@ -347,6 +352,14 @@ static void regulator_rpmsg_server_unbind(FAR struct rpmsg_endpoint *ept)
   kmm_free(priv);
 }
 
+static bool regulator_rpmsg_server_match(FAR struct rpmsg_device *rdev,
+                                         FAR void *priv_,
+                                         FAR const char *name,
+                                         uint32_t dest)
+{
+  return !strcmp(name, REGULATOR_RPMSG_EPT_NAME);
+}
+
 static void regulator_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
                                         FAR void *priv_,
                                         FAR const char *name,
@@ -354,23 +367,20 @@ static void regulator_rpmsg_server_bind(FAR struct rpmsg_device *rdev,
 {
   FAR struct regulator_rpmsg_server_s *priv;
 
-  if (!strcmp(name, REGULATOR_RPMSG_EPT_NAME))
+  priv = kmm_zalloc(sizeof(struct regulator_rpmsg_server_s));
+  if (!priv)
     {
-      priv = kmm_zalloc(sizeof(struct regulator_rpmsg_server_s));
-      if (!priv)
-        {
-          return;
-        }
+      return;
+    }
 
-      priv->ept.priv = priv;
+  priv->ept.priv = priv;
 
-      list_initialize(&priv->regulator_list);
+  list_initialize(&priv->regulator_list);
 
-      rpmsg_create_ept(&priv->ept, rdev, name,
-                       RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
-                       regulator_rpmsg_ept_cb,
-                       regulator_rpmsg_server_unbind);
-    }
+  rpmsg_create_ept(&priv->ept, rdev, name,
+                   RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
+                   regulator_rpmsg_ept_cb,
+                   regulator_rpmsg_server_unbind);
 }
 
 static int regulator_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept,
@@ -695,5 +705,6 @@ int regulator_rpmsg_server_init(void)
   return rpmsg_register_callback(NULL,
                                  NULL,
                                  NULL,
+                                 regulator_rpmsg_server_match,
                                  regulator_rpmsg_server_bind);
 }
diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c
index b39211f2b6..d37034229f 100644
--- a/drivers/rptun/rptun.c
+++ b/drivers/rptun/rptun.c
@@ -100,6 +100,7 @@ struct rptun_cb_s
   FAR void          *priv;
   rpmsg_dev_cb_t    device_created;
   rpmsg_dev_cb_t    device_destroy;
+  rpmsg_match_cb_t  ns_match;
   rpmsg_bind_cb_t   ns_bind;
   struct metal_list node;
 };
@@ -480,33 +481,43 @@ static void rptun_ns_bind(FAR struct rpmsg_device *rdev,
 {
   FAR struct rptun_priv_s *priv = rptun_get_priv_by_rdev(rdev);
   FAR struct rptun_bind_s *bind;
+  FAR struct metal_list *node;
 
-  bind = kmm_malloc(sizeof(struct rptun_bind_s));
-  if (bind)
+  nxmutex_lock(&g_rptun_lockcb);
+
+  metal_list_for_each(&g_rptun_cb, node)
     {
-      FAR struct metal_list *node;
       FAR struct rptun_cb_s *cb;
 
-      bind->dest = dest;
-      strlcpy(bind->name, name, RPMSG_NAME_SIZE);
+      cb = metal_container_of(node, struct rptun_cb_s, node);
+      if (cb->ns_match && cb->ns_match(rdev, cb->priv, name, dest))
+        {
+          rpmsg_bind_cb_t ns_bind = cb->ns_bind;
+          FAR void *cb_priv = cb->priv;
 
-      nxmutex_lock(&g_rptun_lockcb);
+          nxmutex_unlock(&g_rptun_lockcb);
 
-      metal_list_for_each(&g_rptun_cb, node)
-        {
-          cb = metal_container_of(node, struct rptun_cb_s, node);
-          if (cb->ns_bind)
-            {
-              cb->ns_bind(rdev, cb->priv, name, dest);
-            }
+          DEBUGASSERT(ns_bind != NULL);
+          ns_bind(rdev, cb_priv, name, dest);
+
+          return;
         }
+    }
 
-      nxmutex_unlock(&g_rptun_lockcb);
+  nxmutex_unlock(&g_rptun_lockcb);
 
-      nxmutex_lock(&priv->lock);
-      metal_list_add_tail(&priv->bind, &bind->node);
-      nxmutex_unlock(&priv->lock);
+  bind = kmm_malloc(sizeof(struct rptun_bind_s));
+  if (bind == NULL)
+    {
+      return;
     }
+
+  bind->dest = dest;
+  strlcpy(bind->name, name, RPMSG_NAME_SIZE);
+
+  nxmutex_lock(&priv->lock);
+  metal_list_add_tail(&priv->bind, &bind->node);
+  nxmutex_unlock(&priv->lock);
 }
 
 static void rptun_ns_unbind(FAR struct rpmsg_device *rdev,
@@ -1016,6 +1027,7 @@ FAR const char *rpmsg_get_cpuname(FAR struct rpmsg_device *rdev)
 int rpmsg_register_callback(FAR void *priv_,
                             rpmsg_dev_cb_t device_created,
                             rpmsg_dev_cb_t device_destroy,
+                            rpmsg_match_cb_t ns_match,
                             rpmsg_bind_cb_t ns_bind)
 {
   FAR struct metal_list *node;
@@ -1031,6 +1043,7 @@ int rpmsg_register_callback(FAR void *priv_,
   cb->priv           = priv_;
   cb->device_created = device_created;
   cb->device_destroy = device_destroy;
+  cb->ns_match       = ns_match;
   cb->ns_bind        = ns_bind;
 
   nxmutex_lock(&g_rptun_lockpriv);
@@ -1045,20 +1058,32 @@ int rpmsg_register_callback(FAR void *priv_,
           device_created(&priv->rvdev.rdev, priv_);
         }
 
-      if (ns_bind)
+      if (ns_bind == NULL)
+        {
+          continue;
+        }
+
+      DEBUGASSERT(ns_match != NULL);
+again:
+      nxmutex_lock(&priv->lock);
+
+      metal_list_for_each(&priv->bind, bnode)
         {
-          nxmutex_lock(&priv->lock);
+          FAR struct rptun_bind_s *bind;
 
-          metal_list_for_each(&priv->bind, bnode)
+          bind = metal_container_of(bnode, struct rptun_bind_s, node);
+          if (ns_match(&priv->rvdev.rdev, priv_, bind->name, bind->dest))
             {
-              struct rptun_bind_s *bind;
+              metal_list_del(bnode);
+              nxmutex_unlock(&priv->lock);
 
-              bind = metal_container_of(bnode, struct rptun_bind_s, node);
               ns_bind(&priv->rvdev.rdev, priv_, bind->name, bind->dest);
+              kmm_free(bind);
+              goto again;
             }
-
-          nxmutex_unlock(&priv->lock);
         }
+
+      nxmutex_unlock(&priv->lock);
     }
 
   nxmutex_unlock(&g_rptun_lockpriv);
@@ -1073,6 +1098,7 @@ int rpmsg_register_callback(FAR void *priv_,
 void rpmsg_unregister_callback(FAR void *priv_,
                                rpmsg_dev_cb_t device_created,
                                rpmsg_dev_cb_t device_destroy,
+                               rpmsg_match_cb_t ns_match,
                                rpmsg_bind_cb_t ns_bind)
 {
   FAR struct metal_list *node;
@@ -1082,12 +1108,13 @@ void rpmsg_unregister_callback(FAR void *priv_,
 
   metal_list_for_each(&g_rptun_cb, node)
     {
-      struct rptun_cb_s *cb = NULL;
+      FAR struct rptun_cb_s *cb = NULL;
 
       cb = metal_container_of(node, struct rptun_cb_s, node);
       if (cb->priv == priv_ &&
           cb->device_created == device_created &&
           cb->device_destroy == device_destroy &&
+          cb->ns_match == ns_match &&
           cb->ns_bind == ns_bind)
         {
           metal_list_del(&cb->node);
diff --git a/drivers/serial/uart_rpmsg.c b/drivers/serial/uart_rpmsg.c
index 2db339f995..351f82ee72 100644
--- a/drivers/serial/uart_rpmsg.c
+++ b/drivers/serial/uart_rpmsg.c
@@ -434,6 +434,7 @@ int uart_rpmsg_init(FAR const char *cpuname, FAR const char *devname,
   ret = rpmsg_register_callback(dev,
                                 uart_rpmsg_device_created,
                                 uart_rpmsg_device_destroy,
+                                NULL,
                                 NULL);
   if (ret < 0)
     {
diff --git a/drivers/syslog/syslog_rpmsg.c b/drivers/syslog/syslog_rpmsg.c
index b97b7218a2..f4337e46f7 100644
--- a/drivers/syslog/syslog_rpmsg.c
+++ b/drivers/syslog/syslog_rpmsg.c
@@ -450,5 +450,6 @@ int syslog_rpmsg_init(void)
   return rpmsg_register_callback(&g_syslog_rpmsg,
                                  syslog_rpmsg_device_created,
                                  syslog_rpmsg_device_destroy,
+                                 NULL,
                                  NULL);
 }
diff --git a/drivers/syslog/syslog_rpmsg_server.c b/drivers/syslog/syslog_rpmsg_server.c
index bef35833d8..068bee7e42 100644
--- a/drivers/syslog/syslog_rpmsg_server.c
+++ b/drivers/syslog/syslog_rpmsg_server.c
@@ -63,6 +63,9 @@ struct syslog_rpmsg_server_s
 
 static void syslog_rpmsg_write(FAR const char *buf1, size_t len1,
                                FAR const char *buf2, size_t len2);
+static bool syslog_rpmsg_ns_match(FAR struct rpmsg_device *rdev,
+                                  FAR void *priv_, FAR const char *name,
+                                  uint32_t dest);
 static void syslog_rpmsg_ns_bind(FAR struct rpmsg_device *rdev,
                                  FAR void *priv_, FAR const char *name,
                                  uint32_t dest);
@@ -167,6 +170,13 @@ static void syslog_rpmsg_write(FAR const char *buf1, size_t len1,
     }
 }
 
+static bool syslog_rpmsg_ns_match(FAR struct rpmsg_device *rdev,
+                                  FAR void *priv_, FAR const char *name,
+                                  uint32_t dest)
+{
+  return !strcmp(name, SYSLOG_RPMSG_EPT_NAME);
+}
+
 static void syslog_rpmsg_ns_bind(FAR struct rpmsg_device *rdev,
                                  FAR void *priv_, FAR const char *name,
                                  uint32_t dest)
@@ -174,11 +184,6 @@ static void syslog_rpmsg_ns_bind(FAR struct rpmsg_device *rdev,
   FAR struct syslog_rpmsg_server_s *priv;
   int ret;
 
-  if (strcmp(name, SYSLOG_RPMSG_EPT_NAME))
-    {
-      return;
-    }
-
   priv = kmm_zalloc(sizeof(struct syslog_rpmsg_server_s));
   if (!priv)
     {
@@ -308,5 +313,6 @@ int syslog_rpmsg_server_init(void)
   return rpmsg_register_callback(NULL,
                                  NULL,
                                  NULL,
+                                 syslog_rpmsg_ns_match,
                                  syslog_rpmsg_ns_bind);
 }
diff --git a/drivers/timers/rpmsg_rtc.c b/drivers/timers/rpmsg_rtc.c
index 233c19a18c..bc37db5d6c 100644
--- a/drivers/timers/rpmsg_rtc.c
+++ b/drivers/timers/rpmsg_rtc.c
@@ -696,6 +696,14 @@ static int rpmsg_rtc_server_ept_cb(FAR struct rpmsg_endpoint *ept,
     }
 }
 
+static bool rpmsg_rtc_server_ns_match(FAR struct rpmsg_device *rdev,
+                                      FAR void *priv,
+                                      FAR const char *name,
+                                      uint32_t dest)
+{
+  return !strcmp(name, RPMSG_RTC_EPT_NAME);
+}
+
 static void rpmsg_rtc_server_ns_bind(FAR struct rpmsg_device *rdev,
                                      FAR void *priv,
                                      FAR const char *name,
@@ -706,11 +714,6 @@ static void rpmsg_rtc_server_ns_bind(FAR struct rpmsg_device *rdev,
   struct rpmsg_rtc_set_s msg;
   struct rtc_time rtctime;
 
-  if (strcmp(name, RPMSG_RTC_EPT_NAME))
-    {
-      return;
-    }
-
   client = kmm_zalloc(sizeof(*client));
   if (client == NULL)
     {
@@ -767,6 +770,7 @@ FAR struct rtc_lowerhalf_s *rpmsg_rtc_initialize(void)
       rpmsg_register_callback(lower,
                               rpmsg_rtc_device_created,
                               rpmsg_rtc_device_destroy,
+                              NULL,
                               NULL);
     }
 
@@ -800,6 +804,7 @@ FAR struct rtc_lowerhalf_s *rpmsg_rtc_server_initialize(
       list_initialize(&server->list);
       nxsem_init(&server->exclsem, 0, 1);
       if (rpmsg_register_callback(server, NULL, NULL,
+                                  rpmsg_rtc_server_ns_match,
                                   rpmsg_rtc_server_ns_bind) < 0)
         {
           nxsem_destroy(&server->exclsem);
diff --git a/fs/rpmsgfs/rpmsgfs_client.c b/fs/rpmsgfs/rpmsgfs_client.c
index 670031a557..dd8ccfa1bb 100644
--- a/fs/rpmsgfs/rpmsgfs_client.c
+++ b/fs/rpmsgfs/rpmsgfs_client.c
@@ -717,6 +717,7 @@ int rpmsgfs_client_bind(FAR void **handle, FAR const char *cpuname)
   ret = rpmsg_register_callback(priv,
                                 rpmsgfs_device_created,
                                 rpmsgfs_device_destroy,
+                                NULL,
                                 NULL);
   if (ret < 0)
     {
@@ -738,6 +739,7 @@ int rpmsgfs_client_unbind(FAR void *handle)
   rpmsg_unregister_callback(priv,
                             rpmsgfs_device_created,
                             rpmsgfs_device_destroy,
+                            NULL,
                             NULL);
 
   nxsem_destroy(&priv->wait);
diff --git a/fs/rpmsgfs/rpmsgfs_server.c b/fs/rpmsgfs/rpmsgfs_server.c
index 23175ed49d..e34631933b 100644
--- a/fs/rpmsgfs/rpmsgfs_server.c
+++ b/fs/rpmsgfs/rpmsgfs_server.c
@@ -123,6 +123,9 @@ static int rpmsgfs_chstat_handler(FAR struct rpmsg_endpoint *ept,
                                   FAR void *data, size_t len,
                                   uint32_t src, FAR void *priv);
 
+static bool rpmsgfs_ns_match(FAR struct rpmsg_device *rdev,
+                             FAR void *priv_, FAR const char *name,
+                             uint32_t dest);
 static void rpmsgfs_ns_bind(FAR struct rpmsg_device *rdev,
                             FAR void *priv_, FAR const char *name,
                             uint32_t dest);
@@ -826,6 +829,13 @@ out:
   return rpmsg_send(ept, msg, sizeof(*msg));
 }
 
+static bool rpmsgfs_ns_match(FAR struct rpmsg_device *rdev,
+                             FAR void *priv_, FAR const char *name,
+                             uint32_t dest)
+{
+  return !strncmp(name, RPMSGFS_NAME_PREFIX, strlen(RPMSGFS_NAME_PREFIX));
+}
+
 static void rpmsgfs_ns_bind(FAR struct rpmsg_device *rdev,
                             FAR void *priv_, FAR const char *name,
                             uint32_t dest)
@@ -833,11 +843,6 @@ static void rpmsgfs_ns_bind(FAR struct rpmsg_device *rdev,
   FAR struct rpmsgfs_server_s *priv;
   int ret;
 
-  if (strncmp(name, RPMSGFS_NAME_PREFIX, strlen(RPMSGFS_NAME_PREFIX)))
-    {
-      return;
-    }
-
   priv = kmm_zalloc(sizeof(*priv));
   if (!priv)
     {
@@ -912,5 +917,6 @@ int rpmsgfs_server_init(void)
   return rpmsg_register_callback(NULL,
                                  NULL,
                                  NULL,
+                                 rpmsgfs_ns_match,
                                  rpmsgfs_ns_bind);
 }
diff --git a/include/nuttx/rptun/openamp.h b/include/nuttx/rptun/openamp.h
index 833c477a1a..98f4d54c6d 100644
--- a/include/nuttx/rptun/openamp.h
+++ b/include/nuttx/rptun/openamp.h
@@ -38,6 +38,9 @@
 
 typedef void (*rpmsg_dev_cb_t)(FAR struct rpmsg_device *rdev,
                                FAR void *priv);
+typedef bool (*rpmsg_match_cb_t)(FAR struct rpmsg_device *rdev,
+                                 FAR void *priv, FAR const char *name,
+                                 uint32_t dest);
 typedef void (*rpmsg_bind_cb_t)(FAR struct rpmsg_device *rdev,
                                 FAR void *priv, FAR const char *name,
                                 uint32_t dest);
@@ -62,10 +65,12 @@ const char *rpmsg_get_cpuname(FAR struct rpmsg_device *rdev);
 int rpmsg_register_callback(FAR void *priv,
                             rpmsg_dev_cb_t device_created,
                             rpmsg_dev_cb_t device_destroy,
+                            rpmsg_match_cb_t ns_match,
                             rpmsg_bind_cb_t ns_bind);
 void rpmsg_unregister_callback(FAR void *priv,
                                rpmsg_dev_cb_t device_created,
                                rpmsg_dev_cb_t device_destroy,
+                               rpmsg_match_cb_t ns_match,
                                rpmsg_bind_cb_t ns_bind);
 
 #ifdef __cplusplus
diff --git a/net/rpmsg/rpmsg_sockif.c b/net/rpmsg/rpmsg_sockif.c
index 624457ed2e..bd04dd2f6c 100644
--- a/net/rpmsg/rpmsg_sockif.c
+++ b/net/rpmsg/rpmsg_sockif.c
@@ -468,22 +468,18 @@ static void rpmsg_socket_device_destroy(FAR struct rpmsg_device *rdev,
     }
 }
 
-static void rpmsg_socket_ns_bind(FAR struct rpmsg_device *rdev,
-                                 FAR void *priv, FAR const char *name,
-                                 uint32_t dest)
+static bool rpmsg_socket_ns_match(FAR struct rpmsg_device *rdev,
+                                  FAR void *priv, FAR const char *name,
+                                  uint32_t dest)
 {
   FAR struct rpmsg_socket_conn_s *server = priv;
-  FAR struct rpmsg_socket_conn_s *tmp;
-  FAR struct rpmsg_socket_conn_s *new;
   char buf[RPMSG_NAME_SIZE];
-  int cnt = 0;
-  int ret;
 
   snprintf(buf, sizeof(buf), "%s%s", RPMSG_SOCKET_NAME_PREFIX,
            server->rpaddr.rp_name);
   if (strncmp(name, buf, strlen(buf)))
     {
-      return;
+      return false;
     }
 
   if (strlen(server->rpaddr.rp_cpu) &&
@@ -491,9 +487,22 @@ static void rpmsg_socket_ns_bind(FAR struct rpmsg_device *rdev,
     {
       /* Bind specific CPU, then only listen that CPU */
 
-      return;
+      return false;
     }
 
+  return true;
+}
+
+static void rpmsg_socket_ns_bind(FAR struct rpmsg_device *rdev,
+                                 FAR void *priv, FAR const char *name,
+                                 uint32_t dest)
+{
+  FAR struct rpmsg_socket_conn_s *server = priv;
+  FAR struct rpmsg_socket_conn_s *tmp;
+  FAR struct rpmsg_socket_conn_s *new;
+  int cnt = 0;
+  int ret;
+
   new = rpmsg_socket_alloc();
   if (!new)
     {
@@ -662,9 +671,10 @@ static int rpmsg_socket_listen(FAR struct socket *psock, int backlog)
 
   server->backlog = backlog;
   return rpmsg_register_callback(server,
-                                NULL,
-                                NULL,
-                                rpmsg_socket_ns_bind);
+                                 NULL,
+                                 NULL,
+                                 rpmsg_socket_ns_match,
+                                 rpmsg_socket_ns_bind);
 }
 
 static int rpmsg_socket_connect_internal(FAR struct socket *psock)
@@ -681,6 +691,7 @@ static int rpmsg_socket_connect_internal(FAR struct socket *psock)
   ret = rpmsg_register_callback(conn,
                                 rpmsg_socket_device_created,
                                 rpmsg_socket_device_destroy,
+                                NULL,
                                 NULL);
   if (ret < 0)
     {
@@ -702,6 +713,7 @@ static int rpmsg_socket_connect_internal(FAR struct socket *psock)
           rpmsg_unregister_callback(conn,
                                     rpmsg_socket_device_created,
                                     rpmsg_socket_device_destroy,
+                                    NULL,
                                     NULL);
         }
     }
@@ -769,6 +781,7 @@ static int rpmsg_socket_accept(FAR struct socket *psock,
           rpmsg_register_callback(conn,
                                   rpmsg_socket_device_created,
                                   rpmsg_socket_device_destroy,
+                                  NULL,
                                   NULL);
 
           if (conn->sendsize == 0)
@@ -1280,6 +1293,7 @@ static int rpmsg_socket_close(FAR struct socket *psock)
       rpmsg_unregister_callback(conn,
                                 NULL,
                                 NULL,
+                                rpmsg_socket_ns_match,
                                 rpmsg_socket_ns_bind);
     }
   else
@@ -1287,6 +1301,7 @@ static int rpmsg_socket_close(FAR struct socket *psock)
       rpmsg_unregister_callback(conn,
                                 rpmsg_socket_device_created,
                                 rpmsg_socket_device_destroy,
+                                NULL,
                                 NULL);
     }