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