From e4721cef5cda97406fed9da318c37d9f142fe0f2 Mon Sep 17 00:00:00 2001 From: Zhe Weng Date: Fri, 2 Jun 2023 22:43:10 +0800 Subject: [PATCH] usrsock_rpmsg_server: Add net_lock to combine get_tx_payload and recvfrom in recvfrom_handler A dead lock may happen before this patch: rptun thread (usrsock_rpmsg_recvfrom_handler): Gets all tx payload but waiting net_lock in psock_recvfrom net driver thread (higher priority): Receives a packet, holding net_lock, calling usrsock_rpmsg_send_event But no tx buffer left, so rpmsg_send blocks, and won't release net_lock In short: Rptun: Hold all `tx_payload_buffer` -> want `net_lock` Driver: Hold `net_lock` -> want `tx_payload_buffer` This patch use net_lock to combine get_tx_payload and recvfrom together, then: - If it's waiting net_lock, tx payload will not be held, other threads may get tx buffer and do their work. - If net_lock is got, it won't be disturbed before finish receiving, then tx payload won't have chance to be blocked before releasing. Signed-off-by: Zhe Weng --- drivers/usrsock/usrsock_rpmsg_server.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usrsock/usrsock_rpmsg_server.c b/drivers/usrsock/usrsock_rpmsg_server.c index 5548e1106f8..e97faaca5ce 100644 --- a/drivers/usrsock/usrsock_rpmsg_server.c +++ b/drivers/usrsock/usrsock_rpmsg_server.c @@ -562,6 +562,13 @@ static int usrsock_rpmsg_recvfrom_handler(FAR struct rpmsg_endpoint *ept, (FAR void *)(ack + 1) + inaddrlen, ret); } + /* Hold net_lock to combine get_tx_payload and recvfrom together. + * Otherwise we may keep holding tx buffer when waiting net_lock in + * recvfrom, which may block rpmsg and may cause dead lock if + * another thread tries to get tx buffer with net_lock held. + */ + + net_lock(); while (totlen < buflen && i < CONFIG_NET_USRSOCK_RPMSG_SERVER_NIOVEC) { @@ -616,6 +623,8 @@ static int usrsock_rpmsg_recvfrom_handler(FAR struct rpmsg_endpoint *ept, { events |= USRSOCK_EVENT_RECVFROM_AVAIL; } + + net_unlock(); } }