You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/09/05 18:24:03 UTC
[nuttx] branch master updated: arch/risc-v/litex/litex_sdio: Address race condition in eventwait.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 99d630b18d arch/risc-v/litex/litex_sdio: Address race condition in eventwait.
99d630b18d is described below
commit 99d630b18dfa2ad6f182927612a9793a237a835c
Author: Stuart Ianna <st...@motec.com.au>
AuthorDate: Tue Sep 5 16:33:30 2023 +1000
arch/risc-v/litex/litex_sdio: Address race condition in eventwait.
Wraps litex_eventwait in a critical section to handle the case that an event can occur before it's waited on.
---
arch/risc-v/src/litex/litex_sdio.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/risc-v/src/litex/litex_sdio.c b/arch/risc-v/src/litex/litex_sdio.c
index eec66ed295..9b3006dc13 100644
--- a/arch/risc-v/src/litex/litex_sdio.c
+++ b/arch/risc-v/src/litex/litex_sdio.c
@@ -1168,8 +1168,15 @@ static sdio_eventset_t litex_eventwait(struct sdio_dev_s *dev)
{
struct litex_dev_s *priv = (struct litex_dev_s *)dev;
sdio_eventset_t wkupevent = 0;
+ irqstate_t flags;
int ret;
+ /* Use critical section to attempt to handle the case that the event
+ * may have completed before it's waited on.
+ */
+
+ flags = enter_critical_section();
+
DEBUGASSERT((priv->waitevents != 0 && priv->wkupevent == 0) ||
(priv->waitevents == 0 && priv->wkupevent != 0));
for (; ; )
@@ -1177,9 +1184,9 @@ static sdio_eventset_t litex_eventwait(struct sdio_dev_s *dev)
ret = nxsem_wait_uninterruptible(&priv->waitsem);
if (ret < 0)
{
- litex_configwaitints(priv, 0, 0, 0);
wd_cancel(&priv->waitwdog);
- return SDIOWAIT_ERROR;
+ wkupevent = SDIOWAIT_ERROR;
+ goto errout_with_waitints;
}
wkupevent = priv->wkupevent;
@@ -1189,7 +1196,9 @@ static sdio_eventset_t litex_eventwait(struct sdio_dev_s *dev)
}
}
+errout_with_waitints:
litex_configwaitints(priv, 0, 0, 0);
+ leave_critical_section(flags);
return wkupevent;
}