All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2] fw_setenv: avoid writing environment when nothing has changed
@ 2018-09-27 20:45 Rasmus Villemoes
  2018-10-30 11:05 ` Rasmus Villemoes
  2019-11-20  0:19 ` Joe Hershberger
  0 siblings, 2 replies; 3+ messages in thread
From: Rasmus Villemoes @ 2018-09-27 20:45 UTC (permalink / raw)
  To: u-boot

In the case where one deletes an already-non-existing variable, or sets
a variable to the value it already has, there is no point in writing the
environment back, thus reducing wear on the underlying storage
device.

In the case of redundant environments, if the two environments
differ (e.g. because one is corrupt), make sure that any call of
fw_setenv causes the two to become synchronized, even if the fw_setenv
call does not change anything in the good copy.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
Add logic to ensure a corrupt copy gets replaced, even if fw_setenv
wouldn't change anything in the good copy.

 tools/env/fw_env.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
index a5d75958e1..66372dad55 100644
--- a/tools/env/fw_env.c
+++ b/tools/env/fw_env.c
@@ -110,6 +110,7 @@ struct environment {
 	unsigned char *flags;
 	char *data;
 	enum flag_scheme flag_scheme;
+	int dirty;
 };
 
 static struct environment environment = {
@@ -508,6 +509,9 @@ int fw_env_flush(struct env_opts *opts)
 	if (!opts)
 		opts = &default_opts;
 
+	if (!environment.dirty)
+		return 0;
+
 	/*
 	 * Update CRC
 	 */
@@ -553,7 +557,8 @@ int fw_env_write(char *name, char *value)
 
 	deleting = (oldval && !(value && strlen(value)));
 	creating = (!oldval && (value && strlen(value)));
-	overwriting = (oldval && (value && strlen(value)));
+	overwriting = (oldval && (value && strlen(value) &&
+				  strcmp(oldval, value)));
 
 	/* check for permission */
 	if (deleting) {
@@ -593,6 +598,7 @@ int fw_env_write(char *name, char *value)
 		/* Nothing to do */
 		return 0;
 
+	environment.dirty = 1;
 	if (deleting || overwriting) {
 		if (*++nxt == '\0') {
 			*env = '\0';
@@ -1441,6 +1447,7 @@ int fw_env_open(struct env_opts *opts)
 				"Warning: Bad CRC, using default environment\n");
 			memcpy(environment.data, default_environment,
 			       sizeof(default_environment));
+			environment.dirty = 1;
 		}
 	} else {
 		flag0 = *environment.flags;
@@ -1494,6 +1501,16 @@ int fw_env_open(struct env_opts *opts)
 		crc1_ok = (crc1 == redundant->crc);
 		flag1 = redundant->flags;
 
+		/*
+		 * environment.data still points to ((struct
+		 * env_image_redundant *)addr0)->data. If the two
+		 * environments differ, or one has bad crc, force a
+		 * write-out by marking the environment dirty.
+		 */
+		if (memcmp(environment.data, redundant->data, ENV_SIZE) ||
+		    !crc0_ok || !crc1_ok)
+			environment.dirty = 1;
+
 		if (crc0_ok && !crc1_ok) {
 			dev_current = 0;
 		} else if (!crc0_ok && crc1_ok) {
@@ -1503,6 +1520,7 @@ int fw_env_open(struct env_opts *opts)
 				"Warning: Bad CRC, using default environment\n");
 			memcpy(environment.data, default_environment,
 			       sizeof(default_environment));
+			environment.dirty = 1;
 			dev_current = 0;
 		} else {
 			switch (environment.flag_scheme) {
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [U-Boot] [PATCH v2] fw_setenv: avoid writing environment when nothing has changed
  2018-09-27 20:45 [U-Boot] [PATCH v2] fw_setenv: avoid writing environment when nothing has changed Rasmus Villemoes
@ 2018-10-30 11:05 ` Rasmus Villemoes
  2019-11-20  0:19 ` Joe Hershberger
  1 sibling, 0 replies; 3+ messages in thread
From: Rasmus Villemoes @ 2018-10-30 11:05 UTC (permalink / raw)
  To: u-boot

On 2018-09-27 22:45, Rasmus Villemoes wrote:
> In the case where one deletes an already-non-existing variable, or sets
> a variable to the value it already has, there is no point in writing the
> environment back, thus reducing wear on the underlying storage
> device.
> 
> In the case of redundant environments, if the two environments
> differ (e.g. because one is corrupt), make sure that any call of
> fw_setenv causes the two to become synchronized, even if the fw_setenv
> call does not change anything in the good copy.
> 
> Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
> ---
> Add logic to ensure a corrupt copy gets replaced, even if fw_setenv
> wouldn't change anything in the good copy.

ping.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [U-Boot] [PATCH v2] fw_setenv: avoid writing environment when nothing has changed
  2018-09-27 20:45 [U-Boot] [PATCH v2] fw_setenv: avoid writing environment when nothing has changed Rasmus Villemoes
  2018-10-30 11:05 ` Rasmus Villemoes
@ 2019-11-20  0:19 ` Joe Hershberger
  1 sibling, 0 replies; 3+ messages in thread
From: Joe Hershberger @ 2019-11-20  0:19 UTC (permalink / raw)
  To: u-boot

On Thu, Sep 27, 2018 at 3:45 PM Rasmus Villemoes
<rasmus.villemoes@prevas.dk> wrote:
>
> In the case where one deletes an already-non-existing variable, or sets
> a variable to the value it already has, there is no point in writing the
> environment back, thus reducing wear on the underlying storage
> device.
>
> In the case of redundant environments, if the two environments
> differ (e.g. because one is corrupt), make sure that any call of
> fw_setenv causes the two to become synchronized, even if the fw_setenv
> call does not change anything in the good copy.
>
> Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>

Nit below, but

Acked-by: Joe Hershberger <joe.hershberger@ni.com>

> ---
> Add logic to ensure a corrupt copy gets replaced, even if fw_setenv
> wouldn't change anything in the good copy.
>
>  tools/env/fw_env.c | 20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
> index a5d75958e1..66372dad55 100644
> --- a/tools/env/fw_env.c
> +++ b/tools/env/fw_env.c
> @@ -110,6 +110,7 @@ struct environment {
>         unsigned char *flags;
>         char *data;
>         enum flag_scheme flag_scheme;
> +       int dirty;
>  };
>
>  static struct environment environment = {

It seems prudent to initialize the dirty flag here.

> @@ -508,6 +509,9 @@ int fw_env_flush(struct env_opts *opts)
>         if (!opts)
>                 opts = &default_opts;
>
> +       if (!environment.dirty)
> +               return 0;
> +
>         /*
>          * Update CRC
>          */
> @@ -553,7 +557,8 @@ int fw_env_write(char *name, char *value)
>
>         deleting = (oldval && !(value && strlen(value)));
>         creating = (!oldval && (value && strlen(value)));
> -       overwriting = (oldval && (value && strlen(value)));
> +       overwriting = (oldval && (value && strlen(value) &&
> +                                 strcmp(oldval, value)));
>
>         /* check for permission */
>         if (deleting) {
> @@ -593,6 +598,7 @@ int fw_env_write(char *name, char *value)
>                 /* Nothing to do */
>                 return 0;
>
> +       environment.dirty = 1;
>         if (deleting || overwriting) {
>                 if (*++nxt == '\0') {
>                         *env = '\0';
> @@ -1441,6 +1447,7 @@ int fw_env_open(struct env_opts *opts)
>                                 "Warning: Bad CRC, using default environment\n");
>                         memcpy(environment.data, default_environment,
>                                sizeof(default_environment));
> +                       environment.dirty = 1;
>                 }
>         } else {
>                 flag0 = *environment.flags;
> @@ -1494,6 +1501,16 @@ int fw_env_open(struct env_opts *opts)
>                 crc1_ok = (crc1 == redundant->crc);
>                 flag1 = redundant->flags;
>
> +               /*
> +                * environment.data still points to ((struct
> +                * env_image_redundant *)addr0)->data. If the two
> +                * environments differ, or one has bad crc, force a
> +                * write-out by marking the environment dirty.
> +                */
> +               if (memcmp(environment.data, redundant->data, ENV_SIZE) ||
> +                   !crc0_ok || !crc1_ok)
> +                       environment.dirty = 1;
> +
>                 if (crc0_ok && !crc1_ok) {
>                         dev_current = 0;
>                 } else if (!crc0_ok && crc1_ok) {
> @@ -1503,6 +1520,7 @@ int fw_env_open(struct env_opts *opts)
>                                 "Warning: Bad CRC, using default environment\n");
>                         memcpy(environment.data, default_environment,
>                                sizeof(default_environment));
> +                       environment.dirty = 1;
>                         dev_current = 0;
>                 } else {
>                         switch (environment.flag_scheme) {
> --
> 2.16.4
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-11-20  0:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-27 20:45 [U-Boot] [PATCH v2] fw_setenv: avoid writing environment when nothing has changed Rasmus Villemoes
2018-10-30 11:05 ` Rasmus Villemoes
2019-11-20  0:19 ` Joe Hershberger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.