Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1443310 > unrolled thread
| Started by | Rasmus Villemoes <rasmus.villemoes@prevas.dk> |
|---|---|
| First post | 2016-07-14 11:30 +0200 |
| Last post | 2016-07-21 02:40 +0200 |
| Articles | 13 — 3 participants |
Back to article view | Back to linux.kernel
[RFC 0/3] watchdog: introduce open deadline Rasmus Villemoes <rasmus.villemoes@prevas.dk> - 2016-07-14 11:30 +0200
[RFC 2/3] watchdog: introduce watchdog_worker_should_ping helper Rasmus Villemoes <rasmus.villemoes@prevas.dk> - 2016-07-14 11:30 +0200
[RFC 1/3] watchdog: change watchdog_need_worker logic Rasmus Villemoes <rasmus.villemoes@prevas.dk> - 2016-07-14 11:30 +0200
Re: [RFC 1/3] watchdog: change watchdog_need_worker logic Guenter Roeck <linux@roeck-us.net> - 2016-07-14 22:50 +0200
Re: [RFC 1/3] watchdog: change watchdog_need_worker logic Wim Van Sebroeck <wim@iguana.be> - 2016-07-17 21:50 +0200
Re: [RFC 1/3] watchdog: change watchdog_need_worker logic Guenter Roeck <linux@roeck-us.net> - 2016-07-17 22:00 +0200
Re: [RFC 1/3] watchdog: change watchdog_need_worker logic Wim Van Sebroeck <wim@iguana.be> - 2016-07-17 22:40 +0200
[RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE Rasmus Villemoes <rasmus.villemoes@prevas.dk> - 2016-07-14 11:30 +0200
Re: [RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE Guenter Roeck <linux@roeck-us.net> - 2016-07-14 16:50 +0200
Re: [RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE Rasmus Villemoes <rasmus.villemoes@prevas.dk> - 2016-07-15 09:50 +0200
Re: [RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE Guenter Roeck <linux@roeck-us.net> - 2016-07-15 16:30 +0200
Re: [RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE Rasmus Villemoes <rasmus.villemoes@prevas.dk> - 2016-07-21 00:20 +0200
Re: [RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE Guenter Roeck <linux@roeck-us.net> - 2016-07-21 02:40 +0200
| From | Rasmus Villemoes <rasmus.villemoes@prevas.dk> |
|---|---|
| Date | 2016-07-14 11:30 +0200 |
| Subject | [RFC 0/3] watchdog: introduce open deadline |
| Message-ID | <rUL7X-7Qb-3@gated-at.bofh.it> |
If a watchdog driver tells the framework that the device is running, the framework takes care of feeding the watchdog until userspace opens the device. If the userspace application which is supposed to do that never comes up properly, the watchdog is fed indefinitely by the kernel. This can be especially problematic for embedded devices. These patches allow one to set a maximum time for which the kernel will feed the watchdog, thus ensuring that either userspace has come up, or the board gets reset. This allows fallback logic in the bootloader to attempt some recovery (for example, if an automatic update is in progress, it could roll back to the previous version). The patches have been tested on a Raspberry Pi 2 (with a suitably modified driver for setting WDOG_HW_RUNNING - patches will be submitted seperately) and a Wandboard. Rasmus Villemoes (3): watchdog: change watchdog_need_worker logic watchdog: introduce watchdog_worker_should_ping helper watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE drivers/watchdog/Kconfig | 21 +++++++++++++++ drivers/watchdog/watchdog_dev.c | 60 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 74 insertions(+), 7 deletions(-) -- 2.5.0
[toc] | [next] | [standalone]
| From | Rasmus Villemoes <rasmus.villemoes@prevas.dk> |
|---|---|
| Date | 2016-07-14 11:30 +0200 |
| Subject | [RFC 2/3] watchdog: introduce watchdog_worker_should_ping helper |
| Message-ID | <rUL7X-7Qb-7@gated-at.bofh.it> |
| In reply to | #1443310 |
This will be useful when the condition becomes slightly more
complicated in the next patch.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/watchdog/watchdog_dev.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index 14f8a92..da549e5 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -188,18 +188,23 @@ static int watchdog_ping(struct watchdog_device *wdd)
return __watchdog_ping(wdd);
}
+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));
+}
+
static void watchdog_ping_work(struct work_struct *work)
{
struct watchdog_core_data *wd_data;
- struct watchdog_device *wdd;
wd_data = container_of(to_delayed_work(work), struct watchdog_core_data,
work);
mutex_lock(&wd_data->lock);
- wdd = wd_data->wdd;
- if (wdd && (watchdog_active(wdd) || watchdog_hw_running(wdd)))
- __watchdog_ping(wdd);
+ if (watchdog_worker_should_ping(wd_data))
+ __watchdog_ping(wd_data->wdd);
mutex_unlock(&wd_data->lock);
}
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Rasmus Villemoes <rasmus.villemoes@prevas.dk> |
|---|---|
| Date | 2016-07-14 11:30 +0200 |
| Subject | [RFC 1/3] watchdog: change watchdog_need_worker logic |
| Message-ID | <rUL7X-7Qb-9@gated-at.bofh.it> |
| In reply to | #1443310 |
If the driver indicates that the watchdog is running, the framework should feed it until userspace opens the device, regardless of whether the driver has set max_hw_heartbeat_ms. This patch only affects the case where wdd->max_hw_heartbeat_ms is zero, wdd->timeout is non-zero, the watchdog is not active and the hardware device is running (*): - If wdd->timeout is zero, watchdog_need_worker() returns false both before and after this patch, and watchdog_next_keepalive() is not called. - If watchdog_active(wdd), the return value from watchdog_need_worker is also the same as before (namely, hm && t > hm). Hence in that case, watchdog_next_keepalive() is only called if hm == max_hw_heartbeat_ms is non-zero, so the change to min_not_zero there is a no-op. - If the watchdog is not active and the device is not running, we return false from watchdog_need_worker just as before. That leaves the watchdog_hw_running(wdd) && !watchdog_active(wdd) && wdd->timeout case. Again, it's easy to see that if wdd->max_hw_heartbeat_ms is non-zero, we return true from watchdog_need_worker with and without this patch, and the logic in watchdog_next_keepalive is unchanged. Finally, if wdd->max_hw_heartbeat_ms is 0, we used to end up in the cancel_delayed_work branch, whereas with this patch we end up scheduling a ping timeout_ms/2 from now. (*) This should imply that no current kernel drivers are affected, since the only drivers which explicitly set WDOG_HW_RUNNING are imx2_wdt.c and dw_wdt.c, both of which also provide a non-zero value for max_hw_heartbeat_ms. The watchdog core also sets WDOG_HW_RUNNING, but only when the driver doesn't provide ->stop, in which case it must, according to Documentation/watchdog/watchdog-kernel-api.txt, set max_hw_heartbeat_ms. Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> --- drivers/watchdog/watchdog_dev.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 3595cff..14f8a92 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -92,9 +92,13 @@ static inline bool watchdog_need_worker(struct watchdog_device *wdd) * 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))); + return (hm && watchdog_active(wdd) && t > hm) || + (t && !watchdog_active(wdd) && watchdog_hw_running(wdd)); } static long watchdog_next_keepalive(struct watchdog_device *wdd) @@ -107,7 +111,7 @@ static long watchdog_next_keepalive(struct watchdog_device *wdd) unsigned int hw_heartbeat_ms; virt_timeout = wd_data->last_keepalive + msecs_to_jiffies(timeout_ms); - hw_heartbeat_ms = min(timeout_ms, wdd->max_hw_heartbeat_ms); + hw_heartbeat_ms = min_not_zero(timeout_ms, wdd->max_hw_heartbeat_ms); keepalive_interval = msecs_to_jiffies(hw_heartbeat_ms / 2); if (!watchdog_active(wdd)) -- 2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Guenter Roeck <linux@roeck-us.net> |
|---|---|
| Date | 2016-07-14 22:50 +0200 |
| Subject | Re: [RFC 1/3] watchdog: change watchdog_need_worker logic |
| Message-ID | <rUVK2-5Zr-39@gated-at.bofh.it> |
| In reply to | #1443314 |
On Thu, Jul 14, 2016 at 11:16:26AM +0200, Rasmus Villemoes wrote: > If the driver indicates that the watchdog is running, the framework > should feed it until userspace opens the device, regardless of whether > the driver has set max_hw_heartbeat_ms. > > This patch only affects the case where wdd->max_hw_heartbeat_ms is > zero, wdd->timeout is non-zero, the watchdog is not active and the > hardware device is running (*): > > - If wdd->timeout is zero, watchdog_need_worker() returns false both > before and after this patch, and watchdog_next_keepalive() is not > called. > > - If watchdog_active(wdd), the return value from watchdog_need_worker > is also the same as before (namely, hm && t > hm). Hence in that case, > watchdog_next_keepalive() is only called if hm == max_hw_heartbeat_ms > is non-zero, so the change to min_not_zero there is a no-op. > > - If the watchdog is not active and the device is not running, we > return false from watchdog_need_worker just as before. > > That leaves the watchdog_hw_running(wdd) && !watchdog_active(wdd) && > wdd->timeout case. Again, it's easy to see that if > wdd->max_hw_heartbeat_ms is non-zero, we return true from > watchdog_need_worker with and without this patch, and the logic in > watchdog_next_keepalive is unchanged. Finally, if > wdd->max_hw_heartbeat_ms is 0, we used to end up in the > cancel_delayed_work branch, whereas with this patch we end up > scheduling a ping timeout_ms/2 from now. > > (*) This should imply that no current kernel drivers are affected, > since the only drivers which explicitly set WDOG_HW_RUNNING are > imx2_wdt.c and dw_wdt.c, both of which also provide a non-zero value > for max_hw_heartbeat_ms. The watchdog core also sets WDOG_HW_RUNNING, > but only when the driver doesn't provide ->stop, in which case it > must, according to Documentation/watchdog/watchdog-kernel-api.txt, set > max_hw_heartbeat_ms. > > Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> LGTM. Reviewed-by: Guenter Roeck <linux@roeck-us.net> > --- > drivers/watchdog/watchdog_dev.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c > index 3595cff..14f8a92 100644 > --- a/drivers/watchdog/watchdog_dev.c > +++ b/drivers/watchdog/watchdog_dev.c > @@ -92,9 +92,13 @@ static inline bool watchdog_need_worker(struct watchdog_device *wdd) > * 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))); > + return (hm && watchdog_active(wdd) && t > hm) || > + (t && !watchdog_active(wdd) && watchdog_hw_running(wdd)); > } > > static long watchdog_next_keepalive(struct watchdog_device *wdd) > @@ -107,7 +111,7 @@ static long watchdog_next_keepalive(struct watchdog_device *wdd) > unsigned int hw_heartbeat_ms; > > virt_timeout = wd_data->last_keepalive + msecs_to_jiffies(timeout_ms); > - hw_heartbeat_ms = min(timeout_ms, wdd->max_hw_heartbeat_ms); > + hw_heartbeat_ms = min_not_zero(timeout_ms, wdd->max_hw_heartbeat_ms); > keepalive_interval = msecs_to_jiffies(hw_heartbeat_ms / 2); > > if (!watchdog_active(wdd)) > -- > 2.5.0 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
[toc] | [prev] | [next] | [standalone]
| From | Wim Van Sebroeck <wim@iguana.be> |
|---|---|
| Date | 2016-07-17 21:50 +0200 |
| Subject | Re: [RFC 1/3] watchdog: change watchdog_need_worker logic |
| Message-ID | <rW0eB-4Or-11@gated-at.bofh.it> |
| In reply to | #1443314 |
Hi Rasmus, > If the driver indicates that the watchdog is running, the framework > should feed it until userspace opens the device, regardless of whether > the driver has set max_hw_heartbeat_ms. > > This patch only affects the case where wdd->max_hw_heartbeat_ms is > zero, wdd->timeout is non-zero, the watchdog is not active and the > hardware device is running (*): > > - If wdd->timeout is zero, watchdog_need_worker() returns false both > before and after this patch, and watchdog_next_keepalive() is not > called. > > - If watchdog_active(wdd), the return value from watchdog_need_worker > is also the same as before (namely, hm && t > hm). Hence in that case, > watchdog_next_keepalive() is only called if hm == max_hw_heartbeat_ms > is non-zero, so the change to min_not_zero there is a no-op. > > - If the watchdog is not active and the device is not running, we > return false from watchdog_need_worker just as before. > > That leaves the watchdog_hw_running(wdd) && !watchdog_active(wdd) && > wdd->timeout case. Again, it's easy to see that if > wdd->max_hw_heartbeat_ms is non-zero, we return true from > watchdog_need_worker with and without this patch, and the logic in > watchdog_next_keepalive is unchanged. Finally, if > wdd->max_hw_heartbeat_ms is 0, we used to end up in the > cancel_delayed_work branch, whereas with this patch we end up > scheduling a ping timeout_ms/2 from now. > > (*) This should imply that no current kernel drivers are affected, > since the only drivers which explicitly set WDOG_HW_RUNNING are > imx2_wdt.c and dw_wdt.c, both of which also provide a non-zero value > for max_hw_heartbeat_ms. The watchdog core also sets WDOG_HW_RUNNING, > but only when the driver doesn't provide ->stop, in which case it > must, according to Documentation/watchdog/watchdog-kernel-api.txt, set > max_hw_heartbeat_ms. This isn't completely true. We will have the following in the linux-watchdog tree: drivers/watchdog/aspeed_wdt.c: set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); drivers/watchdog/dw_wdt.c: set_bit(WDOG_HW_RUNNING, &wdd->status); drivers/watchdog/dw_wdt.c: set_bit(WDOG_HW_RUNNING, &wdd->status); drivers/watchdog/imx2_wdt.c: set_bit(WDOG_HW_RUNNING, &wdog->status); drivers/watchdog/imx2_wdt.c: set_bit(WDOG_HW_RUNNING, &wdog->status); drivers/watchdog/max77620_wdt.c: set_bit(WDOG_HW_RUNNING, &wdt_dev->status); drivers/watchdog/sbsa_gwdt.c: set_bit(WDOG_HW_RUNNING, &wdd->status); drivers/watchdog/tangox_wdt.c: set_bit(WDOG_HW_RUNNING, &dev->wdt.status); I checked the ones that aren't mentioned and aspeed_wdt, max77620_wdt and sbsa_gwdt.c also have a non-zero value for max_hw_heartbeat_ms. But tangox_wdt.c doesn't set it. This one will need to be looked at closer. > > Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> > --- > drivers/watchdog/watchdog_dev.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c > index 3595cff..14f8a92 100644 > --- a/drivers/watchdog/watchdog_dev.c > +++ b/drivers/watchdog/watchdog_dev.c > @@ -92,9 +92,13 @@ static inline bool watchdog_need_worker(struct watchdog_device *wdd) > * 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))); > + return (hm && watchdog_active(wdd) && t > hm) || > + (t && !watchdog_active(wdd) && watchdog_hw_running(wdd)); > } > > static long watchdog_next_keepalive(struct watchdog_device *wdd) > @@ -107,7 +111,7 @@ static long watchdog_next_keepalive(struct watchdog_device *wdd) > unsigned int hw_heartbeat_ms; > > virt_timeout = wd_data->last_keepalive + msecs_to_jiffies(timeout_ms); > - hw_heartbeat_ms = min(timeout_ms, wdd->max_hw_heartbeat_ms); > + hw_heartbeat_ms = min_not_zero(timeout_ms, wdd->max_hw_heartbeat_ms); > keepalive_interval = msecs_to_jiffies(hw_heartbeat_ms / 2); > > if (!watchdog_active(wdd)) > -- > 2.5.0 > Kind regards, Wim.
[toc] | [prev] | [next] | [standalone]
| From | Guenter Roeck <linux@roeck-us.net> |
|---|---|
| Date | 2016-07-17 22:00 +0200 |
| Subject | Re: [RFC 1/3] watchdog: change watchdog_need_worker logic |
| Message-ID | <rW0oh-4RC-1@gated-at.bofh.it> |
| In reply to | #1445093 |
On 07/17/2016 12:24 PM, Wim Van Sebroeck wrote: > Hi Rasmus, > >> If the driver indicates that the watchdog is running, the framework >> should feed it until userspace opens the device, regardless of whether >> the driver has set max_hw_heartbeat_ms. >> >> This patch only affects the case where wdd->max_hw_heartbeat_ms is >> zero, wdd->timeout is non-zero, the watchdog is not active and the >> hardware device is running (*): >> >> - If wdd->timeout is zero, watchdog_need_worker() returns false both >> before and after this patch, and watchdog_next_keepalive() is not >> called. >> >> - If watchdog_active(wdd), the return value from watchdog_need_worker >> is also the same as before (namely, hm && t > hm). Hence in that case, >> watchdog_next_keepalive() is only called if hm == max_hw_heartbeat_ms >> is non-zero, so the change to min_not_zero there is a no-op. >> >> - If the watchdog is not active and the device is not running, we >> return false from watchdog_need_worker just as before. >> >> That leaves the watchdog_hw_running(wdd) && !watchdog_active(wdd) && >> wdd->timeout case. Again, it's easy to see that if >> wdd->max_hw_heartbeat_ms is non-zero, we return true from >> watchdog_need_worker with and without this patch, and the logic in >> watchdog_next_keepalive is unchanged. Finally, if >> wdd->max_hw_heartbeat_ms is 0, we used to end up in the >> cancel_delayed_work branch, whereas with this patch we end up >> scheduling a ping timeout_ms/2 from now. >> >> (*) This should imply that no current kernel drivers are affected, >> since the only drivers which explicitly set WDOG_HW_RUNNING are >> imx2_wdt.c and dw_wdt.c, both of which also provide a non-zero value >> for max_hw_heartbeat_ms. The watchdog core also sets WDOG_HW_RUNNING, >> but only when the driver doesn't provide ->stop, in which case it >> must, according to Documentation/watchdog/watchdog-kernel-api.txt, set >> max_hw_heartbeat_ms. > > This isn't completely true. We will have the following in the linux-watchdog tree: > drivers/watchdog/aspeed_wdt.c: set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); > drivers/watchdog/dw_wdt.c: set_bit(WDOG_HW_RUNNING, &wdd->status); > drivers/watchdog/dw_wdt.c: set_bit(WDOG_HW_RUNNING, &wdd->status); > drivers/watchdog/imx2_wdt.c: set_bit(WDOG_HW_RUNNING, &wdog->status); > drivers/watchdog/imx2_wdt.c: set_bit(WDOG_HW_RUNNING, &wdog->status); > drivers/watchdog/max77620_wdt.c: set_bit(WDOG_HW_RUNNING, &wdt_dev->status); > drivers/watchdog/sbsa_gwdt.c: set_bit(WDOG_HW_RUNNING, &wdd->status); > drivers/watchdog/tangox_wdt.c: set_bit(WDOG_HW_RUNNING, &dev->wdt.status); > > I checked the ones that aren't mentioned and aspeed_wdt, max77620_wdt and sbsa_gwdt.c > also have a non-zero value for max_hw_heartbeat_ms. But tangox_wdt.c doesn't set it. > This one will need to be looked at closer. > I had a brief look; the tangox_wdt problem is my fault. I overlooked that with my commit 'watchdog: tangox: Mark running watchdog correctly'. We have a number of options: Set max_hw_heartbeat_ms in tangox_wdt.c, accept this patch, or both. I think we should accept this patch. Thanks, Guenter >> >> Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> >> --- >> drivers/watchdog/watchdog_dev.c | 10 +++++++--- >> 1 file changed, 7 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c >> index 3595cff..14f8a92 100644 >> --- a/drivers/watchdog/watchdog_dev.c >> +++ b/drivers/watchdog/watchdog_dev.c >> @@ -92,9 +92,13 @@ static inline bool watchdog_need_worker(struct watchdog_device *wdd) >> * 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))); >> + return (hm && watchdog_active(wdd) && t > hm) || >> + (t && !watchdog_active(wdd) && watchdog_hw_running(wdd)); >> } >> >> static long watchdog_next_keepalive(struct watchdog_device *wdd) >> @@ -107,7 +111,7 @@ static long watchdog_next_keepalive(struct watchdog_device *wdd) >> unsigned int hw_heartbeat_ms; >> >> virt_timeout = wd_data->last_keepalive + msecs_to_jiffies(timeout_ms); >> - hw_heartbeat_ms = min(timeout_ms, wdd->max_hw_heartbeat_ms); >> + hw_heartbeat_ms = min_not_zero(timeout_ms, wdd->max_hw_heartbeat_ms); >> keepalive_interval = msecs_to_jiffies(hw_heartbeat_ms / 2); >> >> if (!watchdog_active(wdd)) >> -- >> 2.5.0 >> > > Kind regards, > Wim. > >
[toc] | [prev] | [next] | [standalone]
| From | Wim Van Sebroeck <wim@iguana.be> |
|---|---|
| Date | 2016-07-17 22:40 +0200 |
| Subject | Re: [RFC 1/3] watchdog: change watchdog_need_worker logic |
| Message-ID | <rW110-5jw-21@gated-at.bofh.it> |
| In reply to | #1445094 |
Hi Guenter, > On 07/17/2016 12:24 PM, Wim Van Sebroeck wrote: > >Hi Rasmus, > > > >>If the driver indicates that the watchdog is running, the framework > >>should feed it until userspace opens the device, regardless of whether > >>the driver has set max_hw_heartbeat_ms. > >> > >>This patch only affects the case where wdd->max_hw_heartbeat_ms is > >>zero, wdd->timeout is non-zero, the watchdog is not active and the > >>hardware device is running (*): > >> > >>- If wdd->timeout is zero, watchdog_need_worker() returns false both > >>before and after this patch, and watchdog_next_keepalive() is not > >>called. > >> > >>- If watchdog_active(wdd), the return value from watchdog_need_worker > >>is also the same as before (namely, hm && t > hm). Hence in that case, > >>watchdog_next_keepalive() is only called if hm == max_hw_heartbeat_ms > >>is non-zero, so the change to min_not_zero there is a no-op. > >> > >>- If the watchdog is not active and the device is not running, we > >>return false from watchdog_need_worker just as before. > >> > >>That leaves the watchdog_hw_running(wdd) && !watchdog_active(wdd) && > >>wdd->timeout case. Again, it's easy to see that if > >>wdd->max_hw_heartbeat_ms is non-zero, we return true from > >>watchdog_need_worker with and without this patch, and the logic in > >>watchdog_next_keepalive is unchanged. Finally, if > >>wdd->max_hw_heartbeat_ms is 0, we used to end up in the > >>cancel_delayed_work branch, whereas with this patch we end up > >>scheduling a ping timeout_ms/2 from now. > >> > >>(*) This should imply that no current kernel drivers are affected, > >>since the only drivers which explicitly set WDOG_HW_RUNNING are > >>imx2_wdt.c and dw_wdt.c, both of which also provide a non-zero value > >>for max_hw_heartbeat_ms. The watchdog core also sets WDOG_HW_RUNNING, > >>but only when the driver doesn't provide ->stop, in which case it > >>must, according to Documentation/watchdog/watchdog-kernel-api.txt, set > >>max_hw_heartbeat_ms. > > > >This isn't completely true. We will have the following in the > >linux-watchdog tree: > >drivers/watchdog/aspeed_wdt.c: set_bit(WDOG_HW_RUNNING, > >&wdt->wdd.status); > >drivers/watchdog/dw_wdt.c: set_bit(WDOG_HW_RUNNING, &wdd->status); > >drivers/watchdog/dw_wdt.c: set_bit(WDOG_HW_RUNNING, > >&wdd->status); > >drivers/watchdog/imx2_wdt.c: set_bit(WDOG_HW_RUNNING, &wdog->status); > >drivers/watchdog/imx2_wdt.c: set_bit(WDOG_HW_RUNNING, > >&wdog->status); > >drivers/watchdog/max77620_wdt.c: set_bit(WDOG_HW_RUNNING, > >&wdt_dev->status); > >drivers/watchdog/sbsa_gwdt.c: set_bit(WDOG_HW_RUNNING, > >&wdd->status); > >drivers/watchdog/tangox_wdt.c: set_bit(WDOG_HW_RUNNING, > >&dev->wdt.status); > > > >I checked the ones that aren't mentioned and aspeed_wdt, max77620_wdt and > >sbsa_gwdt.c > >also have a non-zero value for max_hw_heartbeat_ms. But tangox_wdt.c > >doesn't set it. > >This one will need to be looked at closer. > > > > I had a brief look; the tangox_wdt problem is my fault. I overlooked that > with > my commit 'watchdog: tangox: Mark running watchdog correctly'. > > We have a number of options: Set max_hw_heartbeat_ms in tangox_wdt.c, > accept this patch, or both. I think we should accept this patch. We accept this patch and add a fix for tangox_wdt.c . > > Thanks, > Guenter > > >> > >>Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> > >>--- > >> drivers/watchdog/watchdog_dev.c | 10 +++++++--- > >> 1 file changed, 7 insertions(+), 3 deletions(-) > >> > >>diff --git a/drivers/watchdog/watchdog_dev.c > >>b/drivers/watchdog/watchdog_dev.c > >>index 3595cff..14f8a92 100644 > >>--- a/drivers/watchdog/watchdog_dev.c > >>+++ b/drivers/watchdog/watchdog_dev.c > >>@@ -92,9 +92,13 @@ static inline bool watchdog_need_worker(struct > >>watchdog_device *wdd) > >> * 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))); > >>+ return (hm && watchdog_active(wdd) && t > hm) || > >>+ (t && !watchdog_active(wdd) && watchdog_hw_running(wdd)); > >> } > >> > >> static long watchdog_next_keepalive(struct watchdog_device *wdd) > >>@@ -107,7 +111,7 @@ static long watchdog_next_keepalive(struct > >>watchdog_device *wdd) > >> unsigned int hw_heartbeat_ms; > >> > >> virt_timeout = wd_data->last_keepalive + > >> msecs_to_jiffies(timeout_ms); > >>- hw_heartbeat_ms = min(timeout_ms, wdd->max_hw_heartbeat_ms); > >>+ hw_heartbeat_ms = min_not_zero(timeout_ms, wdd->max_hw_heartbeat_ms); > >> keepalive_interval = msecs_to_jiffies(hw_heartbeat_ms / 2); > >> > >> if (!watchdog_active(wdd)) > >>-- > >>2.5.0 > >> > > > >Kind regards, > >Wim. > > > > > Kind regards, Wim.
[toc] | [prev] | [next] | [standalone]
| From | Rasmus Villemoes <rasmus.villemoes@prevas.dk> |
|---|---|
| Date | 2016-07-14 11:30 +0200 |
| Subject | [RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE |
| Message-ID | <rUL7X-7Qb-11@gated-at.bofh.it> |
| In reply to | #1443310 |
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 open timeout is also used as a maximum time for an application to
re-open /dev/watchdogN after closing it.
Setting a timeout of 0 (either on the kernel command line or via
sysfs) makes the system behave as if WATCHDOG_OPEN_DEADLINE=n.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/watchdog/Kconfig | 21 +++++++++++++++++++++
drivers/watchdog/watchdog_dev.c | 39 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index b4b3e25..2674ddf 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -53,6 +53,27 @@ config WATCHDOG_SYSFS
Say Y here if you want to enable watchdog device status read through
sysfs attributes.
+config WATCHDOG_OPEN_DEADLINE
+ bool "Allow deadline for opening watchdog device"
+ help
+ If a watchdog driver indicates that to the framework that
+ the hardware watchdog is running, the framework takes care
+ of pinging the watchdog until userspace opens
+ /dev/watchdogN. By selecting this option, you can set a
+ maximum time for which the kernel will do this after the
+ device has been registered.
+
+config WATCHDOG_OPEN_TIMEOUT
+ int "Timeout value for opening watchdog device"
+ depends on WATCHDOG_OPEN_DEADLINE
+ default 120000
+ help
+ The maximum time, in milliseconds, for which the watchdog
+ framework takes care of pinging a watchdog device. A value
+ of 0 means infinite. The value set here can be overridden by
+ the commandline parameter "watchdog.open_timeout" or through
+ sysfs.
+
#
# General Watchdog drivers
#
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index da549e5..584c8a5 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -65,6 +65,9 @@ struct watchdog_core_data {
struct mutex lock;
unsigned long last_keepalive;
unsigned long last_hw_keepalive;
+#ifdef CONFIG_WATCHDOG_OPEN_DEADLINE
+ unsigned long open_deadline;
+#endif
struct delayed_work work;
unsigned long status; /* Internal status bits */
#define _WDOG_DEV_OPEN 0 /* Opened ? */
@@ -78,6 +81,32 @@ static struct watchdog_core_data *old_wd_data;
static struct workqueue_struct *watchdog_wq;
+#ifdef CONFIG_WATCHDOG_OPEN_DEADLINE
+static unsigned open_timeout = CONFIG_WATCHDOG_OPEN_TIMEOUT;
+module_param(open_timeout, uint, 0644);
+
+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);
+}
+#else
+static bool watchdog_past_open_deadline(struct watchdog_core_data *data)
+{
+ return false;
+}
+
+static void watchdog_set_open_deadline(struct watchdog_core_data *data)
+{
+}
+#endif
+
static inline bool watchdog_need_worker(struct watchdog_device *wdd)
{
/* All variables in milli-seconds */
@@ -192,7 +221,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)
@@ -745,6 +780,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 */
@@ -843,6 +879,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,
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Guenter Roeck <linux@roeck-us.net> |
|---|---|
| Date | 2016-07-14 16:50 +0200 |
| Subject | Re: [RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE |
| Message-ID | <rUQ7D-2v3-7@gated-at.bofh.it> |
| In reply to | #1443315 |
On 07/14/2016 02:16 AM, Rasmus Villemoes wrote:
> 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 open timeout is also used as a maximum time for an application to
> re-open /dev/watchdogN after closing it.
>
> Setting a timeout of 0 (either on the kernel command line or via
> sysfs) makes the system behave as if WATCHDOG_OPEN_DEADLINE=n.
>
> Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
> ---
> drivers/watchdog/Kconfig | 21 +++++++++++++++++++++
> drivers/watchdog/watchdog_dev.c | 39 ++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 59 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index b4b3e25..2674ddf 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -53,6 +53,27 @@ config WATCHDOG_SYSFS
> Say Y here if you want to enable watchdog device status read through
> sysfs attributes.
>
> +config WATCHDOG_OPEN_DEADLINE
> + bool "Allow deadline for opening watchdog device"
> + help
> + If a watchdog driver indicates that to the framework that
> + the hardware watchdog is running, the framework takes care
> + of pinging the watchdog until userspace opens
> + /dev/watchdogN. By selecting this option, you can set a
> + maximum time for which the kernel will do this after the
> + device has been registered.
> +
> +config WATCHDOG_OPEN_TIMEOUT
> + int "Timeout value for opening watchdog device"
> + depends on WATCHDOG_OPEN_DEADLINE
> + default 120000
> + help
> + The maximum time, in milliseconds, for which the watchdog
> + framework takes care of pinging a watchdog device. A value
> + of 0 means infinite. The value set here can be overridden by
> + the commandline parameter "watchdog.open_timeout" or through
> + sysfs.
> +
I like the basic idea, and we always thought about implementing it,
though as "initial timeout" (I personally preferred that term).
However, implementing it as configuration option diminishes its
value substantially, since it means that using it in multi-platform
images (such as multi_v7_defconfig) becomes impossible.
The initial timeout should be specified as module option or as
devicetree parameter, and there should be no additional configuration
option.
Where does the module parameter in watchdog_dev.c end up ?
Thanks,
Guenter
> #
> # General Watchdog drivers
> #
> diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
> index da549e5..584c8a5 100644
> --- a/drivers/watchdog/watchdog_dev.c
> +++ b/drivers/watchdog/watchdog_dev.c
> @@ -65,6 +65,9 @@ struct watchdog_core_data {
> struct mutex lock;
> unsigned long last_keepalive;
> unsigned long last_hw_keepalive;
> +#ifdef CONFIG_WATCHDOG_OPEN_DEADLINE
> + unsigned long open_deadline;
> +#endif
> struct delayed_work work;
> unsigned long status; /* Internal status bits */
> #define _WDOG_DEV_OPEN 0 /* Opened ? */
> @@ -78,6 +81,32 @@ static struct watchdog_core_data *old_wd_data;
>
> static struct workqueue_struct *watchdog_wq;
>
> +#ifdef CONFIG_WATCHDOG_OPEN_DEADLINE
> +static unsigned open_timeout = CONFIG_WATCHDOG_OPEN_TIMEOUT;
> +module_param(open_timeout, uint, 0644);
> +
> +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);
> +}
> +#else
> +static bool watchdog_past_open_deadline(struct watchdog_core_data *data)
> +{
> + return false;
> +}
> +
> +static void watchdog_set_open_deadline(struct watchdog_core_data *data)
> +{
> +}
> +#endif
> +
> static inline bool watchdog_need_worker(struct watchdog_device *wdd)
> {
> /* All variables in milli-seconds */
> @@ -192,7 +221,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)
> @@ -745,6 +780,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 */
> @@ -843,6 +879,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,
>
[toc] | [prev] | [next] | [standalone]
| From | Rasmus Villemoes <rasmus.villemoes@prevas.dk> |
|---|---|
| Date | 2016-07-15 09:50 +0200 |
| Subject | Re: [RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE |
| Message-ID | <rV62K-47o-3@gated-at.bofh.it> |
| In reply to | #1443490 |
On 2016-07-14 16:42, Guenter Roeck wrote: > On 07/14/2016 02:16 AM, Rasmus Villemoes wrote: >> >> +config WATCHDOG_OPEN_DEADLINE >> + bool "Allow deadline for opening watchdog device" >> + help >> + If a watchdog driver indicates that to the framework that >> + the hardware watchdog is running, the framework takes care >> + of pinging the watchdog until userspace opens >> + /dev/watchdogN. By selecting this option, you can set a >> + maximum time for which the kernel will do this after the >> + device has been registered. >> + >> +config WATCHDOG_OPEN_TIMEOUT >> + int "Timeout value for opening watchdog device" >> + depends on WATCHDOG_OPEN_DEADLINE >> + default 120000 >> + help >> + The maximum time, in milliseconds, for which the watchdog >> + framework takes care of pinging a watchdog device. A value >> + of 0 means infinite. The value set here can be overridden by >> + the commandline parameter "watchdog.open_timeout" or through >> + sysfs. >> + > > I like the basic idea, and we always thought about implementing it, > though as "initial timeout" (I personally preferred that term). I also used WATCHDOG_INIT_TIMEOUT in my first few drafts, and my helper watchdog_set_open_deadline was called watchdog_set_init_timeout. But then I stumbled on watchdog_init_timeout in watchdog_core.c, and thought that might end up being quite confusing. I think having 'open' part of the name is quite natural, but I don't really have strong feelings about the naming of this thing. > However, implementing it as configuration option diminishes its > value substantially, since it means that using it in multi-platform > images (such as multi_v7_defconfig) becomes impossible. If one wants to allow this feature in an existing _defconfig, one can set OPEN_DEADLINE=y and OPEN_TIMEOUT=0; we could change the default for the latter to that. (I thought about just having that single config option with a default of 0, but it wasn't much more code to allow this thing to be compiled out completely.) Platforms without a running watchdog won't be affected, and for those with, having a non-zero deadline requires opt-in anyway. > The initial timeout should be specified as module option or as > devicetree parameter, and there should be no additional configuration > option. I was under the impression that device tree was exclusively for describing hardware, and this certainly is not that. I also wanted to avoid having to modify each driver, which would seem to be necessary if it was module parameter/DT - the only thing required of a driver now is that it correctly reports WDOG_HW_RUNNING. Regardless of implementation, it's not something that any "distro" kernel is going to enable (with non-zero deadline), so to use it will require some customization - which could be a .config tweak, passing a command line parameter, a custom dtb, and probably other options. ISTM that the first two are the most generic and require the least repeated work across platforms. > Where does the module parameter in watchdog_dev.c end up ? # cat /sys/module/watchdog/parameters/open_timeout 120000 Rasmus
[toc] | [prev] | [next] | [standalone]
| From | Guenter Roeck <linux@roeck-us.net> |
|---|---|
| Date | 2016-07-15 16:30 +0200 |
| Subject | Re: [RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE |
| Message-ID | <rVchP-7ZP-1@gated-at.bofh.it> |
| In reply to | #1444010 |
On 07/15/2016 12:32 AM, Rasmus Villemoes wrote: > On 2016-07-14 16:42, Guenter Roeck wrote: >> On 07/14/2016 02:16 AM, Rasmus Villemoes wrote: >>> >>> +config WATCHDOG_OPEN_DEADLINE >>> + bool "Allow deadline for opening watchdog device" >>> + help >>> + If a watchdog driver indicates that to the framework that >>> + the hardware watchdog is running, the framework takes care >>> + of pinging the watchdog until userspace opens >>> + /dev/watchdogN. By selecting this option, you can set a >>> + maximum time for which the kernel will do this after the >>> + device has been registered. >>> + >>> +config WATCHDOG_OPEN_TIMEOUT >>> + int "Timeout value for opening watchdog device" >>> + depends on WATCHDOG_OPEN_DEADLINE >>> + default 120000 >>> + help >>> + The maximum time, in milliseconds, for which the watchdog >>> + framework takes care of pinging a watchdog device. A value >>> + of 0 means infinite. The value set here can be overridden by >>> + the commandline parameter "watchdog.open_timeout" or through >>> + sysfs. >>> + >> >> I like the basic idea, and we always thought about implementing it, >> though as "initial timeout" (I personally preferred that term). > > I also used WATCHDOG_INIT_TIMEOUT in my first few drafts, and my helper watchdog_set_open_deadline was called watchdog_set_init_timeout. But then I stumbled on watchdog_init_timeout in watchdog_core.c, and thought that might end up being quite confusing. I think having 'open' part of the name is quite natural, but I don't really have strong feelings about the naming of this thing. > You could use "INITIAL". >> However, implementing it as configuration option diminishes its >> value substantially, since it means that using it in multi-platform >> images (such as multi_v7_defconfig) becomes impossible. > > If one wants to allow this feature in an existing _defconfig, one can set OPEN_DEADLINE=y and OPEN_TIMEOUT=0; we could change the default for the latter to that. (I thought about just having that single config option with a default of 0, but it wasn't much more code to allow this thing to be compiled out completely.) Platforms without a running watchdog won't be affected, and for those with, having a non-zero deadline requires opt-in anyway. > Ok, off to Wim to decide then. I don't see the value of WATCHDOG_OPEN_DEADLINE, and for sure don't like the WATCHDOG_OPEN_TIMEOUT parameter. >> The initial timeout should be specified as module option or as >> devicetree parameter, and there should be no additional configuration >> option. > > I was under the impression that device tree was exclusively for describing hardware, and this certainly is not that. I also wanted to avoid having to modify each driver, which would seem to be necessary if it was module parameter/DT - the only thing required of a driver now is that it correctly reports WDOG_HW_RUNNING. What is "hardware" ? It is supposed to describe the system, isn't it ? Part of that system is its clock rate, and the means how the OS is loaded, and both have impact on the initial timeout (and the regular timeout). You might as well argue that clock rates should not be in devicetree either. Clock rates are, after all, just reflecting the _use_ of the hardware, not the hardware itself. Devicetree could be handled in the core, with a function to set the initial timeout, or possibly even with the watchdog registration itself. > > Regardless of implementation, it's not something that any "distro" kernel is going to enable (with non-zero deadline), so to use it will require some customization - which could be a .config tweak, passing a command line parameter, a custom dtb, and probably other options. ISTM that the first two are the most generic and require the least repeated work across platforms. > Each system running a specific kernel will require its own dtb, so I don't see your point there. Guenter
[toc] | [prev] | [next] | [standalone]
| From | Rasmus Villemoes <rasmus.villemoes@prevas.dk> |
|---|---|
| Date | 2016-07-21 00:20 +0200 |
| Subject | Re: [RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE |
| Message-ID | <rX80q-7jq-5@gated-at.bofh.it> |
| In reply to | #1444343 |
On 2016-07-15 16:29, Guenter Roeck wrote: > On 07/15/2016 12:32 AM, Rasmus Villemoes wrote: > >>> The initial timeout should be specified as module option or as >>> devicetree parameter, and there should be no additional configuration >>> option. >> >> I was under the impression that device tree was exclusively for >> describing hardware, and this certainly is not that. I also wanted to >> avoid having to modify each driver, which would seem to be necessary >> if it was module parameter/DT - the only thing required of a driver >> now is that it correctly reports WDOG_HW_RUNNING. > > What is "hardware" ? It is supposed to describe the system, isn't it ? > Part of that system is its clock rate, > and the means how the OS is loaded, and both have impact on the initial > timeout (and the regular timeout). > > You might as well argue that clock rates should not be in devicetree > either. Clock rates are, after all, > just reflecting the _use_ of the hardware, not the hardware itself. But they are used to configure hardware. The init timeout is not a property of any particular device - it configures how the kernel behaves, and as such I find it quite natural to have it in the kernel's .config (and overridable on command line and via sysfs). > Devicetree could be handled in the core, with a function to set the > initial timeout, > or possibly even with the watchdog registration itself. But where in the device tree would you put this value? I'd really prefer not having to modify the node representing each individual watchdog device I might use. Rasmus
[toc] | [prev] | [next] | [standalone]
| From | Guenter Roeck <linux@roeck-us.net> |
|---|---|
| Date | 2016-07-21 02:40 +0200 |
| Subject | Re: [RFC 3/3] watchdog: introduce CONFIG_WATCHDOG_OPEN_DEADLINE |
| Message-ID | <rXabU-8r-3@gated-at.bofh.it> |
| In reply to | #1447506 |
On Thu, Jul 21, 2016 at 12:08:52AM +0200, Rasmus Villemoes wrote: > On 2016-07-15 16:29, Guenter Roeck wrote: > >On 07/15/2016 12:32 AM, Rasmus Villemoes wrote: > > > >>>The initial timeout should be specified as module option or as > >>>devicetree parameter, and there should be no additional configuration > >>>option. > >> > >>I was under the impression that device tree was exclusively for > >>describing hardware, and this certainly is not that. I also wanted to > >>avoid having to modify each driver, which would seem to be necessary > >>if it was module parameter/DT - the only thing required of a driver > >>now is that it correctly reports WDOG_HW_RUNNING. > > > >What is "hardware" ? It is supposed to describe the system, isn't it ? > >Part of that system is its clock rate, > >and the means how the OS is loaded, and both have impact on the initial > >timeout (and the regular timeout). > > > >You might as well argue that clock rates should not be in devicetree > >either. Clock rates are, after all, > >just reflecting the _use_ of the hardware, not the hardware itself. > > But they are used to configure hardware. The init timeout is not a property > of any particular device - it configures how the kernel behaves, and as such > I find it quite natural to have it in the kernel's .config (and overridable > on command line and via sysfs). > I hear you. "configure hardware" is a slippery term, though. After all, one would typically configure the initial timeout in hardware, just as any "normal" timeout. In many cases, this will actually already be the case (and should be), since the watchdog should be enabled by the ROMMON or BIOS before control is passed to the kernel. As such, the initial timeout should already be set when the driver is loaded. Also, I would want to be able to use the same kernel, and the same root file system, on different machines without having to bother about system variants, even more so if I was responsible for potentially dozens of different variants with subtle differences in hardware. One ends up having to maintain configuration files which happen to closely look like devicetree files, plus an entire infrastructure to detect and configure hardware variants. Such configuration files may be part of the root file system, or have to be maintained separately. Either creates additional overhead. Unfortunately, those configuration files can only be read after the kernel passed control to user space, which typically happens after the driver to be controlled was already loaded. Using sysfs is therefore pretty much useless - one might as well start the watchdog daemon as early as possible after passing control to user space. This leaves module parameters, which have to be passed on the kernel command line to be useful. This is not really desirable either in most situations, since now the system variant specific configuration has to be implemented somewhere in the ROMMON, BIOS, or bootloader configuration file. Another level of complexity added, since the per-variant boot parameters have to be managed somewhere. Plus, as mentioned above, if the initial timeout has to be passed as parameter to the kernel, the passing entity might as well program it into the hardware directly, and start the watchdog, thereby fixing the gap between hand-off to kernel and loading the watchdog driver. So what is left ? Situations where the hardware does not tell software what its configured timeout is, and situations where the maximum hardware timeout is smaller than the required initial timeout. Both would, in my opinion, warrant the use of a devicetree property, but I understand that others may have a different opinion. Overall, my conclusion is that if a devicetree property is not acceptable for some reason, we should drop the notion of supporting an initial or "open" timeout entirely, and leave it up to the BIOS/ROMMON as well as the respective watchdog driver to set an acceptable default or initial timeout. This initial timeout can (and will) be overwritten with the desired runtime timeout by the watchdog daemon after it opened the watchdog device. > >Devicetree could be handled in the core, with a function to set the > >initial timeout, > >or possibly even with the watchdog registration itself. > > But where in the device tree would you put this value? I'd really prefer not > having to modify the node representing each individual watchdog device I > might use. > The existing "timeout-sec" property is in the watchdog node as well. Thanks, Guenter
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web