rpmsg: use workqueue for rpmsgdev poll notify

use workqueue for rpmsgdev poll notify to prevent
calling rpmsgdev_poll_cb in interrupt context which
will try to hold mutex in rpmsg_send

Signed-off-by: liaoao <liaoao@xiaomi.com>
This commit is contained in:
liaoao
2023-06-26 16:34:13 +08:00
committed by Xiang Xiao
parent a7926405ca
commit e8c6eb0aba
+21 -3
View File
@@ -32,6 +32,7 @@
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include <nuttx/mutex.h> #include <nuttx/mutex.h>
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
#include <nuttx/wqueue.h>
#include <nuttx/drivers/rpmsgdev.h> #include <nuttx/drivers/rpmsgdev.h>
#include <nuttx/rptun/openamp.h> #include <nuttx/rptun/openamp.h>
@@ -62,6 +63,7 @@ struct rpmsgdev_server_s
mutex_t lock; /* The mutex used to protect the list mutex_t lock; /* The mutex used to protect the list
* operation * operation
*/ */
struct work_s work; /* Poll notify work */
}; };
/**************************************************************************** /****************************************************************************
@@ -88,6 +90,7 @@ static int rpmsgdev_lseek_handler(FAR struct rpmsg_endpoint *ept,
static int rpmsgdev_ioctl_handler(FAR struct rpmsg_endpoint *ept, static int rpmsgdev_ioctl_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len, FAR void *data, size_t len,
uint32_t src, FAR void *priv); uint32_t src, FAR void *priv);
static void rpmsgdev_poll_worker(FAR void *arg);
static void rpmsgdev_poll_cb(FAR struct pollfd *fds); static void rpmsgdev_poll_cb(FAR struct pollfd *fds);
static int rpmsgdev_poll_handler(FAR struct rpmsg_endpoint *ept, static int rpmsgdev_poll_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len, FAR void *data, size_t len,
@@ -309,17 +312,18 @@ static int rpmsgdev_ioctl_handler(FAR struct rpmsg_endpoint *ept,
} }
/**************************************************************************** /****************************************************************************
* Name: rpmsgdev_poll_cb * Name: rpmsgdev_poll_worker
****************************************************************************/ ****************************************************************************/
static void rpmsgdev_poll_cb(FAR struct pollfd *fds) static void rpmsgdev_poll_worker(FAR void *arg)
{ {
FAR struct pollfd *fds = arg;
FAR struct rpmsgdev_server_s *server = fds->arg; FAR struct rpmsgdev_server_s *server = fds->arg;
FAR struct rpmsgdev_device_s *dev = FAR struct rpmsgdev_device_s *dev =
container_of(fds, FAR struct rpmsgdev_device_s, fd); container_of(fds, FAR struct rpmsgdev_device_s, fd);
FAR struct rpmsgdev_notify_s msg; FAR struct rpmsgdev_notify_s msg;
DEBUGASSERT(fds != NULL && dev->cfd != 0); DEBUGASSERT(dev->cfd != 0);
msg.header.command = RPMSGDEV_NOTIFY; msg.header.command = RPMSGDEV_NOTIFY;
msg.revents = fds->revents; msg.revents = fds->revents;
@@ -330,6 +334,20 @@ static void rpmsgdev_poll_cb(FAR struct pollfd *fds)
rpmsg_send(&server->ept, &msg, sizeof(msg)); rpmsg_send(&server->ept, &msg, sizeof(msg));
} }
/****************************************************************************
* Name: rpmsgdev_poll_cb
****************************************************************************/
static void rpmsgdev_poll_cb(FAR struct pollfd *fds)
{
FAR struct rpmsgdev_server_s *server;
DEBUGASSERT(fds != NULL);
server = fds->arg;
work_queue(HPWORK, &server->work, rpmsgdev_poll_worker, fds, 0);
}
/**************************************************************************** /****************************************************************************
* Name: rpmsgdev_poll_handler * Name: rpmsgdev_poll_handler
****************************************************************************/ ****************************************************************************/