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

commit 27c9d388d90cc136188df0fdf140a4a1f27bba61
Author: guanyi3 <[email protected]>
AuthorDate: Wed Jan 14 16:03:47 2026 +0800

    sim: replace wdog to work queue to avoid deadlock
    
    The wdog callbacks are executed in the host's signal handler context, which 
has strict limitations on what operations can be safely performed. 
Specifically, signal handlers should not call non-async-signal-safe functions 
(e.g., sim_alsa use mutex_lock in wdog and cause deadlock).
    
    This change only replaces uses of wdog for periodic tasks. Other interrupt 
callbacks that are still invoked from the host signal handler are not replace 
to work queue.
    
    Signed-off-by: guanyi3 <[email protected]>
---
 arch/sim/src/sim/posix/sim_alsa.c   | 16 ++++++++--------
 arch/sim/src/sim/sim_initialize.c   | 25 +++++++++++++------------
 arch/sim/src/sim/sim_netdriver.c    | 13 +++++++------
 arch/sim/src/sim/sim_rpmsg_virtio.c | 15 ++++++++-------
 arch/sim/src/sim/sim_rptun.c        | 12 +++++++-----
 arch/sim/src/sim/sim_usbdev.c       | 11 ++++++-----
 arch/sim/src/sim/sim_usbhost.c      | 10 ++++++----
 7 files changed, 55 insertions(+), 47 deletions(-)

diff --git a/arch/sim/src/sim/posix/sim_alsa.c 
b/arch/sim/src/sim/posix/sim_alsa.c
index 064dc2480fb..0ec651d332b 100644
--- a/arch/sim/src/sim/posix/sim_alsa.c
+++ b/arch/sim/src/sim/posix/sim_alsa.c
@@ -29,8 +29,7 @@
 #include <nuttx/audio/audio.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/nuttx.h>
-#include <nuttx/wdog.h>
-
+#include <nuttx/wqueue.h>
 #include <debug.h>
 #include <sys/param.h>
 
@@ -53,10 +52,9 @@ struct sim_audio_s
 {
   struct audio_lowerhalf_s dev;
   struct dq_queue_s pendq;
+  struct work_s work;
   mutex_t pendlock;
 
-  struct wdog_s wdog;           /* Watchdog for event loop */
-
   bool playback;
   bool offload;
   bool paused;
@@ -1134,13 +1132,14 @@ fail:
   return 0;
 }
 
-static void sim_alsa_interrupt(wdparm_t arg)
+static void sim_audio_work_handler(FAR void *arg)
 {
   struct sim_audio_s *priv = (struct sim_audio_s *)arg;
 
   sim_audio_process(priv);
 
-  wd_start_next(&priv->wdog, SIM_AUDIO_PERIOD, sim_alsa_interrupt, arg);
+  work_queue_next(HPWORK, &priv->work, sim_audio_work_handler, priv,
+                  SIM_AUDIO_PERIOD);
 }
 
 /****************************************************************************
@@ -1169,7 +1168,9 @@ struct audio_lowerhalf_s *sim_audio_initialize(bool 
playback, bool offload)
       return NULL;
     }
 
-  wd_start(&priv->wdog, 0, sim_alsa_interrupt, (wdparm_t)priv);
+  memset(&priv->work, 0, sizeof(struct work_s));
+  work_queue(HPWORK, &priv->work, sim_audio_work_handler, priv,
+             SIM_AUDIO_PERIOD);
 
   /* Setting default config */
 
@@ -1181,6 +1182,5 @@ struct audio_lowerhalf_s *sim_audio_initialize(bool 
playback, bool offload)
   priv->channels    = 2;
   priv->bps         = 16;
   priv->frame_size  = 4;
-
   return &priv->dev;
 }
diff --git a/arch/sim/src/sim/sim_initialize.c 
b/arch/sim/src/sim/sim_initialize.c
index f736c8415ff..ab0d4cbb16c 100644
--- a/arch/sim/src/sim/sim_initialize.c
+++ b/arch/sim/src/sim/sim_initialize.c
@@ -32,6 +32,7 @@
 #include <nuttx/power/pm.h>
 #include <nuttx/spi/spi_flash.h>
 #include <nuttx/spi/qspi_flash.h>
+#include <nuttx/wqueue.h>
 
 #include <stdlib.h>
 
@@ -51,11 +52,11 @@
 
 #if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \
     defined(CONFIG_SIM_BUTTONS)
