How to stop the watchdog timer of a BeableBone Black running Linux


But who's going to watch the watchers?

September 2016.
A Beable Bone Black with an operator setting its watchdog timer

The BeagleBone Black's SoC (AM335x) includes a watchdog timer, that will reset the whole board is it isn't pingged regularly.

Let's see if we can stop that thing running the latest Debian GNU/Linux to date.

# uname -a
Linux beaglebone 4.4.9-ti-r25 #1 SMP Thu May 5 23:08:13 UTC 2016 armv7l GNU/Linux
root@beaglebone:~# cat /etc/debian_version
8.4

Ever since this commit, the OMAP watchdog driver has the magic close feature enabled. This means that closing the timer's device won't stop the timer from ticking. The only way to stop it is to send to it the magic character 'V' (a capital 'v').

# wdctl /dev/watchdog
wdctl: write failed: Invalid argument
Device: /dev/watchdog
Identity: OMAP Watchdog [version 0]
Timeout: 120 seconds
Timeleft: 119 seconds
FLAG DESCRIPTION STATUS BOOT-STATUS
KEEPALIVEPING Keep alive ping reply 0 0
MAGICCLOSE Supports magic close char 0 0
SETTIMEOUT Set timeout (in seconds) 0 0

This feature is particularly useful if you want the watchdog timer to only be active when a specific application is running, and if you then want it to be stopped when the application is stopped normally.

Unfortunately, the kernel can be configure with a mode called "no way out", which means that even tough the magic close feature of the driver is enabled, it won't be honored at all, and you are doomed to ping your timer until the end of time once you opened the device.

# cat /proc/config.gz | gunzip | grep CONFIG_WATCHDOG_NOWAYOUT
CONFIG_WATCHDOG_NOWAYOUT=y

On a kernel version 3.8, the feature was not enabled:

$ cat /proc/config.gz | gunzip | grep CONFIG_WATCHDOG_NOWAYOUT
# CONFIG_WATCHDOG_NOWAYOUT is not set

So, how do we stop that thing?

Well, you can see in the code of the driver that the default value of the kernel can be overridden by a module param:

static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
"(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

Edit the boot configuration in /boot/uEnv.txt and add set that parameter to 0 in the cmdline:

cmdline=coherent_pool=1M quiet cape_universal=enable omap_wdt.nowayout=0

Reboot the board, and check that the loaded command line was changed correctly:

# cat /proc/cmdline
console=tty0 console=ttyO0,115200n8 root=/dev/mmcblk0p1 rootfstype=ext4 rootwait coherent_pool=1M quiet cape_universal=enable omap_wdt.nowayout=0

That's it. Now if you send a 'V' to the watchdog right before closing it, it will be stopped.