Re: watchdog timer programming

Stephane Rochoy <[email protected]> Tue, 1 Oct 2024 08:07:28 +0200
Newsgroups gmane.os.freebsd.devel.hardware
Message-ID <[email protected]>
mike tancsa <[email protected]> writes:

> WARNING: This e-mail comes from someone outside your=20
> organisation. Do not click
> on links or open attachments if you do not know the sender and=20
> are not sure that
> the content is safe.
>
> On 9/30/2024 3:18 AM, Stephane Rochoy wrote:
>>
>> mike tancsa <[email protected]> writes:
>>
>>> Do you know off hand how to set the system to just reboot ?=20
>>> The ddb man
>>> page seems to imply I need options DDB as well, which is not=20
>>> in GENERIC
>>> in order to set script actions.
>>
>> I would try the following:
>>
>>  ddb script kdb.enter.default=3Dreset
>>
> If I build a custom kernel then that will work. But with GENERIC=20
> (I am
> tracking project via freebsd-update), it fails
>
> # ddb script kdb.enter.default=3Dreset
> ddb: sysctl: debug.ddb.scripting.scripts: No such file or=20
> directory
>
> With a customer kernel, adding
>
> options DDB
>
> it works perfectly.
>
> Is there any way to get this to work without having ddb custom
> compiled in ?

I don't understand what's happening here. AFAIK, the code
corresponding to the soft watchdog being triggered is the
following:

  static void
  wd_timeout_cb(void *arg)
  {
    const char *type =3D arg;

  #ifdef DDB
    if ((wd_pretimeout_act & WD_SOFT_DDB)) {
      char kdb_why[80];
      snprintf(kdb_why, sizeof(kdb_why), "watchdog %s-timeout",=20
      type);
      kdb_backtrace();
      kdb_enter(KDB_WHY_WATCHDOG, kdb_why);
    }
  #endif
    if ((wd_pretimeout_act & WD_SOFT_LOG))
      log(LOG_EMERG, "watchdog %s-timeout, WD_SOFT_LOG\n", type);
    if ((wd_pretimeout_act & WD_SOFT_PRINTF))
      printf("watchdog %s-timeout, WD_SOFT_PRINTF\n", type);
    if ((wd_pretimeout_act & WD_SOFT_PANIC))
      panic("watchdog %s-timeout, WD_SOFT_PANIC set", type);
  }

So without DDB, it should call panic. But in your case, it
called kdb_backtrace. So initial hypothesis was wrong. What I
missed is that panic was natively able to kdb_backtrace if gently
asked to do so:

  #ifdef KDB
    if ((newpanic || trace_all_panics) && trace_on_panic)
      kdb_backtrace();
    if (debugger_on_panic)
      kdb_enter(KDB_WHY_PANIC, "panic");
    else if (!newpanic && debugger_on_recursive_panic)
      kdb_enter(KDB_WHY_PANIC, "re-panic");
  #endif
    /*thread_lock(td); */
    td->td_flags |=3D TDF_INPANIC;
    /* thread_unlock(td); */
    if (!sync_on_panic)
      bootopt |=3D RB_NOSYNC;
    if (poweroff_on_panic)
      bootopt |=3D RB_POWEROFF;
    if (powercycle_on_panic)
      bootopt |=3D RB_POWERCYCLE;
    kern_reboot(bootopt);

So it definitely should reboot but as it don't, maybe playing with
kern.powercycle_on_panic would help?

Regards,
--=20=20
St=C3=A9phane Rochoy
O: Stormshield