-static struct wdog_s g_x11event_wdog;   /* Watchdog for event loop */
+static struct work_s g_x11event_work;   /* Watchdog for event loop */
 #endif
 
 #ifdef CONFIG_SIM_X11FB
-static struct wdog_s g_x11update_wdog;  /* Watchdog for update loop */
+static struct work_s g_x11update_work;  /* Watchdog for update loop */
 #endif
 
 /****************************************************************************
@@ -88,11 +89,11 @@ static void sim_init_cmdline(void)
 
 #if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \
     defined(CONFIG_SIM_BUTTONS)
-static void sim_x11event_interrupt(wdparm_t arg)
+static void sim_x11event_work(void *arg)
 {
   sim_x11events();
-  wd_start_next((FAR struct wdog_s *)arg, SIM_X11EVENT_PERIOD,
-                sim_x11event_interrupt, arg);
+  work_queue_next(HPWORK, &g_x11event_work, sim_x11event_work,
+                  NULL, SIM_X11EVENT_PERIOD);
 }
 #endif
 
@@ -105,11 +106,11 @@ static void sim_x11event_interrupt(wdparm_t arg)
  ****************************************************************************/
 
 #ifdef CONFIG_SIM_X11FB
-static void sim_x11update_interrupt(wdparm_t arg)
+static void sim_x11update_work(void *arg)
 {
   sim_x11loop();
-  wd_start_next((FAR struct wdog_s *)arg, SIM_X11UPDATE_PERIOD,
-                sim_x11update_interrupt, arg);
+  work_queue_next(HPWORK, &g_x11update_work, sim_x11update_work,
+                  NULL, SIM_X11UPDATE_PERIOD);
 }
 #endif
 
@@ -317,12 +318,12 @@ void up_initialize(void)
 
 #if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \
     defined(CONFIG_SIM_BUTTONS)
-  wd_start(&g_x11event_wdog, 0, sim_x11event_interrupt,
-           (wdparm_t)&g_x11event_wdog);
+  work_queue(HPWORK, &g_x11event_work, sim_x11event_work,
+             NULL, SIM_X11EVENT_PERIOD);
 #endif
 
 #ifdef CONFIG_SIM_X11FB
-  wd_start(&g_x11update_wdog, 0, sim_x11update_interrupt,
-           (wdparm_t)&g_x11update_wdog);
+  work_queue(HPWORK, &g_x11update_work, sim_x11update_work,
+             NULL, SIM_X11UPDATE_PERIOD);
 #endif
 }
diff --git a/arch/sim/src/sim/sim_netdriver.c b/arch/sim/src/sim/sim_netdriver.c
index 6ad654b3014..1dda9326f69 100644
--- a/arch/sim/src/sim/sim_netdriver.c
+++ b/arch/sim/src/sim/sim_netdriver.c
@@ -108,7 +108,7 @@ struct sim_netdev_s
   struct netdev_lowerhalf_s dev;
 #endif
   uint8_t buf[SIM_NETDEV_BUFSIZE]; /* Used when packet buffer is fragmented */
-  struct wdog_s wdog;
+  struct work_s work;
 };
 
 /****************************************************************************
@@ -268,7 +268,7 @@ static void netdriver_rxready_interrupt(void *priv)
   netdev_lower_rxready(dev);
 }
 
-static void sim_netdev_interrupt(wdparm_t arg)
+static void sim_netdev_work(void *arg)
 {
   struct sim_netdev_s *priv = (struct sim_netdev_s *)arg;
   struct netdev_lowerhalf_s *dev = &priv->dev;
@@ -278,8 +278,8 @@ static void sim_netdev_interrupt(wdparm_t arg)
       netdev_lower_rxready(dev);
     }
 
-  wd_start_next(&priv->wdog, SIM_NETDEV_PERIOD,
-                sim_netdev_interrupt, arg);
+  work_queue_next(HPWORK, &priv->work, sim_netdev_work, arg,
+                  SIM_NETDEV_PERIOD);
 }
 
 /****************************************************************************
@@ -330,8 +330,9 @@ int sim_netdriver_init(void)
 
       netdev_lower_register(dev, devidx < CONFIG_SIM_WIFIDEV_NUMBER ?
                                  NET_LL_IEEE80211 : NET_LL_ETHERNET);
-      wd_start(&g_sim_dev[devidx].wdog, 0,
-               sim_netdev_interrupt, (wdparm_t)&g_sim_dev[devidx]);
+      work_queue(HPWORK, &g_sim_dev[devidx].work,
+                 sim_netdev_work, &g_sim_dev[devidx],
+                 SIM_NETDEV_PERIOD);
     }
 
   return OK;
diff --git a/arch/sim/src/sim/sim_rpmsg_virtio.c 
b/arch/sim/src/sim/sim_rpmsg_virtio.c
index fbedcf8bd57..0e805b3b294 100644
--- a/arch/sim/src/sim/sim_rpmsg_virtio.c
+++ b/arch/sim/src/sim/sim_rpmsg_virtio.c
@@ -30,7 +30,7 @@
 #include <nuttx/kmalloc.h>
 #include <nuttx/nuttx.h>
 #include <nuttx/rpmsg/rpmsg_virtio_lite.h>
-#include <nuttx/wdog.h>
+#include <nuttx/wqueue.h>
 
 #include "sim_internal.h"
 
@@ -67,9 +67,9 @@ struct sim_rpmsg_virtio_dev_s
   char                            cpuname[RPMSG_NAME_SIZE + 1];
   char                            shmemname[RPMSG_NAME_SIZE + 1];
 
-  /* Wdog for transmit */
+  /* Work for transmit */
 
