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

View file

@ -32,6 +32,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/mutex.h>
#include <nuttx/fs/fs.h>
#include <nuttx/wqueue.h>
#include <nuttx/drivers/rpmsgdev.h>
#include <nuttx/rptun/openamp.h>
@ -62,6 +63,7 @@ struct rpmsgdev_server_s
mutex_t lock; /* The mutex used to protect the list
* 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,
FAR void *data, size_t len,
uint32_t src, FAR void *priv);
static void rpmsgdev_poll_worker(FAR void *arg);
static void rpmsgdev_poll_cb(FAR struct pollfd *fds);
static int rpmsgdev_poll_handler(FAR struct rpmsg_endpoint *ept,
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_device_s *dev =
container_of(fds, FAR struct rpmsgdev_device_s, fd);
FAR struct rpmsgdev_notify_s msg;
DEBUGASSERT(fds != NULL && dev->cfd != 0);
DEBUGASSERT(dev->cfd != 0);
msg.header.command = RPMSGDEV_NOTIFY;
msg.revents = fds->revents;
@ -330,6 +334,20 @@ static void rpmsgdev_poll_cb(FAR struct pollfd *fds)
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
****************************************************************************/