driver/sensors: fix race condiftion about rptun thread recursive

In sensor_rpmsg_ioctl, when rpmsg_get_tx_payload_buffer is block,
The rptun thread will continue to process rx_buffers from other cores,
So the proxy may be released in sensor_unadv_handler, then if using
the proxy, It causes a crash.
backtrace:
0  0x06007c2e in is_rpmsg_ept_ready (ept=0x5a5a5a5a) at nuttx/include/openamp/rpmsg.h:172
1  0x06013354 in rpmsg_send_nocopy (len=<optimized out>,
    data=<optimized out>, ept=<optimized out>) at nuttx/include/openamp/rpmsg.h:521
2  rpmsg_send_nocopy (ept=0x5a5a5a5a, data=data@entry=0x201facf0,
    len=len@entry=40) at nuttx/include/openamp/rpmsg.h:512
3  0x06013b34 in sensor_rpmsg_ioctl (dev=dev@entry=0x201b7388,
    cmd=538701816, cmd@entry=2690, arg=0, len=len@entry=0,
        wait=<error reading variable: dwarf2_find_location_expression:
        Corrupted DWARF expression.>) at ../../../drivers/sensors/sensor_rpmsg.c:395
4  0x06013cce in sensor_rpmsg_alloc_proxy (dev=dev@entry=0x201b7388,
    ept=ept@entry=0x202073d0, msg=msg@entry=0x201684f0) at ../../../drivers/sensors/sensor_rpmsg.c:498
5  0x06013d12 in sensor_rpmsg_adv_handler (ept=0x202073d0,
    data=0x201684f0, len=49, src=<optimized out>, priv=0x202073c8) at ../../../drivers/sensors/sensor_rpmsg.c:905
6  0x0600d45e in sensor_rpmsg_ept_cb (ept=<optimized out>,
    data=<optimized out>, len=<optimized out>, src=<optimized out>,
    priv=0x202073c8) at ../../../drivers/sensors/sensor_rpmsg.c:1168

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
dongjiuzhu1 2023-09-04 20:39:19 +08:00 committed by Xiang Xiao
parent f8052cdc76
commit 88105f2b3d

View File

@ -351,6 +351,8 @@ static int sensor_rpmsg_ioctl(FAR struct sensor_rpmsg_dev_s *dev,
FAR struct sensor_rpmsg_proxy_s *proxy;
FAR struct sensor_rpmsg_proxy_s *ptmp;
FAR struct sensor_rpmsg_ioctl_s *msg;
FAR struct rpmsg_endpoint *ept;
uint64_t pcookie;
uint32_t space;
int ret = -ENOTTY;
@ -369,18 +371,20 @@ static int sensor_rpmsg_ioctl(FAR struct sensor_rpmsg_dev_s *dev,
list_for_every_entry_safe(&dev->proxylist, proxy, ptmp,
struct sensor_rpmsg_proxy_s, node)
{
msg = rpmsg_get_tx_payload_buffer(proxy->ept, &space, true);
ept = proxy->ept;
pcookie = proxy->cookie;
msg = rpmsg_get_tx_payload_buffer(ept, &space, true);
if (!msg)
{
ret = -ENOMEM;
snerr("ERROR: ioctl get buffer failed:%s, %s\n",
dev->path, rpmsg_get_cpuname(proxy->ept->rdev));
dev->path, rpmsg_get_cpuname(ept->rdev));
break;
}
msg->command = SENSOR_RPMSG_IOCTL;
msg->cookie = wait ? (uint64_t)(uintptr_t)&cookie : 0;
msg->proxy = proxy->cookie;
msg->proxy = pcookie;
msg->request = cmd;
msg->arglen = len;
if (len > 0)
@ -392,11 +396,11 @@ static int sensor_rpmsg_ioctl(FAR struct sensor_rpmsg_dev_s *dev,
msg->arg = arg;
}
ret = rpmsg_send_nocopy(proxy->ept, msg, sizeof(*msg) + len);
ret = rpmsg_send_nocopy(ept, msg, sizeof(*msg) + len);
if (ret < 0)
{
snerr("ERROR: ioctl rpmsg send failed:%s, %d, %s\n",
dev->path, ret, rpmsg_get_cpuname(proxy->ept->rdev));
dev->path, ret, rpmsg_get_cpuname(ept->rdev));
break;
}
@ -406,12 +410,12 @@ static int sensor_rpmsg_ioctl(FAR struct sensor_rpmsg_dev_s *dev,
}
sensor_rpmsg_unlock(dev);
ret = rpmsg_wait(proxy->ept, &cookie.sem);
ret = rpmsg_wait(ept, &cookie.sem);
sensor_rpmsg_lock(dev);
if (ret < 0)
{
snerr("ERROR: ioctl rpmsg wait failed:%s, %d, %s\n",
dev->path, ret, rpmsg_get_cpuname(proxy->ept->rdev));
dev->path, ret, rpmsg_get_cpuname(ept->rdev));
break;
}