-  struct wdog_s                   wdog;
+  struct work_s                   work;
 };
 
 /****************************************************************************
@@ -164,7 +164,7 @@ sim_rpmsg_virtio_register_callback(struct 
rpmsg_virtio_lite_s *dev,
   return 0;
 }
 
-static void sim_rpmsg_virtio_work(wdparm_t arg)
+static void sim_rpmsg_virtio_work(void *arg)
 {
   struct sim_rpmsg_virtio_dev_s *dev = (struct sim_rpmsg_virtio_dev_s *)arg;
 
@@ -189,8 +189,8 @@ static void sim_rpmsg_virtio_work(wdparm_t arg)
         }
     }
 
-  wd_start(&dev->wdog, SIM_RPMSG_VIRTIO_WORK_DELAY,
-           sim_rpmsg_virtio_work, (wdparm_t)dev);
+  work_queue_next(HPWORK, &dev->work, sim_rpmsg_virtio_work, dev,
+                  SIM_RPMSG_VIRTIO_WORK_DELAY);
 }
 
 static int sim_rpmsg_virtio_notify(struct rpmsg_virtio_lite_s *dev,
@@ -252,5 +252,6 @@ int sim_rpmsg_virtio_init(const char *shmemname, const char 
*cpuname,
       return ret;
     }
 
-  return wd_start(&priv->wdog, 0, sim_rpmsg_virtio_work, (wdparm_t)priv);
+  return work_queue(HPWORK, &priv->work, sim_rpmsg_virtio_work, priv,
+                    SIM_RPMSG_VIRTIO_WORK_DELAY);
 }
diff --git a/arch/sim/src/sim/sim_rptun.c b/arch/sim/src/sim/sim_rptun.c
index 5295cab5f5e..e3f878634fc 100644
--- a/arch/sim/src/sim/sim_rptun.c
+++ b/arch/sim/src/sim/sim_rptun.c
@@ -28,7 +28,7 @@
 #include <nuttx/drivers/addrenv.h>
 #include <nuttx/rptun/rptun.h>
 #include <nuttx/list.h>
-#include <nuttx/wdog.h>
+#include <nuttx/wqueue.h>
 
 #include "sim_internal.h"
 
@@ -74,9 +74,9 @@ struct sim_rptun_dev_s
   char                      shmemname[RPMSG_NAME_SIZE + 1];
   pid_t                     pid;
 
-  /* Wdog for transmit */
+  /* Work for transmit */
 
-  struct wdog_s             wdog;
+  struct work_s             work;
 };
 
 /****************************************************************************
@@ -358,7 +358,8 @@ static void sim_rptun_work(wdparm_t arg)
         }
     }
 
-  wd_start(&dev->wdog, SIM_RPTUN_WORK_DELAY, sim_rptun_work, (wdparm_t)dev);
+  work_queue_next(HPWORK, &dev->work, sim_rptun_work, dev,
+                  SIM_RPTUN_WORK_DELAY);
 }
 
 /****************************************************************************
@@ -405,5 +406,6 @@ int sim_rptun_init(const char *shmemname, const char 
*cpuname, int master)
       return ret;
     }
 
-  return wd_start(&dev->wdog, 0, sim_rptun_work, (wdparm_t)dev);
+  return work_queue(HPWORK, &dev->work, sim_rptun_work, dev,
+                    SIM_RPTUN_WORK_DELAY);
 }
diff --git a/arch/sim/src/sim/sim_usbdev.c b/arch/sim/src/sim/sim_usbdev.c
index f3a48196323..32e3037f808 100644
--- a/arch/sim/src/sim/sim_usbdev.c
+++ b/arch/sim/src/sim/sim_usbdev.c
@@ -38,7 +38,7 @@
 #include <debug.h>
 
 #include <nuttx/arch.h>
-#include <nuttx/wdog.h>
+#include <nuttx/wqueue.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/usb/usb.h>
 #include <nuttx/usb/usbdev.h>
@@ -159,7 +159,7 @@ struct sim_usbdev_s
   uint16_t                      epavail;              /* Bitset of available 
endpoints */
   struct sim_ep_s               eps[SIM_USB_EPNUM];
   spinlock_t                    lock;                 /* Spinlock */
