Skip to content

sched: Add max delay tick limitation for wdog/wqueue. #16394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Documentation/reference/os/time_clock.rst
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ with NuttX tasks.
- :c:func:`wd_gettime`
- Watchdog Timer Callback

.. c:function:: int wd_start(FAR struct wdog_s *wdog, int delay, \
.. c:function:: int wd_start(FAR struct wdog_s *wdog, clock_t delay, \
wdentry_t wdentry, wdparm_t arg)

This function adds a watchdog to the timer queue.
Expand Down
18 changes: 16 additions & 2 deletions include/nuttx/wdog.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@

#define WDOG_ISACTIVE(w) ((w)->func != NULL)

/* The maximum delay tick are supposed to be CLOCK_MAX >> 1.
* However, if there are expired wdog timers in the wdog queue,
* clock_compare might be incorrect when the delay is CLOCK_MAX >> 1.
* e.g. Current tick is 123, and there is an expired wdog timer with the
* expired ticks 100. If we insert a wdog timer with delay CLOCK_MAX >> 1,
* Then clock_compare(100, 123 + CLOCK_MAX >> 1) will return false, leading
* to the new wdog timer queued before the expired wdog timer.
* So we limited the delay to CLOCK_MAX >> 2, which is 2^30 - 1 or 2^62 - 1.
* Assuming all expired wdog timer can be processed within WDOG_MAX_DELAY
* ticks, this ensure the correct enqueue of the wdog timer.
*/

#define WDOG_MAX_DELAY (CLOCK_MAX >> 2)

/****************************************************************************
* Public Type Declarations
****************************************************************************/
Expand Down Expand Up @@ -140,7 +154,7 @@ extern "C"
*
****************************************************************************/

int wd_start(FAR struct wdog_s *wdog, sclock_t delay,
int wd_start(FAR struct wdog_s *wdog, clock_t delay,
wdentry_t wdentry, wdparm_t arg);

/****************************************************************************
Expand Down Expand Up @@ -306,7 +320,7 @@ static inline int wd_start_realtime(FAR struct wdog_s *wdog,
*
****************************************************************************/

int wd_start_period(FAR struct wdog_period_s *wdog, sclock_t delay,
int wd_start_period(FAR struct wdog_period_s *wdog, clock_t delay,
clock_t period, wdentry_t wdentry, wdparm_t arg);

/****************************************************************************
Expand Down
8 changes: 4 additions & 4 deletions sched/wdog/wd_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,12 +406,12 @@ int wd_start_abstick(FAR struct wdog_s *wdog, clock_t ticks,
*
****************************************************************************/

int wd_start(FAR struct wdog_s *wdog, sclock_t delay,
int wd_start(FAR struct wdog_s *wdog, clock_t delay,
wdentry_t wdentry, wdparm_t arg)
{
/* Verify the wdog and setup parameters */
/* Ensure delay is within the range the wdog can handle. */

if (delay < 0)
if (delay > WDOG_MAX_DELAY)
{
return -EINVAL;
}
Expand Down Expand Up @@ -444,7 +444,7 @@ int wd_start(FAR struct wdog_s *wdog, sclock_t delay,
*
****************************************************************************/

int wd_start_period(FAR struct wdog_period_s *wdog, sclock_t delay,
int wd_start_period(FAR struct wdog_period_s *wdog, clock_t delay,
clock_t period, wdentry_t wdentry, wdparm_t arg)
{
if (!wdog || !period || !wdentry)
Expand Down
3 changes: 2 additions & 1 deletion sched/wqueue/kwork_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ int work_queue_period_wq(FAR struct kwork_wqueue_s *wqueue,
clock_t expected;
bool retimer;

if (wqueue == NULL || work == NULL || worker == NULL)
if (wqueue == NULL || work == NULL || worker == NULL ||
delay > WDOG_MAX_DELAY)
{
return -EINVAL;
}
Expand Down
Loading