You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pk...@apache.org on 2022/03/30 07:00:20 UTC
[incubator-nuttx] 06/13: rptun: add rpmsg_wait/post support for recursive dispatch
This is an automated email from the ASF dual-hosted git repository.
pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit be49f6b87c40248a93129458c34e02a1cf5a126e
Author: ligd <li...@xiaomi.com>
AuthorDate: Tue Jan 18 15:51:24 2022 +0800
rptun: add rpmsg_wait/post support for recursive dispatch
Signed-off-by: ligd <li...@xiaomi.com>
---
drivers/rptun/Kconfig | 4 --
drivers/rptun/rptun.c | 152 +++++++++++++++++++++++++++++++++---------
include/nuttx/rptun/openamp.h | 3 +
3 files changed, 125 insertions(+), 34 deletions(-)
diff --git a/drivers/rptun/Kconfig b/drivers/rptun/Kconfig
index d7bf6b5..a3e4487 100644
--- a/drivers/rptun/Kconfig
+++ b/drivers/rptun/Kconfig
@@ -34,10 +34,6 @@ config RPTUN_STACKSIZE
depends on RPTUN_THREAD
default 4096
-config RPTUN_RECURSIVE_DISPATCH
- bool "rptun recursive dispatch"
- default y
-
config RPTUN_LOADER
bool "rptun loader support"
default n
diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c
index 3323e66..f016b02 100644
--- a/drivers/rptun/rptun.c
+++ b/drivers/rptun/rptun.c
@@ -69,10 +69,10 @@ struct rptun_priv_s
struct rpmsg_virtio_shm_pool shm_pool;
struct metal_list bind;
struct metal_list node;
+ sem_t sem;
#ifdef CONFIG_RPTUN_WORKQUEUE
struct work_s work;
#else
- sem_t sem;
int tid;
#endif
unsigned long cmd;
@@ -119,7 +119,7 @@ rptun_get_mem(FAR struct remoteproc *rproc,
metal_phys_addr_t da,
FAR void *va, size_t size,
FAR struct remoteproc_mem *buf);
-static int rptun_can_recursive(FAR struct remoteproc *rproc);
+static int rptun_wait_tx_buffer(FAR struct remoteproc *rproc);
static void rptun_ns_bind(FAR struct rpmsg_device *rdev,
FAR const char *name, uint32_t dest);
@@ -152,14 +152,14 @@ static metal_phys_addr_t rptun_da_to_pa(FAR struct rptun_dev_s *dev,
static struct remoteproc_ops g_rptun_ops =
{
- .init = rptun_init,
- .remove = rptun_remove,
- .config = rptun_config,
- .start = rptun_start,
- .stop = rptun_stop,
- .notify = rptun_notify,
- .get_mem = rptun_get_mem,
- .can_recursive = rptun_can_recursive,
+ .init = rptun_init,
+ .remove = rptun_remove,
+ .config = rptun_config,
+ .start = rptun_start,
+ .stop = rptun_stop,
+ .notify = rptun_notify,
+ .get_mem = rptun_get_mem,
+ .wait_tx_buffer = rptun_wait_tx_buffer,
};
static const struct file_operations g_rptun_devops =
@@ -274,11 +274,39 @@ static void rptun_worker(FAR void *arg)
remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL);
}
+static void rptun_post(FAR struct rptun_priv_s *priv)
+{
+ int semcount;
+
+ nxsem_get_value(&priv->sem, &semcount);
+ while (semcount++ < 1)
+ {
+ nxsem_post(&priv->sem);
+ }
+}
+
#ifdef CONFIG_RPTUN_WORKQUEUE
static void rptun_wakeup(FAR struct rptun_priv_s *priv)
{
work_queue(HPWORK, &priv->work, rptun_worker, priv, 0);
+ rptun_post(priv);
+}
+
+static void rptun_in_recursive(int tid, FAR void *arg)
+{
+ if (gettid() == tid)
+ {
+ *((FAR bool *)arg) = true;
+ }
+}
+
+static bool rptun_is_recursive(FAR struct rptun_priv_s *priv)
+{
+ bool in = false;
+ work_foreach(HPWORK, rptun_in_recursive, &in);
+ return in;
}
+
#else
static int rptun_thread(int argc, FAR char *argv[])
{
@@ -298,13 +326,12 @@ static int rptun_thread(int argc, FAR char *argv[])
static void rptun_wakeup(FAR struct rptun_priv_s *priv)
{
- int semcount;
+ rptun_post(priv);
+}
- nxsem_get_value(&priv->sem, &semcount);
- if (semcount < 1)
- {
- nxsem_post(&priv->sem);
- }
+static bool rptun_is_recursive(FAR struct rptun_priv_s *priv)
+{
+ return gettid() == priv->tid;
}
#endif
@@ -434,16 +461,21 @@ rptun_get_mem(FAR struct remoteproc *rproc,
return buf;
}
-static int rptun_can_recursive(FAR struct remoteproc *rproc)
+static int rptun_wait_tx_buffer(FAR struct remoteproc *rproc)
{
-#ifndef CONFIG_RPTUN_RECURSIVE_DISPATCH
- return false;
-#elif defined(CONFIG_RPTUN_WORKQUEUE)
- return work_in_context(HPWORK);
-#else
FAR struct rptun_priv_s *priv = rproc->priv;
- return gettid() == priv->tid;
-#endif
+
+ if (!rptun_is_recursive(priv))
+ {
+ return -EAGAIN;
+ }
+
+ /* Wait to wakeup */
+
+ nxsem_wait(&priv->sem);
+ rptun_worker(priv);
+
+ return 0;
}
static void *rptun_get_priv_by_rdev(FAR struct rpmsg_device *rdev)
@@ -453,6 +485,11 @@ static void *rptun_get_priv_by_rdev(FAR struct rpmsg_device *rdev)
struct remoteproc_virtio *rpvdev;
struct remoteproc *rproc;
+ if (!rdev)
+ {
+ return NULL;
+ }
+
rvdev = metal_container_of(rdev, struct rpmsg_virtio_device, rdev);
vdev = rvdev->vdev;
if (!vdev)
@@ -656,6 +693,10 @@ static int rptun_dev_start(FAR struct remoteproc *rproc)
rptun_lock();
+ /* Register callback to mbox for receiving remote message */
+
+ RPTUN_REGISTER_CALLBACK(priv->dev, rptun_callback, priv);
+
/* Add priv to list */
metal_list_add_tail(&g_rptun_priv, &priv->node);
@@ -673,10 +714,6 @@ static int rptun_dev_start(FAR struct remoteproc *rproc)
rptun_unlock();
- /* Register callback to mbox for receiving remote message */
-
- RPTUN_REGISTER_CALLBACK(priv->dev, rptun_callback, priv);
-
return 0;
}
@@ -880,6 +917,60 @@ static metal_phys_addr_t rptun_da_to_pa(FAR struct rptun_dev_s *dev,
* Public Functions
****************************************************************************/
+int rpmsg_wait(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem)
+{
+ FAR struct rptun_priv_s *priv;
+ int ret;
+
+ if (!ept)
+ {
+ return -EINVAL;
+ }
+
+ priv = rptun_get_priv_by_rdev(ept->rdev);
+ if (!priv || !rptun_is_recursive(priv))
+ {
+ return nxsem_wait_uninterruptible(sem);
+ }
+
+ while (1)
+ {
+ ret = nxsem_trywait(sem);
+ if (ret >= 0)
+ {
+ break;
+ }
+
+ nxsem_wait(&priv->sem);
+ rptun_worker(priv);
+ }
+
+ return ret;
+}
+
+int rpmsg_post(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem)
+{
+ FAR struct rptun_priv_s *priv;
+ int semcount;
+ int ret;
+
+ if (!ept)
+ {
+ return -EINVAL;
+ }
+
+ nxsem_get_value(sem, &semcount);
+ ret = nxsem_post(sem);
+
+ priv = rptun_get_priv_by_rdev(ept->rdev);
+ if (priv && semcount >= 0)
+ {
+ rptun_post(priv);
+ }
+
+ return ret;
+}
+
FAR const char *rpmsg_get_cpuname(FAR struct rpmsg_device *rdev)
{
FAR struct rptun_priv_s *priv = rptun_get_priv_by_rdev(rdev);
@@ -1022,6 +1113,8 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
priv->cmd = RPTUNIOC_START;
work_queue(HPWORK, &priv->work, rptun_worker, priv, 0);
}
+
+ nxsem_init(&priv->sem, 0, 0);
#else
if (RPTUN_IS_AUTOSTART(dev))
{
@@ -1033,8 +1126,6 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
nxsem_init(&priv->sem, 0, 0);
}
- nxsem_set_protocol(&priv->sem, SEM_PRIO_NONE);
-
snprintf(arg1, sizeof(arg1), "0x%" PRIxPTR, (uintptr_t)priv);
argv[0] = (void *)RPTUN_GET_CPUNAME(dev);
argv[1] = arg1;
@@ -1049,6 +1140,7 @@ int rptun_initialize(FAR struct rptun_dev_s *dev)
goto err_driver;
}
#endif
+ nxsem_set_protocol(&priv->sem, SEM_PRIO_NONE);
return OK;
diff --git a/include/nuttx/rptun/openamp.h b/include/nuttx/rptun/openamp.h
index 8a96b98..365e2bc 100644
--- a/include/nuttx/rptun/openamp.h
+++ b/include/nuttx/rptun/openamp.h
@@ -54,6 +54,9 @@ extern "C"
#define EXTERN extern
#endif
+int rpmsg_wait(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem);
+int rpmsg_post(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem);
+
const char *rpmsg_get_cpuname(FAR struct rpmsg_device *rdev);
int rpmsg_register_callback(FAR void *priv,
rpmsg_dev_cb_t device_created,