Re: [PATCH 3/3] ACPI / watchdog: Set default timeout in probe

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 12 Feb 2020 14:05:40 +0300, Mika Westerberg wrote:
> If the BIOS default timeout for the watchdog is too small userspace may
> not have enough time to configure new timeout after opening the device
> before the system is already reset. For this reason program default
> timeout of 30 seconds in the driver probe and allow userspace to change
> this from command line or through module parameter (wdat_wdt.timeout).
> 
> Reported-by: Jean Delvare <jdelvare@xxxxxxx>
> Signed-off-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx>
> ---
>  drivers/watchdog/wdat_wdt.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c
> index 2132018f031d..7b0257163522 100644
> --- a/drivers/watchdog/wdat_wdt.c
> +++ b/drivers/watchdog/wdat_wdt.c
> @@ -54,6 +54,13 @@ module_param(nowayout, bool, 0);
>  MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
>  		 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
>  
> +#define WDAT_DEFAULT_TIMEOUT	30
> +
> +static int timeout = WDAT_DEFAULT_TIMEOUT;
> +module_param(timeout, int, 0);
> +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default="
> +		 __MODULE_STRING(WDAT_DEFAULT_TIMEOUT) ")");
> +
>  static int wdat_wdt_read(struct wdat_wdt *wdat,
>  	 const struct wdat_instruction *instr, u32 *value)
>  {
> @@ -308,6 +315,7 @@ static int wdat_wdt_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	const struct acpi_wdat_entry *entries;
>  	const struct acpi_table_wdat *tbl;
> +	int default_timeout = timeout;
>  	struct wdat_wdt *wdat;
>  	struct resource *res;
>  	void __iomem **regs;
> @@ -438,6 +446,22 @@ static int wdat_wdt_probe(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, wdat);
>  
> +	/*
> +	 * Set initial timeout so that userspace has time to configure
> +	 * the watchdog properly after it has opened the device. In some
> +	 * cases the BIOS default is too short and causes immediate reboot.
> +	 */
> +	default_timeout = timeout;

You have already done that at variable declaration time.

> +	if (timeout < wdat->wdd.min_hw_heartbeat_ms ||
> +	    timeout > wdat->wdd.max_hw_heartbeat_ms)

Comparing seconds to milliseconds is unlikely to give the expected
result.

> +		default_timeout = WDAT_DEFAULT_TIMEOUT;
> +	else
> +		default_timeout = timeout;

You have already done that twice ;-)

> +
> +	ret = wdat_wdt_set_timeout(&wdat->wdd, timeout);

You must pass "default_timeout" here, not "timeout", else the check
before serves no purpose. It might be less confusing to not introduce a
separate variable and just tweak timeout in place?

> +	if (ret)
> +		return ret;
> +
>  	watchdog_set_nowayout(&wdat->wdd, nowayout);
>  	return devm_watchdog_register_device(dev, &wdat->wdd);
>  }


-- 
Jean Delvare
SUSE L3 Support



[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux