|
Jean Delvare |
d609cb |
From: Jean Delvare <jdelvare@suse.de>
|
|
Jean Delvare |
d609cb |
Subject: watchdog: wdat_wdt: Set the min and max timeout values properly
|
|
Jean Delvare |
d609cb |
References: bsc#1194023
|
|
Jean Delvare |
d609cb |
Patch-mainline: submitted, 2022-08-23 https://lore.kernel.org/linux-watchdog/20220823154713.023ee771@endymion.delvare/
|
|
Jean Delvare |
d609cb |
|
|
Jean Delvare |
d609cb |
The wdat_wdt driver is misusing the min_hw_heartbeat_ms field. This
|
|
Jean Delvare |
d609cb |
field should only be used when the hardware watchdog device should not
|
|
Jean Delvare |
d609cb |
be pinged more frequently than a specific period. The ACPI WDAT
|
|
Jean Delvare |
d609cb |
"Minimum Count" field, on the other hand, specifies the minimum
|
|
Jean Delvare |
d609cb |
timeout value that can be set. This corresponds to the min_timeout
|
|
Jean Delvare |
d609cb |
field in Linux's watchdog infrastructure.
|
|
Jean Delvare |
d609cb |
|
|
Jean Delvare |
d609cb |
Setting min_hw_heartbeat_ms instead can cause pings to the hardware
|
|
Jean Delvare |
d609cb |
to be delayed when there is no reason for that, eventually leading to
|
|
Jean Delvare |
d609cb |
unexpected firing of the watchdog timer (and thus unexpected reboot).
|
|
Jean Delvare |
d609cb |
|
|
Jean Delvare |
d609cb |
Since commit 6d72c7ac9fbe ("watchdog: wdat_wdt: Using the existing
|
|
Jean Delvare |
d609cb |
function to check parameter timeout"), min_timeout is being set too,
|
|
Jean Delvare |
d609cb |
but to the arbitrary value of 1 second, which doesn't make sense and
|
|
Jean Delvare |
d609cb |
allows setting timeout values lower that the ACPI WDAT "Minimum
|
|
Jean Delvare |
d609cb |
Count" field.
|
|
Jean Delvare |
d609cb |
|
|
Jean Delvare |
d609cb |
I'm also changing max_hw_heartbeat_ms to max_timeout for symmetry,
|
|
Jean Delvare |
d609cb |
although the use of this one isn't fundamentally wrong, but there is
|
|
Jean Delvare |
d609cb |
also no reason to enable the software-driven ping mechanism for the
|
|
Jean Delvare |
d609cb |
wdat_wdt driver.
|
|
Jean Delvare |
d609cb |
|
|
Jean Delvare |
d609cb |
Signed-off-by: Jean Delvare <jdelvare@suse.de>
|
|
Jean Delvare |
d609cb |
Fixes: 058dfc767008 ("ACPI / watchdog: Add support for WDAT hardware watchdog")
|
|
Jean Delvare |
d609cb |
Fixes: 6d72c7ac9fbe ("watchdog: wdat_wdt: Using the existing function to check parameter timeout")
|
|
Jean Delvare |
d609cb |
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
|
|
Jean Delvare |
d609cb |
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
|
|
Jean Delvare |
d609cb |
Cc: Wim Van Sebroeck <wim@linux-watchdog.org>
|
|
Jean Delvare |
d609cb |
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
|
Jean Delvare |
d609cb |
Cc: Liu Xinpeng <liuxp11@chinatelecom.cn>
|
|
Jean Delvare |
d609cb |
---
|
|
Jean Delvare |
d609cb |
drivers/watchdog/wdat_wdt.c | 8 ++++----
|
|
Jean Delvare |
d609cb |
1 file changed, 4 insertions(+), 4 deletions(-)
|
|
Jean Delvare |
d609cb |
|
|
Jean Delvare |
d609cb |
--- a/drivers/watchdog/wdat_wdt.c
|
|
Jean Delvare |
d609cb |
+++ b/drivers/watchdog/wdat_wdt.c
|
|
Jean Delvare |
d609cb |
@@ -342,8 +342,8 @@ static int wdat_wdt_probe(struct platfor
|
|
Jean Delvare |
d609cb |
return -EINVAL;
|
|
Jean Delvare |
d609cb |
|
|
Jean Delvare |
d609cb |
wdat->period = tbl->timer_period;
|
|
Jean Delvare |
d609cb |
- wdat->wdd.min_hw_heartbeat_ms = wdat->period * tbl->min_count;
|
|
Jean Delvare |
d609cb |
- wdat->wdd.max_hw_heartbeat_ms = wdat->period * tbl->max_count;
|
|
Jean Delvare |
d609cb |
+ wdat->wdd.min_timeout = DIV_ROUND_UP(wdat->period * tbl->min_count, 1000);
|
|
Jean Delvare |
d609cb |
+ wdat->wdd.max_timeout = wdat->period * tbl->max_count / 1000;
|
|
Jean Delvare |
d609cb |
wdat->stopped_in_sleep = tbl->flags & ACPI_WDAT_STOPPED;
|
|
Jean Delvare |
d609cb |
wdat->wdd.info = &wdat_wdt_info;
|
|
Jean Delvare |
d609cb |
wdat->wdd.ops = &wdat_wdt_ops;
|
|
Jean Delvare |
d609cb |
@@ -450,8 +450,8 @@ static int wdat_wdt_probe(struct platfor
|
|
Jean Delvare |
d609cb |
* watchdog properly after it has opened the device. In some cases
|
|
Jean Delvare |
d609cb |
* the BIOS default is too short and causes immediate reboot.
|
|
Jean Delvare |
d609cb |
*/
|
|
Jean Delvare |
d609cb |
- if (timeout * 1000 < wdat->wdd.min_hw_heartbeat_ms ||
|
|
Jean Delvare |
d609cb |
- timeout * 1000 > wdat->wdd.max_hw_heartbeat_ms) {
|
|
Jean Delvare |
d609cb |
+ if (timeout < wdat->wdd.min_timeout ||
|
|
Jean Delvare |
d609cb |
+ timeout > wdat->wdd.max_timeout) {
|
|
Jean Delvare |
d609cb |
dev_warn(dev, "Invalid timeout %d given, using %d\n",
|
|
Jean Delvare |
d609cb |
timeout, WDAT_DEFAULT_TIMEOUT);
|
|
Jean Delvare |
d609cb |
timeout = WDAT_DEFAULT_TIMEOUT;
|