Re: Stop watchdog timer during DDB session

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: Stop watchdog timer during DDB session

Christian Ludwig-3
> Deliberately breaking into DDB, e.g. via serial console BREAK, can lead
> to an abrupt end of the debugging session once the hardware watchdog
> reboots the machine. This is because all CPUs are IPL_HIGH. None of them
> tickles the watchdog anymore.
>
> The same is true on panic, when the system enters DDB. If you really
> want the system to reboot on panic, set ddb.panic to 0.
>
> So stop the watchdog timer when entering DDB. Restart it after the
> debugging session finished.

mpi@ ok'ed this already. Any more oks? Anyone wants to commit this?

> ---
>
>  sys/ddb/db_interface.h   |  4 ++++
>  sys/ddb/db_trap.c        |  2 ++
>  sys/kern/kern_watchdog.c | 25 +++++++++++++++++++++++++
>  3 files changed, 31 insertions(+)
>
> diff --git a/sys/ddb/db_interface.h b/sys/ddb/db_interface.h
> index 77602d2..5728764 100644
> --- a/sys/ddb/db_interface.h
> +++ b/sys/ddb/db_interface.h
> @@ -45,6 +45,10 @@ void db_show_all_procs(db_expr_t, int, db_expr_t, char
> *);
>
>  /* kern/kern_timeout.c */
>  void db_show_callout(db_expr_t, int, db_expr_t, char *);
>
> +/* kern/kern_watchdog.c */
> +void db_wdog_disable(void);
> +void db_wdog_enable(void);
> +
>
>  struct mount;
>  
>  /* kern/vfs_subr.c */
>
> diff --git a/sys/ddb/db_trap.c b/sys/ddb/db_trap.c
> index 85e5c8a..d347ede 100644
> --- a/sys/ddb/db_trap.c
> +++ b/sys/ddb/db_trap.c
> @@ -53,6 +53,7 @@ db_trap(int type, int code)
>
>   boolean_t watchpt;
>  
>   db_is_active = 1;
>
> + db_wdog_disable();
>
>   bkpt = IS_BREAKPOINT_TRAP(type, code);
>   watchpt = IS_WATCHPOINT_TRAP(type, code);
>
> @@ -94,5 +95,6 @@ db_trap(int type, int code)
>
>   }
>  
>   db_restart_at_pc(&ddb_regs, watchpt);
>
> + db_wdog_enable();
>
>   db_is_active = 0;
>  
>  }
>
> diff --git a/sys/kern/kern_watchdog.c b/sys/kern/kern_watchdog.c
> index 5c27b17..e848e24 100644
> --- a/sys/kern/kern_watchdog.c
> +++ b/sys/kern/kern_watchdog.c
> @@ -106,3 +106,28 @@ sysctl_wdog(int *name, u_int namelen, void *oldp,
> size_t *oldlenp, void *newp,>
>   return (error);
>  
>  }
>
> +
> +#ifdef DDB
> +#include <machine/db_machdep.h>
> +#include <ddb/db_interface.h>
> +
> +void
> +db_wdog_disable(void)
> +{
> + if (wdog_ctl_cb == NULL || wdog_period == 0)
> + return;
> +
> + timeout_del(&wdog_timeout);
> + (void) (*wdog_ctl_cb)(wdog_ctl_cb_arg, 0);
> +}
> +
> +void
> +db_wdog_enable(void)
> +{
> + if (wdog_ctl_cb == NULL || wdog_period == 0)
> + return;
> +
> + (void) (*wdog_ctl_cb)(wdog_ctl_cb_arg, wdog_period);
> + timeout_add(&wdog_timeout, wdog_period * hz / 2);
> +}
> +#endif
> --
> 2.1.4