-  struct wdog_s                 wdog;                 /* Watchdog for event 
loop */
+  struct work_s                 work;                 /* Work for event loop */
 };
 
 struct sim_req_s
@@ -1045,7 +1045,7 @@ static void sim_usbdev_devinit(struct sim_usbdev_s *dev)
   dev->epavail = SIM_EPSET_NOEP0;
 }
 
-static void sim_usbdev_interrupt(wdparm_t arg)
+static void sim_usbdev_work(void *arg)
 {
   struct sim_usbdev_s *priv = (struct sim_usbdev_s *)arg;
   struct sim_ep_s *privep;
@@ -1080,7 +1080,8 @@ static void sim_usbdev_interrupt(wdparm_t arg)
         }
     }
 
-  wd_start_next(&priv->wdog, SIM_USB_PERIOD, sim_usbdev_interrupt, arg);
+  work_queue_next(HPWORK, &priv->work, sim_usbdev_work, priv,
+                  SIM_USB_PERIOD);
 }
 
 /****************************************************************************
@@ -1138,7 +1139,7 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
 #endif
     }
 
-  wd_start(&priv->wdog, 0, sim_usbdev_interrupt, (wdparm_t)priv);
+  work_queue(HPWORK, &priv->work, sim_usbdev_work, priv, SIM_USB_PERIOD);
 
   return ret;
 }
diff --git a/arch/sim/src/sim/sim_usbhost.c b/arch/sim/src/sim/sim_usbhost.c
index 4f3df26b198..dbd9e5e5b74 100644
--- a/arch/sim/src/sim/sim_usbhost.c
+++ b/arch/sim/src/sim/sim_usbhost.c
@@ -43,6 +43,7 @@
 #include <nuttx/usb/usb.h>
 #include <nuttx/usb/usbhost.h>
 #include <nuttx/usb/usbhost_trace.h>
+#include <nuttx/wqueue.h>
 
 #include "sim_usbhost.h"
 #include "sim_internal.h"
@@ -111,7 +112,7 @@ struct sim_usbhost_s
   sem_t                         pscsem;             /* Semaphore to wait for 
port status change events */
 
   struct usbhost_devaddr_s      devgen;              /* Address generation 
data */
-  struct wdog_s                 wdog;
+  struct work_s                 work;
 };
 
 /****************************************************************************
@@ -712,7 +713,7 @@ static void sim_usbhost_rqcomplete(struct sim_usbhost_s 
*drvr)
  * Name: sim_usbhost_interrupt
  ****************************************************************************/
 
-static void sim_usbhost_interrupt(wdparm_t arg)
+static void sim_usbhost_work(void *arg)
 {
   struct sim_usbhost_s *priv = (struct sim_usbhost_s *)arg;
   struct usbhost_hubport_s *hport;
@@ -778,7 +779,8 @@ static void sim_usbhost_interrupt(wdparm_t arg)
         }
     }
 
-  wd_start_next(&priv->wdog, SIM_USBHOST_PERIOD, sim_usbhost_interrupt, arg);
+  work_queue_next(HPWORK, &priv->work, sim_usbhost_work, priv,
+                  SIM_USBHOST_PERIOD);
 }
 
 /****************************************************************************
@@ -851,7 +853,7 @@ int sim_usbhost_initialize(void)
       return -ENODEV;
     }
 
-  wd_start(&priv->wdog, 0, sim_usbhost_interrupt, (wdparm_t)priv);
+  work_queue(HPWORK, &priv->work, sim_usbhost_work, priv, SIM_USBHOST_PERIOD);
 
   return OK;
 }

Reply via email to