mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Juergen Borleis <jbe@pengutronix.de>
Cc: barebox@lists.infradead.org
Subject: Re: [PATCH 3/5] Watchdog: add a scope value to the watchdog feature
Date: Wed, 24 Jun 2015 08:51:11 +0200	[thread overview]
Message-ID: <20150624065111.GT6325@pengutronix.de> (raw)
In-Reply-To: <1435064284-8015-4-git-send-email-jbe@pengutronix.de>

On Tue, Jun 23, 2015 at 02:58:02PM +0200, Juergen Borleis wrote:
> Sometimes the SoC internal watchdogs are inappropriate to restart the
> machine in a reliable manner. This change should help to handle more than
> one watchdog unit by adding a scope parameter. The framework always
> prefers the watchdog with the widest scope. For example a watchdog
> which is able to restart the whole machine (SoC + external devices) gets
> precedence over a watchdog which can restart the SoC only.
> 
> Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
> ---
>  Documentation/user/user-manual.rst |  1 +
>  Documentation/user/watchdog.rst    | 74 ++++++++++++++++++++++++++++++++++++++
>  common/restart.c                   |  6 ++++
>  drivers/watchdog/im28wd.c          |  1 +
>  drivers/watchdog/imxwd.c           |  1 +
>  drivers/watchdog/wd_core.c         | 24 +++++++++++--
>  include/watchdog.h                 |  3 ++
>  7 files changed, 108 insertions(+), 2 deletions(-)
>  create mode 100644 Documentation/user/watchdog.rst
> 
> diff --git a/Documentation/user/user-manual.rst b/Documentation/user/user-manual.rst
> index 0d6daee..8a32469 100644
> --- a/Documentation/user/user-manual.rst
> +++ b/Documentation/user/user-manual.rst
> @@ -30,6 +30,7 @@ Contents:
>     system-setup
>     reset-reason
>     system-reset
> +   watchdog
>  
>  * :ref:`search`
>  * :ref:`genindex`
> diff --git a/Documentation/user/watchdog.rst b/Documentation/user/watchdog.rst
> new file mode 100644
> index 0000000..d8e6e76
> --- /dev/null
> +++ b/Documentation/user/watchdog.rst
> @@ -0,0 +1,74 @@
> +.. _watchdog_usage:
> +
> +Using a watchdog
> +----------------
> +
> +Watchdogs are commonly used to prevent bad software from hanging the whole
> +system for ever. Sometimes a simple approach can help to make a system work
> +if hanging failures are happen very seldom: just restart the system and do
> +everything again in the same way as it was done when the system starts the
> +last time.
> +
> +But using a watchdog should always be the 'last resort' to keep a machine
> +working. The focus should still be on finding and fixing the bug ;)
> +
> +A more complex way to use a watchdog in a real-word example is when the state
> +frameworks comes into play. Then the watchdog's task isn't only to keep the
> +machine working. It also monitors the whole health of the machine including
> +hardware and software. Especially something like a firmware update can go
> +wrong: a wrong firmware was programmed (wrong release or for a different machine),
> +programming was incomplete due to a user intervention or power fail and so on.
> +
> +In this case the watchdog does not just restart the system if the software hangs,
> +it also provides 'additional' information about the firmware by this restart.
> +The barebox's state framework is now able to run some kind of state machine to handle
> +firmware updates in a correct manner: trying the new firmware once and if it fails falling
> +back to the previous firmware (if available) for example.
> +
> +Refer the :ref:`reset_reason` how to detect the reason why the bootloader runs.
> +This information can be used by the barebox's state framework.
> +
> +.. _watchdog_restart_pitfalls:
> +
> +Watchdog Pitfalls
> +~~~~~~~~~~~~~~~~~
> +
> +If a watchdog triggers a machine restart it suffers from the same issues like
> +a regular user triggered system machine restart. Refer :ref:`system_reset_pitfalls`
> +for further details.
> +So keep this in mind when you select an available watchdog on your machine for
> +this task. And if you are a hardware designer keep this in mind even more, and
> +provide a reliable restart source for the software developers and to keep their
> +headache low.
> +
> +Watchdogs from the developers point of view
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Watchdogs gets registered in barebox with a scope. When you register your own
> +watchdog driver, check its hardware scope carefully and use one of the
> +definitions from the file ``include/restart.h``.
> +
> +The list of defined scopes (defined in file ``include/restart.h``):
> +
> +* ``FEATURE_SCOPE_UNKNOWN``: completely useless watchdog, maybe a last resort..
> +* ``FEATURE_SCOPE_CPU``: this watchdog is able to restart the core CPU only.
> +  Regarding to the issues in :ref:`system_reset_pitfalls` this kind of watchdog
> +  seems more or less useless.
> +* ``FEATURE_SCOPE_SOC``: this watchdog is able to restart the whole SoC. Regarding
> +  to the issues in :ref:`system_reset_pitfalls` this scope is more reliable, but
> +  depends on the machine and its hardware design if is able to bring the machine
> +  back into life under every circumstance.
> +* ``FEATURE_SCOPE_MACHINE``: it is able to restart the whole machine and does
> +  the same like a real ``POR`` does. Best scope and always reliable.
> +
> +The selected scope is very important because barebox will always use
> +the watchdog with the best available scope.
> +
> +But that is true only for watchdogs used in barebox and as long barebox is
> +running.
> +
> +If an operating system runs later on, it is the task of this OS to use a watchdog
> +with a correct scope. Otherwise it suffers from the :ref:`system_reset_pitfalls`
> +as well. This is even more important if the state framework is used. That means
> +barebox and the operating system must use the same watchdog in order to check
> +and change the states correctly.
> diff --git a/common/restart.c b/common/restart.c
> index 67797e4..c0c4861 100644
> --- a/common/restart.c
> +++ b/common/restart.c
> @@ -119,6 +119,12 @@ int restart_remove_handler(void (*func)(struct device_d*), struct device_d *dev)
>  }
>  EXPORT_SYMBOL(restart_remove_handler);
>  
> +void watchdog_update_global_info(int *scope)
> +{
> +	globalvar_add_simple_enum("system.wd.scope", scope,
> +				scope_names, ARRAY_SIZE(scope_names));
> +}
> +
>  static int reset_feature_init(void)
>  {
>  	reset_source_update_global_info();
> diff --git a/drivers/watchdog/im28wd.c b/drivers/watchdog/im28wd.c
> index c824a25..918d37a 100644
> --- a/drivers/watchdog/im28wd.c
> +++ b/drivers/watchdog/im28wd.c
> @@ -197,6 +197,7 @@ static int imx28_wd_probe(struct device_d *dev)
>  	if (IS_ERR(priv->regs))
>  		return PTR_ERR(priv->regs);
>  	priv->wd.set_timeout = imx28_watchdog_set_timeout;
> +	priv->wd.scope = FEATURE_SCOPE_SOC;
>  
>  	if (!(readl(priv->regs + MXS_RTC_STAT) & MXS_RTC_STAT_WD_PRESENT)) {
>  		rc = -ENODEV;
> diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
> index 3cbae09..60772b1 100644
> --- a/drivers/watchdog/imxwd.c
> +++ b/drivers/watchdog/imxwd.c
> @@ -185,6 +185,7 @@ static int imx_wd_probe(struct device_d *dev)
>  	}
>  	priv->ops = ops;
>  	priv->wd.set_timeout = imx_watchdog_set_timeout;
> +	priv->wd.scope = FEATURE_SCOPE_SOC;
>  	priv->dev = dev;
>  
>  	if (IS_ENABLED(CONFIG_WATCHDOG_IMX)) {
> diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
> index 3d0cfc6..6386cf3 100644
> --- a/drivers/watchdog/wd_core.c
> +++ b/drivers/watchdog/wd_core.c
> @@ -13,22 +13,32 @@
>   */
>  
>  #include <common.h>
> +#include <init.h>
>  #include <command.h>
>  #include <errno.h>
>  #include <linux/ctype.h>
>  #include <watchdog.h>
> +#include <globalvar.h>
> +#include <restart.h>
>  
>  /*
>   * Note: this simple framework supports one watchdog only.
>   */
>  static struct watchdog *watchdog;
> +static int watchdog_scope;
> +
> +void watchdog_update_global_info(int*);
>  
>  int watchdog_register(struct watchdog *wd)
>  {
> -	if (watchdog != NULL)
> -		return -EBUSY;
> +	/* ignore a lower or same priority, it isn't a failure */
> +	if (wd->scope <= watchdog_scope)
> +		return 0;
>  
>  	watchdog = wd;
> +	watchdog_scope = (int)wd->scope;

I don't think we have to make this explicit cast from enum to int.

> +	watchdog_update_global_info(&watchdog_scope);

Unnecessary.

> +
>  	return 0;
>  }
>  EXPORT_SYMBOL(watchdog_register);
> @@ -39,6 +49,9 @@ int watchdog_deregister(struct watchdog *wd)
>  		return -ENODEV;
>  
>  	watchdog = NULL;
> +	watchdog_scope = (int)FEATURE_SCOPE_UNKNOWN;
> +	watchdog_update_global_info(&watchdog_scope);

Unnecessary.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  reply	other threads:[~2015-06-24  6:51 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-23 12:57 [PATCHv2] Change barebox regarding "machine-restart", "reset cause detection" und "watchdog usage" Juergen Borleis
2015-06-23 12:58 ` [PATCH 1/5] Reset reason: add a scope value to the reset reason feature Juergen Borleis
2015-06-24  6:32   ` Sascha Hauer
2015-06-24  7:35     ` Juergen Borleis
2015-06-23 12:58 ` [PATCH 2/5] System restart: add a scope value to the system restart feature Juergen Borleis
2015-06-24  6:42   ` Sascha Hauer
2015-06-23 12:58 ` [PATCH 3/5] Watchdog: add a scope value to the watchdog feature Juergen Borleis
2015-06-24  6:51   ` Sascha Hauer [this message]
2015-06-23 12:58 ` [PATCH 4/5] Watchdog/i.MX: make the watchdog driver a regular driver Juergen Borleis
2015-06-23 12:58 ` [PATCH 5/5] MFD/DA9053: da9053: add basic da9053 driver Juergen Borleis
2015-06-25  7:34 [PATCHv3] Change barebox regarding "machine-restart", "reset cause detection" und "watchdog usage" Juergen Borleis
2015-06-25  7:34 ` [PATCH 3/5] Watchdog: add a scope value to the watchdog feature Juergen Borleis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150624065111.GT6325@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    --cc=jbe@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox