Кто обновляет аппаратный сторожевой таймер в Linux?

У меня есть процессор AT91SAM9G20 с ядром 2.6. Watchdog включен на уровне начальной загрузки и настроен на 16 секунд. Регистр режима Watchdog может быть настроен только один раз. Когда код зависает либо в bootstrap, загрузчике или ядре, плата перезагружается. Но как только ядро ​​появляется, даже если сторожевой таймер не обновляется ни в одном из приложений, плата не будет reset через 16 секунд, но 15 минут.

Кто освежает сторожевого пса?

В нашем случае сторожевой таймер должен находиться под воздействием приложений, так что плата может reset, если наше приложение зависает.

Это запущенные процессы:

1 root     init
2 root     [kthreadd]
3 root     [ksoftirqd/0]
4 root     [watchdog/0]
5 root     [events/0]
6 root     [khelper]
63 root     [kblockd/0]
72 root     [ksuspend_usbd]
78 root     [khubd]
85 root     [kmmcd]
107 root     [pdflush]
108 root     [pdflush]
109 root     [kswapd0]
110 root     [aio/0]
740 root     [mtdblockd]
828 root     [rpciod/0]
982 root     [jffs2_gcd_mtd10]
1003 root     /sbin/udevd -d
1145 daemon   portmap
1158 dbus     dbus-daemon --system
1178 root     /usr/sbin/ifplugd -i eth0 -fwI -u0 -d5 -l -q
1190 root     /usr/sbin/ifplugd -i eth1 -fwI -u0 -d5 -l -q
1221 default  avahi-daemon: running [SP14.local]
1226 root     /usr/sbin/dropbear
1246 root     /root/bin/host_app
1254 root     /root/bin/mini_httpd -c *.cgi -d /root/bin -u root -E /root/bin/
1256 root     -sh
1257 root     /sbin/syslogd -n -m 0
1258 root     /sbin/klogd -n
1259 root     /usr/bin/tail -f /var/log/messages
1265 root     ps -e

Мы используем сторожевой таймер для мягких блокировок, доступных в kernel-2.6.25-ts.at91sam9g20/kernel/softlockup.c

Ответы

Ответ 1

Если вы включили сторожевой драйвер в своем ядре, сторожевой драйвер устанавливает таймер ядра, отвечающий за сброс сторожевого таймера. Соответствующий код здесь. Поэтому он работает следующим образом:

Если ни одно приложение не открывает файл /dev/watchdog, ядро ​​позаботится о сбросе сторожевого таймера. Поскольку это таймер, он не будет отображаться как выделенный поток ядра, а обрабатывается мягкой нитью IRQ. Теперь, если приложение открывает этот файл, оно становится ответственным за сторожевой таймер и может reset его записывать в файл, как описано в документации, связанной с сообщением Ричарда.

Является ли драйвер сторожевого таймера настроен в вашем ядре? Если нет, вы должны настроить его и посмотреть, все еще происходит reset. Если это все равно, вероятно, ваш reset происходит откуда-то еще.

Если ваше ядро ​​слишком старое, чтобы иметь правильный драйвер сторожевого таймера (нет в 2.6.25), вы должны выполнить его резервное копирование с 2.6.28. Или вы можете попытаться отключить сторожевой таймер в вашем загрузчике и посмотреть, есть ли reset.

Ответ 2

Это может дать вам подсказку: http://www.mjmwired.net/kernel/Documentation/watchdog/watchdog-api.txt

Имеет смысл иметь демонов пользовательского пространства, обрабатывающих сторожевой таймер. Вероятно, по умолчанию он будет равен 15-минутному тайм-ауту.

Ответ 3

В июле 2016 года фиксация в ядре 4.7 на watchdog_dev.c включена такая же реакция, как и ответ shodanex для всех драйверов сторожевого таймера. Это, похоже, не документировано нигде, кроме этого потока и исходного кода.

/*
* A worker to generate heartbeat requests is needed if all of the
* following conditions are true.
* - Userspace activated the watchdog.
* - The driver provided a value for the maximum hardware timeout, and
*   thus is aware that the framework supports generating heartbeat
*   requests.
* - Userspace requests a longer timeout than the hardware can handle.
*
* Alternatively, if userspace has not opened the watchdog
* device, we take care of feeding the watchdog if it is
* running.
*/

return (hm && watchdog_active(wdd) && t > hm) ||
       (t && !watchdog_active(wdd) && watchdog_hw_running(wdd));

Ответ 4

у нас была аналогичная проблема в отношении WDT на AT91SAM9263. Проблема была в бит 29 WDIDLEHLT из WDT_MR (адрес: 0xFFFFFD44). Этот бит был установлен в 1, но он должен быть 0 для наших приложений.

Объяснение бит из документации по данным:

• WDIDLEHLT: Watchdog Idle Halt

  • 0: Watchdog запускается, когда система находится в режиме ожидания.
  • 1: сторожевой таймер останавливается, когда система находится в режиме ожидания.

Это означает, что счетчик WDT не увеличивается, когда ядро ​​находится в состоянии ожидания, поэтому происходит 15 или более задержка до reset.

Вы можете попробовать "dd if =/dev/zero of =/dev/null", который не позволит ядру войти в состояние ожидания, и вы должны получить reset за 16 секунд (или любой другой период, который вы установили в регистре WDT_MR).

Итак, решение заключается в обновлении кода u-boot или другого фрагмента кода, который устанавливает регистр WDT_MR. Помните, что этот регистр записывается один раз...

Ответ 5

Разве ядро ​​не обновляло бы сторожевой таймер? Watchdog разработан для reset платы, если вся система зависает, а не только одно приложение.