Кто обновляет аппаратный сторожевой таймер в Linux? - PullRequest
16 голосов
/ 07 января 2010

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

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

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

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

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

Ответы [ 5 ]

17 голосов
/ 07 января 2010

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

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

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

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

8 голосов
/ 04 марта 2017

В июле 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));
6 голосов
/ 07 января 2010

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

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

2 голосов
/ 27 июля 2015

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

Битовое объяснение из документации таблицы:

• WDIDLEHLT: Watchdog Idle Halt

  1. 0: сторожевой таймер работает, когда система находится в режиме ожидания.
  2. 1: сторожевой таймер останавливается, когда система находится в режиме ожидания.

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

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

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

0 голосов
/ 07 января 2010

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

...