Received: by 10.223.164.202 with SMTP id h10csp2866345wrb; Tue, 28 Nov 2017 02:37:32 -0800 (PST) X-Google-Smtp-Source: AGs4zMbj4iiv772zT8+eGMP07d9GNTSezU1OoR/mBoXF+rSWFX7sYbs06LzG6LMCghQNzqEwqOCz X-Received: by 10.84.171.193 with SMTP id l59mr30405035plb.33.1511865452833; Tue, 28 Nov 2017 02:37:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511865452; cv=none; d=google.com; s=arc-20160816; b=Ol05Da+vXwa4m98FgYElOWJQLiZqg/xTnh1zJAixOmwuYJvMBpE2DF961dKXTBi232 dUS/OpkBCisr1h5BYvtRyjOBRuq5XOCYJM0nAZD/ctz5EiWXUJn2OivqJc9dKr8yViEh OwZbz6HnfLVDV93ADytH6u48Ly0GqCBk/GfkBWe3GeoE4FwjcqGhUITmOIPs0B8aUT9A r6K5VVlxLL6BSdBsy3XRBwZ8WmAK4iwBthvZLBLUCNsZoe8nAhoscPIrjCHSez2Xwc/8 tuiSG+m7e5w4WB1+7c6zbvq2Q7nageINp3M+Z4WYwsA6lIbtaqdSOSder+f7t6M53suS +QsA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=yLCmId3MpH1GoGVS7pp7t+N5QLkHlUC6fsACKxv3PGo=; b=GzwizwCiIElxv9PN4x4XlDYxoViBufNE6tLbQppncP5mtMp9uh2Tt0iSY1wozlV3HD aBk+wMGp82mZbcudCKFA2LUaeaIhzVWrZ2My16OieHTuQDYIOMr93cPlq5HMrA+4JctJ 31A/jt+u9ASaPmn38nJ6MUMC6afzeDXuHkIjSgQnIO3i8J50f7n7CtD/Nq6hadCssqAT vTIC5uznwPAgSZhIWFhozT5PGwGFbq+uPCMHUTZqIMiYrzIxyKH3qIrsWKwTpeGtV0j7 jnBgydbD/XqOm8aOFp7ilinjiVqNH49QZHVrD/0hbgTz/XcbuC6Nf4Q35yrNG9Xyx334 aR5g== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@prevas.dk header.s=ironport2 header.b=hMW6uh+m; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y3si27698747pfj.120.2017.11.28.02.37.20; Tue, 28 Nov 2017 02:37:32 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@prevas.dk header.s=ironport2 header.b=hMW6uh+m; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932401AbdK1KgD (ORCPT + 79 others); Tue, 28 Nov 2017 05:36:03 -0500 Received: from mail02.prevas.se ([62.95.78.10]:22533 "EHLO mail02.prevas.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932349AbdK1Kf7 (ORCPT ); Tue, 28 Nov 2017 05:35:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=prevas.dk; i=@prevas.dk; l=5814; q=dns/txt; s=ironport2; t=1511865359; x=1543401359; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=fbiuZ1gk68yu7QEqPSyvLngaKuJ/MkhOpUYyZAxqxbA=; b=hMW6uh+mhon/S18m4MVQIsEfieh4MlGyR5sIA04dX8GWo5U+U5ZTBPeP DrICbXRKOoDHaCm7gOK2tjFK4IVx1AQ1hr1bClQR/R1H8Fzjtbb0TCi1f 7f1DBcyz/9JfZW5mAs1sGie1zl27ouavNxQihI7+wHWb7bFAlHT6JHLuQ Y=; X-IronPort-AV: E=Sophos;i="5.44,467,1505772000"; d="scan'208";a="2736150" Received: from vmprevas4.prevas.se (HELO smtp.prevas.se) ([172.16.8.104]) by ironport2.prevas.se with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Nov 2017 11:35:57 +0100 Received: from prevas-ravi.prevas.se (172.16.8.31) by smtp.prevas.se (172.16.8.104) with Microsoft SMTP Server (TLS) id 14.3.361.1; Tue, 28 Nov 2017 11:35:57 +0100 From: Rasmus Villemoes To: Wim Van Sebroeck , Guenter Roeck , Jonathan Corbet CC: Esben Haabendal , , Rasmus Villemoes , , , Subject: [PATCH 1/2] watchdog: introduce watchdog.open_timeout commandline parameter Date: Tue, 28 Nov 2017 11:35:49 +0100 Message-ID: <1511865350-20665-2-git-send-email-rasmus.villemoes@prevas.dk> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1511865350-20665-1-git-send-email-rasmus.villemoes@prevas.dk> References: <1511865350-20665-1-git-send-email-rasmus.villemoes@prevas.dk> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [172.16.8.31] Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The watchdog framework takes care of feeding a hardware watchdog until userspace opens /dev/watchdogN. If that never happens for some reason (buggy init script, corrupt root filesystem or whatnot) but the kernel itself is fine, the machine stays up indefinitely. This patch allows setting an upper limit for how long the kernel will take care of the watchdog, thus ensuring that the watchdog will eventually reset the machine. This is particularly useful for embedded devices where some fallback logic is implemented in the bootloader (e.g., use a different root partition, boot from network, ...). The existing handle_boot_enabled parameter has the same purpose, but that is only usable when the hardware watchdog has a sufficiently long timeout (possibly configured by the bootloader). Many hardware watchdogs cannot be configured, or can only be configured up to a certain value, making the timeout short enough that it is completely impossible to have userspace ready soon enough. Hence it is necessary for the kernel to handle those watchdogs for a while. The open timeout is also used as a maximum time for an application to re-open /dev/watchdogN after closing it. A value of 0 (the default) means infinite timeout, preserving the current behaviour. The unit is milliseconds rather than seconds because that covers more use cases. For example, one can effectively disable the kernel handling by setting the open_timeout to 1 ms. There are also customers with very strict requirements that may want to set the open_timeout to something like 4500 ms, which combined with a hardware watchdog that must be pinged every 250 ms ensures userspace is up no more than 5 seconds after the bootloader hands control to the kernel (250 ms until the driver gets registered and kernel handling starts, 4500 ms of kernel handling, and then up to 250 ms from the last ping until userspace takes over). Signed-off-by: Rasmus Villemoes Reviewed-by: Esben Haabendal --- Documentation/watchdog/watchdog-parameters.txt | 8 ++++++++ drivers/watchdog/watchdog_dev.c | 27 +++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt index 6f9d7b4..5363bf3 100644 --- a/Documentation/watchdog/watchdog-parameters.txt +++ b/Documentation/watchdog/watchdog-parameters.txt @@ -8,6 +8,14 @@ See Documentation/admin-guide/kernel-parameters.rst for information on providing kernel parameters for builtin drivers versus loadable modules. +The watchdog core parameter watchdog.open_timeout is the maximum time, +in milliseconds, for which the watchdog framework will take care of +pinging a hardware watchdog until userspace opens the corresponding +/dev/watchdogN device. A value of 0 (the default) means an infinite +timeout. Setting this to a non-zero value can be useful to ensure that +either userspace comes up properly, or the board gets reset and allows +fallback logic in the bootloader to try something else. + ------------------------------------------------- acquirewdt: diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 1e971a5..b4985db 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -67,6 +67,7 @@ struct watchdog_core_data { struct mutex lock; unsigned long last_keepalive; unsigned long last_hw_keepalive; + unsigned long open_deadline; struct delayed_work work; unsigned long status; /* Internal status bits */ #define _WDOG_DEV_OPEN 0 /* Opened ? */ @@ -83,6 +84,19 @@ static struct workqueue_struct *watchdog_wq; static bool handle_boot_enabled = IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED); +static unsigned open_timeout; + +static bool watchdog_past_open_deadline(struct watchdog_core_data *data) +{ + if (!open_timeout) + return false; + return time_is_before_jiffies(data->open_deadline); +} + +static void watchdog_set_open_deadline(struct watchdog_core_data *data) +{ + data->open_deadline = jiffies + msecs_to_jiffies(open_timeout); +} static inline bool watchdog_need_worker(struct watchdog_device *wdd) { @@ -200,7 +214,13 @@ static bool watchdog_worker_should_ping(struct watchdog_core_data *wd_data) { struct watchdog_device *wdd = wd_data->wdd; - return wdd && (watchdog_active(wdd) || watchdog_hw_running(wdd)); + if (!wdd) + return false; + + if (watchdog_active(wdd)) + return true; + + return watchdog_hw_running(wdd) && !watchdog_past_open_deadline(wd_data); } static void watchdog_ping_work(struct work_struct *work) @@ -861,6 +881,7 @@ static int watchdog_release(struct inode *inode, struct file *file) watchdog_ping(wdd); } + watchdog_set_open_deadline(wd_data); watchdog_update_worker(wdd); /* make sure that /dev/watchdog can be re-opened */ @@ -959,6 +980,7 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno) /* Record time of most recent heartbeat as 'just before now'. */ wd_data->last_hw_keepalive = jiffies - 1; + watchdog_set_open_deadline(wd_data); /* * If the watchdog is running, prevent its driver from being unloaded, @@ -1156,3 +1178,6 @@ module_param(handle_boot_enabled, bool, 0444); MODULE_PARM_DESC(handle_boot_enabled, "Watchdog core auto-updates boot enabled watchdogs before userspace takes over (default=" __MODULE_STRING(IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) ")"); +module_param(open_timeout, uint, 0644); +MODULE_PARM_DESC(open_timeout, + "Maximum time in milliseconds for userspace to take over handling enabled watchdogs (0 = infinite)"); -- 2.7.4 From 1585361847965330062@xxx Wed Nov 29 01:27:56 +0000 2017 X-GM-THRID: 1584312765931206486 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread