From be49f6b87c40248a93129458c34e02a1cf5a126e Mon Sep 17 00:00:00 2001 From: ligd Date: Tue, 18 Jan 2022 15:51:24 +0800 Subject: [PATCH] rptun: add rpmsg_wait/post support for recursive dispatch Signed-off-by: ligd --- 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 d7bf6b53d2..a3e448740f 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 3323e66dfa..f016b02c2e 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 8a96b98889..365e2bcc53 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,