Skip to content

Commit

Permalink
os/kernel/wdog: add debug logs in wd_expiration
Browse files Browse the repository at this point in the history
This commit adds debug log in wd_expiration. It logs the  wdog structure
value which can be useful to debug the cause of timer expiration fail.
This commit also modifies the wdog struct to keep track of process pid
which is responsible for timer creation.
  • Loading branch information
gSahitya-samsung authored and r-prabu committed Jan 7, 2025
1 parent 2c0ceef commit 869e7a2
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 0 deletions.
3 changes: 3 additions & 0 deletions os/include/tinyara/wdog.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ struct wdog_s {
wdentry_t func; /* Function to execute when delay expires */
#ifdef CONFIG_PIC
FAR void *picbase; /* PIC base address */
#endif
#ifdef CONFIG_DEBUG
int pid; /* The pid of process which creates wdog timer */
#endif
int lag; /* Timer associated with the delay */
uint8_t flags; /* See WDOGF_* definitions above */
Expand Down
3 changes: 3 additions & 0 deletions os/kernel/wdog/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ CSRCS += wd_gettime.c wd_recover.c
ifeq ($(CONFIG_SCHED_WAKEUPSOURCE),y)
CSRCS += wd_setwakeupsource.c wd_getwakeupdelay.c
endif
ifeq ($(CONFIG_DEBUG),y)
CSRCS += wd_dbg.c
endif

# Include wdog build support

Expand Down
94 changes: 94 additions & 0 deletions os/kernel/wdog/wd_dbg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/****************************************************************************
*
* Copyright 2025 Samsung Electronics All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/

#include <sys/types.h>

#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <unistd.h>
#include <sched.h>
#include <assert.h>
#include <errno.h>

#include <tinyara/arch.h>
#include <tinyara/wdog.h>
#include <tinyara/mm/mm.h>

#include "sched/sched.h"
#include "wdog/wdog.h"

static inline void wd_dump(struct wdog_s *wdog)
{
int index = 0;
lldbg("Wdog address = 0x%08x\n", wdog);
lldbg("lag: %d\n", wdog->lag);
lldbg("flags: %u\n", wdog->flags);
lldbg("pid: %d\n", wdog->pid);
lldbg("func: %p\n", wdog->func);
lldbg("argc: %u\n", wdog->argc);
for (; index < CONFIG_MAX_WDOGPARMS; index++) {
lldbg("parm[%d]: %u\n", index, wdog->parm[index]);
}
}

void wd_corruption_dbg(struct wdog_s *wdog)
{
uint32_t wd_node;
lldbg("WDOG INFO\n");
wd_dump(wdog);

if (mm_get_heap(wdog)) {

#ifdef CONFIG_DEBUG_MM_HEAPINFO
// Wdog struct is in heap
lldbg("WDOG is in HEAP. Print neighbour heap nodes\n");
wd_node = (uint32_t)wdog - SIZEOF_MM_ALLOCNODE;
lldbg("PREV WDOG INFO\n");
mm_dump_node((struct mm_allocnode_s *)(wd_node - (((struct mm_allocnode_s *)wd_node)->preceding & ~MM_ALLOC_BIT)), "PREV HEAP NODE");
lldbg("NEXT WDOG INFO\n");
mm_dump_node((struct mm_allocnode_s *)(wd_node + ((struct mm_allocnode_s *)wd_node)->size), "NEXT HEAP NODE");
#endif

} else if (wd_is_prealloc(wdog)) {
// Wdog struct is from prealloc list

lldbg("WDOG is in pre alloc list. Print neighbor wdog nodes\n");

if (wd_is_prealloc(wdog - 1)) {
lldbg("PREV WDOG INFO\n");
wd_dump(wdog - 1);
} else {
lldbg("WDOG is first in pre-alloc list\n");
}

if (wd_is_prealloc(wdog + 1)) {
lldbg("NEXT WDOG INFO\n");
wd_dump(wdog + 1);
} else {
lldbg("WDOG is last in pre-alloc list\n");
}

} else {
lldbg("WDOG Address is invalid\n");
}
}
30 changes: 30 additions & 0 deletions os/kernel/wdog/wd_initialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,36 @@ static struct wdog_s g_wdpool[CONFIG_PREALLOC_WDOGS];
* Public Functions
************************************************************************/

/************************************************************************
* Name: wd_is_prealloc
*
* Description:
* This function checks if the wdog is pre- allocated or not
*
* Parameters:
* wdog - the address of wdog (WDOG_ID)
*
* Return Value:
* true - if wdog is preallocated
* false - otherwise
*
************************************************************************/

bool wd_is_prealloc(WDOG_ID wdog)
{
uintptr_t wdog_ptr = (uintptr_t)wdog;
uintptr_t start = (uintptr_t)(&g_wdpool[0]);
uintptr_t end = (uintptr_t)(&g_wdpool[CONFIG_PREALLOC_WDOGS - 1]);

if (end < start) {
start = start ^ end;
end = start ^ end;
start = start ^ end;
}

return (wdog_ptr >= start) && (wdog_ptr <= end) && (((wdog_ptr - start) % sizeof(struct wdog_s)) == 0);
}

/************************************************************************
* Name: wd_initialize
*
Expand Down
6 changes: 6 additions & 0 deletions os/kernel/wdog/wd_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ static inline void wd_expiration(void)
up_setpicbase(wdog->picbase);
switch (wdog->argc) {
default:
wd_corruption_dbg(wdog);
DEBUGPANIC();
break;

Expand Down Expand Up @@ -247,6 +248,11 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...)
return ERROR;
}

#ifdef CONFIG_DEBUG
/* Store the pid of process to keep track which process is responsible for wdog expiration */
wdog->pid = getpid();
#endif

/* Check if the watchdog has been started. If so, stop it.
* NOTE: There is a race condition here... the caller may receive
* the watchdog between the time that wd_start is called and
Expand Down
22 changes: 22 additions & 0 deletions os/kernel/wdog/wdog.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,23 @@ extern uint16_t g_wdnfree;
* Public Function Prototypes
************************************************************************/

/************************************************************************
* Name: wd_is_prealloc
*
* Description:
* This function checks if the wdog is pre- allocated or not
*
* Parameters:
* wdog - the address of wdog (WDOG_ID)
*
* Return Value:
* true - if wdog is preallocated
* false - otherwise
*
************************************************************************/

bool wd_is_prealloc(WDOG_ID wdog);

/************************************************************************
* Name: wd_initialize
*
Expand Down Expand Up @@ -162,6 +179,11 @@ void wd_timer(void);
#ifdef CONFIG_SCHED_TICKSUPPRESS
void wd_timer_nohz(clock_t ticks);
#endif
#ifdef CONFIG_DEBUG
void wd_corruption_dbg(struct wdog_s *wdog);
#else
#define wd_corruption_dbg(wdog) (0)
#endif
/****************************************************************************
* Name: wd_recover
*
Expand Down

0 comments on commit 869e7a2

Please sign in to comment.