drivers/sensors: sensor deadlock fix.

using read-write lock to avoid deadlock

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
dongjiuzhu1
2025-01-21 22:44:34 +08:00
committed by Xiang Xiao
parent 6a8262314f
commit f9c5647813
+22 -21
View File
@@ -33,6 +33,7 @@
#include <nuttx/list.h> #include <nuttx/list.h>
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include <nuttx/mutex.h> #include <nuttx/mutex.h>
#include <nuttx/rwsem.h>
#include <nuttx/sensors/sensor.h> #include <nuttx/sensors/sensor.h>
#include <nuttx/rpmsg/rpmsg.h> #include <nuttx/rpmsg/rpmsg.h>
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
@@ -291,8 +292,8 @@ static const rpmsg_ept_cb g_sensor_rpmsg_handler[] =
static struct list_node g_devlist = LIST_INITIAL_VALUE(g_devlist); static struct list_node g_devlist = LIST_INITIAL_VALUE(g_devlist);
static struct list_node g_eptlist = LIST_INITIAL_VALUE(g_eptlist); static struct list_node g_eptlist = LIST_INITIAL_VALUE(g_eptlist);
static rmutex_t g_ept_lock = NXRMUTEX_INITIALIZER; static rw_semaphore_t g_ept_lock = RWSEM_INITIALIZER;
static rmutex_t g_dev_lock = NXRMUTEX_INITIALIZER; static rw_semaphore_t g_dev_lock = RWSEM_INITIALIZER;
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
@@ -346,14 +347,14 @@ static void sensor_rpmsg_advsub(FAR struct sensor_rpmsg_dev_s *dev,
/* Broadcast advertise/subscribe message to all ready ept */ /* Broadcast advertise/subscribe message to all ready ept */
nxrmutex_lock(&g_ept_lock); down_read(&g_ept_lock);
list_for_every_entry(&g_eptlist, sre, struct sensor_rpmsg_ept_s, list_for_every_entry(&g_eptlist, sre, struct sensor_rpmsg_ept_s,
node) node)
{ {
sensor_rpmsg_advsub_one(dev, &sre->ept, command); sensor_rpmsg_advsub_one(dev, &sre->ept, command);
} }
nxrmutex_unlock(&g_ept_lock); up_read(&g_ept_lock);
} }
static int sensor_rpmsg_ioctl(FAR struct sensor_rpmsg_dev_s *dev, static int sensor_rpmsg_ioctl(FAR struct sensor_rpmsg_dev_s *dev,
@@ -1029,17 +1030,17 @@ sensor_rpmsg_find_dev(FAR const char *path)
{ {
FAR struct sensor_rpmsg_dev_s *dev; FAR struct sensor_rpmsg_dev_s *dev;
nxrmutex_lock(&g_dev_lock); down_read(&g_dev_lock);
list_for_every_entry(&g_devlist, dev, struct sensor_rpmsg_dev_s, node) list_for_every_entry(&g_devlist, dev, struct sensor_rpmsg_dev_s, node)
{ {
if (strcmp(dev->path, path) == 0) if (strcmp(dev->path, path) == 0)
{ {
nxrmutex_unlock(&g_dev_lock); up_read(&g_dev_lock);
return dev; return dev;
} }
} }
nxrmutex_unlock(&g_dev_lock); up_read(&g_dev_lock);
return NULL; return NULL;
} }
@@ -1360,13 +1361,13 @@ static void sensor_rpmsg_device_ns_bound(FAR struct rpmsg_endpoint *ept)
sre = container_of(ept, struct sensor_rpmsg_ept_s, ept); sre = container_of(ept, struct sensor_rpmsg_ept_s, ept);
nxrmutex_lock(&g_ept_lock); down_write(&g_ept_lock);
list_add_tail(&g_eptlist, &sre->node); list_add_tail(&g_eptlist, &sre->node);
nxrmutex_unlock(&g_ept_lock); up_write(&g_ept_lock);
/* Broadcast all device to ready ept */ /* Broadcast all device to ready ept */
nxrmutex_lock(&g_dev_lock); down_read(&g_dev_lock);
list_for_every_entry(&g_devlist, dev, list_for_every_entry(&g_devlist, dev,
struct sensor_rpmsg_dev_s, node) struct sensor_rpmsg_dev_s, node)
{ {
@@ -1384,7 +1385,7 @@ static void sensor_rpmsg_device_ns_bound(FAR struct rpmsg_endpoint *ept)
sensor_rpmsg_unlock(dev); sensor_rpmsg_unlock(dev);
} }
nxrmutex_unlock(&g_dev_lock); up_read(&g_dev_lock);
} }
static void sensor_rpmsg_ept_release(FAR struct rpmsg_endpoint *ept) static void sensor_rpmsg_ept_release(FAR struct rpmsg_endpoint *ept)
@@ -1400,7 +1401,7 @@ static void sensor_rpmsg_ept_release(FAR struct rpmsg_endpoint *ept)
* destroyed. * destroyed.
*/ */
nxrmutex_lock(&g_dev_lock); down_read(&g_dev_lock);
list_for_every_entry(&g_devlist, dev, list_for_every_entry(&g_devlist, dev,
struct sensor_rpmsg_dev_s, node) struct sensor_rpmsg_dev_s, node)
{ {
@@ -1428,15 +1429,15 @@ static void sensor_rpmsg_ept_release(FAR struct rpmsg_endpoint *ept)
sensor_rpmsg_unlock(dev); sensor_rpmsg_unlock(dev);
} }
nxrmutex_unlock(&g_dev_lock); up_read(&g_dev_lock);
nxrmutex_lock(&g_ept_lock); down_write(&g_ept_lock);
if (list_in_list(&sre->node)) if (list_in_list(&sre->node))
{ {
list_delete(&sre->node); list_delete(&sre->node);
} }
nxrmutex_unlock(&g_ept_lock); up_write(&g_ept_lock);
nxrmutex_destroy(&sre->lock); nxrmutex_destroy(&sre->lock);
kmm_free(sre); kmm_free(sre);
@@ -1527,19 +1528,19 @@ sensor_rpmsg_register(FAR struct sensor_lowerhalf_s *lower,
/* If openamp is ready, send advertisement to remote proc */ /* If openamp is ready, send advertisement to remote proc */
nxrmutex_lock(&g_dev_lock); down_write(&g_dev_lock);
list_add_tail(&g_devlist, &dev->node); list_add_tail(&g_devlist, &dev->node);
nxrmutex_unlock(&g_dev_lock); up_write(&g_dev_lock);
if (lower->ops->activate) if (lower->ops->activate)
{ {
nxrmutex_lock(&g_ept_lock); down_read(&g_ept_lock);
list_for_every_entry(&g_eptlist, sre, struct sensor_rpmsg_ept_s, list_for_every_entry(&g_eptlist, sre, struct sensor_rpmsg_ept_s,
node) node)
{ {
sensor_rpmsg_advsub_one(dev, &sre->ept, SENSOR_RPMSG_ADVERTISE); sensor_rpmsg_advsub_one(dev, &sre->ept, SENSOR_RPMSG_ADVERTISE);
} }
nxrmutex_unlock(&g_ept_lock); up_read(&g_ept_lock);
} }
return &dev->lower; return &dev->lower;
@@ -1566,9 +1567,9 @@ void sensor_rpmsg_unregister(FAR struct sensor_lowerhalf_s *lower)
return; return;
} }
nxrmutex_lock(&g_dev_lock); down_write(&g_dev_lock);
list_delete(&dev->node); list_delete(&dev->node);
nxrmutex_unlock(&g_dev_lock); up_write(&g_dev_lock);
nxsem_destroy(&dev->proxysem); nxsem_destroy(&dev->proxysem);
kmm_free(dev); kmm_free(dev);