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;
 }