Message ID | 844212451999302a41d87526d6616b1af7c781d1.1516723179.git-series.maxime.ripard@free-electrons.com |
---|---|
State | Accepted |
Commit | 7d714a24d7258db1188abe3c7c9c46a1cc7ab8be |
Headers | show |
Series | env: Multiple env support and env transition for sunxi | expand |
On Tue, Jan 23, 2018 at 09:16:58PM +0100, Maxime Ripard wrote: > Now that we have everything in place to support multiple environment, let's > make sure the current code can use it. > > The priority used between the various environment is the same one that was > used in the code previously. > > At read / init times, the highest priority environment is going to be > detected, and we'll use the same one without lookup during writes. This > should implement the same behaviour than we currently have. > > Reviewed-by: Andre Przywara <andre.przywara@arm.com> > Reviewed-by: Simon Glass <sjg@chromium.org> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Applied to u-boot/master, thanks! -- Tom
On 23.01.2018 21:16, Maxime Ripard wrote: > Now that we have everything in place to support multiple environment, let's > make sure the current code can use it. > > The priority used between the various environment is the same one that was > used in the code previously. > > At read / init times, the highest priority environment is going to be > detected, Does priority handling really work here? Most env drivers seem to ignore the return value of env_import and may thus return success although importing the environment failed (only reading the data from the device succeeded). This is from reading the code, I haven't had a chance to test this, yet. > and we'll use the same one without lookup during writes. This > should implement the same behaviour than we currently have. Is there a way to save the environment to drivers other than the one selected at init time? Regards, Simon > > Reviewed-by: Andre Przywara <andre.przywara@arm.com> > Reviewed-by: Simon Glass <sjg@chromium.org> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> > --- > env/env.c | 80 +++++++++++++++++++++++++++++++++++--------------------- > 1 file changed, 50 insertions(+), 30 deletions(-) > > diff --git a/env/env.c b/env/env.c > index 906f28ee50a1..1182fdb545db 100644 > --- a/env/env.c > +++ b/env/env.c > @@ -26,6 +26,41 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) > return NULL; > } > > +static enum env_location env_locations[] = { > +#ifdef CONFIG_ENV_IS_IN_EEPROM > + ENVL_EEPROM, > +#endif > +#ifdef CONFIG_ENV_IS_IN_FAT > + ENVL_FAT, > +#endif > +#ifdef CONFIG_ENV_IS_IN_FLASH > + ENVL_FLASH, > +#endif > +#ifdef CONFIG_ENV_IS_IN_MMC > + ENVL_MMC, > +#endif > +#ifdef CONFIG_ENV_IS_IN_NAND > + ENVL_NAND, > +#endif > +#ifdef CONFIG_ENV_IS_IN_NVRAM > + ENVL_NVRAM, > +#endif > +#ifdef CONFIG_ENV_IS_IN_REMOTE > + ENVL_REMOTE, > +#endif > +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH > + ENVL_SPI_FLASH, > +#endif > +#ifdef CONFIG_ENV_IS_IN_UBI > + ENVL_UBI, > +#endif > +#ifdef CONFIG_ENV_IS_NOWHERE > + ENVL_NOWHERE, > +#endif > +}; > + > +static enum env_location env_load_location = ENVL_UNKNOWN; > + > /** > * env_get_location() - Returns the best env location for a board > * @op: operations performed on the environment > @@ -45,36 +80,21 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) > */ > static enum env_location env_get_location(enum env_operation op, int prio) > { > - /* > - * We support a single environment, so any environment asked > - * with a priority that is not zero is out of our supported > - * bounds. > - */ > - if (prio >= 1) > - return ENVL_UNKNOWN; > - > - if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM) > - return ENVL_EEPROM; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT) > - return ENVL_FAT; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH) > - return ENVL_FLASH; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC) > - return ENVL_MMC; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND) > - return ENVL_NAND; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM) > - return ENVL_NVRAM; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE) > - return ENVL_REMOTE; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH) > - return ENVL_SPI_FLASH; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI) > - return ENVL_UBI; > - else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE) > - return ENVL_NOWHERE; > - else > - return ENVL_UNKNOWN; > + switch (op) { > + case ENVOP_GET_CHAR: > + case ENVOP_INIT: > + case ENVOP_LOAD: > + if (prio >= ARRAY_SIZE(env_locations)) > + return ENVL_UNKNOWN; > + > + env_load_location = env_locations[prio]; > + return env_load_location; > + > + case ENVOP_SAVE: > + return env_load_location; > + } > + > + return ENVL_UNKNOWN; > } > >
On 01/30/2018 12:19 AM, Simon Goldschmidt wrote: > On 23.01.2018 21:16, Maxime Ripard wrote: >> Now that we have everything in place to support multiple environment, let's >> make sure the current code can use it. >> >> The priority used between the various environment is the same one that was >> used in the code previously. >> >> At read / init times, the highest priority environment is going to be >> detected, > > Does priority handling really work here? Most env drivers seem to ignore > the return value of env_import and may thus return success although > importing the environment failed (only reading the data from the device > succeeded). > > This is from reading the code, I haven't had a chance to test this, yet. It is broken on my LS1043ARDB with simply NOR flash. I am trying to determine what went wrong. York
On 01/30/2018 11:40 AM, York Sun wrote: > On 01/30/2018 12:19 AM, Simon Goldschmidt wrote: >> On 23.01.2018 21:16, Maxime Ripard wrote: >>> Now that we have everything in place to support multiple environment, let's >>> make sure the current code can use it. >>> >>> The priority used between the various environment is the same one that was >>> used in the code previously. >>> >>> At read / init times, the highest priority environment is going to be >>> detected, >> >> Does priority handling really work here? Most env drivers seem to ignore >> the return value of env_import and may thus return success although >> importing the environment failed (only reading the data from the device >> succeeded). >> >> This is from reading the code, I haven't had a chance to test this, yet. > > It is broken on my LS1043ARDB with simply NOR flash. I am trying to > determine what went wrong. > I found the problem. The variable "env_load_location" is static. It is probably not write-able during booting from flash. It is expected to be set during ENVOP_INIT. But if I print this variable, it has ENVL_UNKNOWN. I can make it work by moving env_load_location to global data structure. That being said, this addition of multiple environments really slows down the booting process for me. I see every time env_get_char() is called, env_driver_lookup() runs. A simple call of env_get_f() gets slowed down dramatically. I didn't find out where the most time is spent yet. Does anyone else experience this unbearable slowness? York
On 01/30/2018 12:16 PM, York Sun wrote: > On 01/30/2018 11:40 AM, York Sun wrote: >> On 01/30/2018 12:19 AM, Simon Goldschmidt wrote: >>> On 23.01.2018 21:16, Maxime Ripard wrote: >>>> Now that we have everything in place to support multiple environment, let's >>>> make sure the current code can use it. >>>> >>>> The priority used between the various environment is the same one that was >>>> used in the code previously. >>>> >>>> At read / init times, the highest priority environment is going to be >>>> detected, >>> >>> Does priority handling really work here? Most env drivers seem to ignore >>> the return value of env_import and may thus return success although >>> importing the environment failed (only reading the data from the device >>> succeeded). >>> >>> This is from reading the code, I haven't had a chance to test this, yet. >> >> It is broken on my LS1043ARDB with simply NOR flash. I am trying to >> determine what went wrong. >> > > I found the problem. The variable "env_load_location" is static. It is > probably not write-able during booting from flash. It is expected to be > set during ENVOP_INIT. But if I print this variable, it has > ENVL_UNKNOWN. I can make it work by moving env_load_location to global > data structure. > > That being said, this addition of multiple environments really slows > down the booting process for me. I see every time env_get_char() is > called, env_driver_lookup() runs. A simple call of env_get_f() gets > slowed down dramatically. I didn't find out where the most time is spent > yet. > > Does anyone else experience this unbearable slowness? > I found the problem. In patch #3 in this series, the default get_char() was dropped so there is no driver for a plain NOR flash. A quick (and maybe dirty) fix is this diff --git a/env/env.c b/env/env.c index edfb575..210bae2 100644 --- a/env/env.c +++ b/env/env.c @@ -159,7 +159,7 @@ int env_get_char(int index) int ret; if (!drv->get_char) - continue; + return *(uchar *)(gd->env_addr + index); if (!env_has_inited(drv->location)) continue; With this temporary fix, my flash chip works again and I can boot all the way up in a timely manner. I still don't like to call env_driver_lookup() thousands of times to get a simple env variable. Can Maxime post a quick post soon? York
On 31.01.2018 00:02, York Sun wrote: > On 01/30/2018 12:16 PM, York Sun wrote: >> On 01/30/2018 11:40 AM, York Sun wrote: >>> On 01/30/2018 12:19 AM, Simon Goldschmidt wrote: >>>> On 23.01.2018 21:16, Maxime Ripard wrote: >>>>> Now that we have everything in place to support multiple environment, let's >>>>> make sure the current code can use it. >>>>> >>>>> The priority used between the various environment is the same one that was >>>>> used in the code previously. >>>>> >>>>> At read / init times, the highest priority environment is going to be >>>>> detected, >>>> Does priority handling really work here? Most env drivers seem to ignore >>>> the return value of env_import and may thus return success although >>>> importing the environment failed (only reading the data from the device >>>> succeeded). >>>> >>>> This is from reading the code, I haven't had a chance to test this, yet. >>> It is broken on my LS1043ARDB with simply NOR flash. I am trying to >>> determine what went wrong. >>> >> I found the problem. The variable "env_load_location" is static. It is >> probably not write-able during booting from flash. It is expected to be >> set during ENVOP_INIT. But if I print this variable, it has >> ENVL_UNKNOWN. I can make it work by moving env_load_location to global >> data structure. >> >> That being said, this addition of multiple environments really slows >> down the booting process for me. I see every time env_get_char() is >> called, env_driver_lookup() runs. A simple call of env_get_f() gets >> slowed down dramatically. I didn't find out where the most time is spent >> yet. >> >> Does anyone else experience this unbearable slowness? Yes. Depending on CPU speed... :-) On my board, that slowdown comes from the fact that env_get_f does not check the return value of env_get_char for an error. That leads to trying for CONFIG_ENV_SIZE times, which is of course slow. I'll post a fix for that. > I found the problem. In patch #3 in this series, the default get_char() > was dropped so there is no driver for a plain NOR flash. A quick (and > maybe dirty) fix is this That patch #3 actually changed the behavior for all env drivers not providing .get_char (so all drivers except for eeprom and nvram) from returning what's behind gd->env_addr. Your patch below restores the old behaviour. I can't tell what's the correct behaviour though: in my tests, env_get_f got called even after importing the environment, which is not what I would have expected... > diff --git a/env/env.c b/env/env.c > index edfb575..210bae2 100644 > --- a/env/env.c > +++ b/env/env.c > @@ -159,7 +159,7 @@ int env_get_char(int index) > int ret; > > if (!drv->get_char) > - continue; > + return *(uchar *)(gd->env_addr + index); > > if (!env_has_inited(drv->location)) > continue; > > With this temporary fix, my flash chip works again and I can boot all > the way up in a timely manner. I still don't like to call > env_driver_lookup() thousands of times to get a simple env variable. That's not a thing Maxime has changed but a change that came in when adding environment drivers. Simon > > Can Maxime post a quick post soon? > > York >
On 23.01.2018 21:16, Maxime Ripard wrote: > Now that we have everything in place to support multiple environment, let's > make sure the current code can use it. I get more build errors testing this feature: there's a global variable 'env_ptr' declared in flash, nand, nvram and remote env drivers (declared as extern in envrionment.h). From reading the code, it seems like these could just be changed to static, since 'env_ptr' is not used outside these drivers? Simon > > The priority used between the various environment is the same one that was > used in the code previously. > > At read / init times, the highest priority environment is going to be > detected, and we'll use the same one without lookup during writes. This > should implement the same behaviour than we currently have. > > Reviewed-by: Andre Przywara <andre.przywara@arm.com> > Reviewed-by: Simon Glass <sjg@chromium.org> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> > --- > env/env.c | 80 +++++++++++++++++++++++++++++++++++--------------------- > 1 file changed, 50 insertions(+), 30 deletions(-) > > diff --git a/env/env.c b/env/env.c > index 906f28ee50a1..1182fdb545db 100644 > --- a/env/env.c > +++ b/env/env.c > @@ -26,6 +26,41 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) > return NULL; > } > > +static enum env_location env_locations[] = { > +#ifdef CONFIG_ENV_IS_IN_EEPROM > + ENVL_EEPROM, > +#endif > +#ifdef CONFIG_ENV_IS_IN_FAT > + ENVL_FAT, > +#endif > +#ifdef CONFIG_ENV_IS_IN_FLASH > + ENVL_FLASH, > +#endif > +#ifdef CONFIG_ENV_IS_IN_MMC > + ENVL_MMC, > +#endif > +#ifdef CONFIG_ENV_IS_IN_NAND > + ENVL_NAND, > +#endif > +#ifdef CONFIG_ENV_IS_IN_NVRAM > + ENVL_NVRAM, > +#endif > +#ifdef CONFIG_ENV_IS_IN_REMOTE > + ENVL_REMOTE, > +#endif > +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH > + ENVL_SPI_FLASH, > +#endif > +#ifdef CONFIG_ENV_IS_IN_UBI > + ENVL_UBI, > +#endif > +#ifdef CONFIG_ENV_IS_NOWHERE > + ENVL_NOWHERE, > +#endif > +}; > + > +static enum env_location env_load_location = ENVL_UNKNOWN; > + > /** > * env_get_location() - Returns the best env location for a board > * @op: operations performed on the environment > @@ -45,36 +80,21 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) > */ > static enum env_location env_get_location(enum env_operation op, int prio) > { > - /* > - * We support a single environment, so any environment asked > - * with a priority that is not zero is out of our supported > - * bounds. > - */ > - if (prio >= 1) > - return ENVL_UNKNOWN; > - > - if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM) > - return ENVL_EEPROM; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT) > - return ENVL_FAT; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH) > - return ENVL_FLASH; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC) > - return ENVL_MMC; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND) > - return ENVL_NAND; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM) > - return ENVL_NVRAM; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE) > - return ENVL_REMOTE; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH) > - return ENVL_SPI_FLASH; > - else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI) > - return ENVL_UBI; > - else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE) > - return ENVL_NOWHERE; > - else > - return ENVL_UNKNOWN; > + switch (op) { > + case ENVOP_GET_CHAR: > + case ENVOP_INIT: > + case ENVOP_LOAD: > + if (prio >= ARRAY_SIZE(env_locations)) > + return ENVL_UNKNOWN; > + > + env_load_location = env_locations[prio]; > + return env_load_location; > + > + case ENVOP_SAVE: > + return env_load_location; > + } > + > + return ENVL_UNKNOWN; > } > >
On Thu, 1970-01-01 at 00:00 +0000, Simon Goldschmidt wrote: ..... > > Reviewed-by: Andre Przywara <andre.przywara@arm.com> > > Reviewed-by: Simon Glass <sjg@chromium.org> > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> > > --- > > env/env.c | 80 +++++++++++++++++++++++++++++++++++--------------------- > > 1 file changed, 50 insertions(+), 30 deletions(-) > > > > diff --git a/env/env.c b/env/env.c > > index 906f28ee50a1..1182fdb545db 100644 > > --- a/env/env.c > > +++ b/env/env.c > > @@ -26,6 +26,41 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) > > return NULL; > > } > > > > +static enum env_location env_locations[] = { Don't use static/global variables. They cause a lot of relocation work/size and is less flexible. There is no way to #define ENVL_EEPROM to a function when a variable. Jocke > > +#ifdef CONFIG_ENV_IS_IN_EEPROM > > + ENVL_EEPROM, > > +#endif > > +#ifdef CONFIG_ENV_IS_IN_FAT > > + ENVL_FAT, > > +#endif > > +#ifdef CONFIG_ENV_IS_IN_FLASH > > + ENVL_FLASH, > > +#endif > > +#ifdef CONFIG_ENV_IS_IN_MMC > > + ENVL_MMC, > > +#endif > > +#ifdef CONFIG_ENV_IS_IN_NAND > > + ENVL_NAND, > > +#endif > > +#ifdef CONFIG_ENV_IS_IN_NVRAM > > + ENVL_NVRAM, > > +#endif > > +#ifdef CONFIG_ENV_IS_IN_REMOTE > > + ENVL_REMOTE, > > +#endif > > +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH > > + ENVL_SPI_FLASH, > > +#endif > > +#ifdef CONFIG_ENV_IS_IN_UBI > > + ENVL_UBI, > > +#endif > > +#ifdef CONFIG_ENV_IS_NOWHERE > > + ENVL_NOWHERE, > > +#endif > > +}; > > + > > +static enum env_location env_load_location = ENVL_UNKNOWN; > > + > > /** > > * env_get_location() - Returns the best env location for a board > > * @op: operations performed on the environment > > @@ -45,36 +80,21 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) > > */ > > static enum env_location env_get_location(enum env_operation op, int prio) > > { > > - /* > > - * We support a single environment, so any environment asked > > - * with a priority that is not zero is out of our supported > > - * bounds. > > - */ > > - if (prio >= 1) > > - return ENVL_UNKNOWN; > > - > > - if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM) > > - return ENVL_EEPROM; > > - else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT) > > - return ENVL_FAT; > > - else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH) > > - return ENVL_FLASH; > > - else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC) > > - return ENVL_MMC; > > - else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND) > > - return ENVL_NAND; > > - else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM) > > - return ENVL_NVRAM; > > - else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE) > > - return ENVL_REMOTE; > > - else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH) > > - return ENVL_SPI_FLASH; > > - else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI) > > - return ENVL_UBI; > > - else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE) > > - return ENVL_NOWHERE; > > - else > > - return ENVL_UNKNOWN; > > + switch (op) { > > + case ENVOP_GET_CHAR: > > + case ENVOP_INIT: > > + case ENVOP_LOAD: > > + if (prio >= ARRAY_SIZE(env_locations)) > > + return ENVL_UNKNOWN; > > + > > + env_load_location = env_locations[prio]; > > + return env_load_location; > > + > > + case ENVOP_SAVE: > > + return env_load_location; > > + } > > + > > + return ENVL_UNKNOWN; > > } > > > > > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot
Hi, On Tue, Feb 06, 2018 at 08:20:49AM +0000, Joakim Tjernlund wrote: > On Thu, 1970-01-01 at 00:00 +0000, Simon Goldschmidt wrote: > > ..... > > > Reviewed-by: Andre Przywara <andre.przywara@arm.com> > > > Reviewed-by: Simon Glass <sjg@chromium.org> > > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> > > > --- > > > env/env.c | 80 +++++++++++++++++++++++++++++++++++--------------------- > > > 1 file changed, 50 insertions(+), 30 deletions(-) > > > > > > diff --git a/env/env.c b/env/env.c > > > index 906f28ee50a1..1182fdb545db 100644 > > > --- a/env/env.c > > > +++ b/env/env.c > > > @@ -26,6 +26,41 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) > > > return NULL; > > > } > > > > > > +static enum env_location env_locations[] = { > > Don't use static/global variables. They cause a lot of relocation work/size > and is less flexible. There is no way to #define ENVL_EEPROM to a function > when a variable. Is that last sentence truncated? Can you elaborate a bit more on what is the source of the relocation issues you're mentionning? Is that because of the section it ends up in? Thanks! Maxime -- Maxime Ripard, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering http://bootlin.com
On Tue, Feb 06, 2018 at 09:09:07AM +0100, Simon Goldschmidt wrote: > On 23.01.2018 21:16, Maxime Ripard wrote: > > Now that we have everything in place to support multiple environment, let's > > make sure the current code can use it. > > I get more build errors testing this feature: there's a global variable > 'env_ptr' declared in flash, nand, nvram and remote env drivers (declared as > extern in envrionment.h). From reading the code, it seems like these could > just be changed to static, since 'env_ptr' is not used outside these > drivers? Given Joakim's comment, I guess we should keep them !static, rename them to $env_env_ptr, and remove the definition in the include/environment that doesn't seem used anywhere. Maxime -- Maxime Ripard, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering http://bootlin.com
On 07.02.2018 09:19, Maxime Ripard wrote: > On Tue, Feb 06, 2018 at 09:09:07AM +0100, Simon Goldschmidt wrote: >> On 23.01.2018 21:16, Maxime Ripard wrote: >>> Now that we have everything in place to support multiple environment, let's >>> make sure the current code can use it. >> I get more build errors testing this feature: there's a global variable >> 'env_ptr' declared in flash, nand, nvram and remote env drivers (declared as >> extern in envrionment.h). From reading the code, it seems like these could >> just be changed to static, since 'env_ptr' is not used outside these >> drivers? > Given Joakim's comment, I guess we should keep them !static, rename > them to $env_env_ptr, and remove the definition in the > include/environment that doesn't seem used anywhere. That's OK for me, I just wanted to point out the build error. However, I do think that having unnecessary non-static global variables is not really good coding style as you risk name clashes. I'd really be interested in a reason for this. Simon
On 06.02.2018 09:20, Joakim Tjernlund wrote: > On Thu, 1970-01-01 at 00:00 +0000, Simon Goldschmidt wrote: > > ..... >>> Reviewed-by: Andre Przywara <andre.przywara@arm.com> >>> Reviewed-by: Simon Glass <sjg@chromium.org> >>> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> >>> --- >>> env/env.c | 80 +++++++++++++++++++++++++++++++++++--------------------- >>> 1 file changed, 50 insertions(+), 30 deletions(-) >>> >>> diff --git a/env/env.c b/env/env.c >>> index 906f28ee50a1..1182fdb545db 100644 >>> --- a/env/env.c >>> +++ b/env/env.c >>> @@ -26,6 +26,41 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) >>> return NULL; >>> } >>> >>> +static enum env_location env_locations[] = { > Don't use static/global variables. They cause a lot of relocation work/size > and is less flexible. In this specific case, I think this array should be const anyway, would that prevent the relocation problems you see? > There is no way to #define ENVL_EEPROM to a function > when a variable. ENVL_EEPROM is an enum value, why would you define it to a function? Simon > > Jocke > >>> +#ifdef CONFIG_ENV_IS_IN_EEPROM >>> + ENVL_EEPROM, >>> +#endif >>> +#ifdef CONFIG_ENV_IS_IN_FAT >>> + ENVL_FAT, >>> +#endif >>> +#ifdef CONFIG_ENV_IS_IN_FLASH >>> + ENVL_FLASH, >>> +#endif >>> +#ifdef CONFIG_ENV_IS_IN_MMC >>> + ENVL_MMC, >>> +#endif >>> +#ifdef CONFIG_ENV_IS_IN_NAND >>> + ENVL_NAND, >>> +#endif >>> +#ifdef CONFIG_ENV_IS_IN_NVRAM >>> + ENVL_NVRAM, >>> +#endif >>> +#ifdef CONFIG_ENV_IS_IN_REMOTE >>> + ENVL_REMOTE, >>> +#endif >>> +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH >>> + ENVL_SPI_FLASH, >>> +#endif >>> +#ifdef CONFIG_ENV_IS_IN_UBI >>> + ENVL_UBI, >>> +#endif >>> +#ifdef CONFIG_ENV_IS_NOWHERE >>> + ENVL_NOWHERE, >>> +#endif >>> +}; >>> + >>> +static enum env_location env_load_location = ENVL_UNKNOWN; >>> + >>> /** >>> * env_get_location() - Returns the best env location for a board >>> * @op: operations performed on the environment >>> @@ -45,36 +80,21 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) >>> */ >>> static enum env_location env_get_location(enum env_operation op, int prio) >>> { >>> - /* >>> - * We support a single environment, so any environment asked >>> - * with a priority that is not zero is out of our supported >>> - * bounds. >>> - */ >>> - if (prio >= 1) >>> - return ENVL_UNKNOWN; >>> - >>> - if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM) >>> - return ENVL_EEPROM; >>> - else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT) >>> - return ENVL_FAT; >>> - else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH) >>> - return ENVL_FLASH; >>> - else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC) >>> - return ENVL_MMC; >>> - else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND) >>> - return ENVL_NAND; >>> - else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM) >>> - return ENVL_NVRAM; >>> - else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE) >>> - return ENVL_REMOTE; >>> - else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH) >>> - return ENVL_SPI_FLASH; >>> - else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI) >>> - return ENVL_UBI; >>> - else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE) >>> - return ENVL_NOWHERE; >>> - else >>> - return ENVL_UNKNOWN; >>> + switch (op) { >>> + case ENVOP_GET_CHAR: >>> + case ENVOP_INIT: >>> + case ENVOP_LOAD: >>> + if (prio >= ARRAY_SIZE(env_locations)) >>> + return ENVL_UNKNOWN; >>> + >>> + env_load_location = env_locations[prio]; >>> + return env_load_location; >>> + >>> + case ENVOP_SAVE: >>> + return env_load_location; >>> + } >>> + >>> + return ENVL_UNKNOWN; >>> } >>> >>> >> _______________________________________________ >> U-Boot mailing list >> U-Boot@lists.denx.de >> https://lists.denx.de/listinfo/u-boot
On Thu, 1970-01-01 at 00:00 +0000, Maxime Ripard wrote: > Hi, > > On Tue, Feb 06, 2018 at 08:20:49AM +0000, Joakim Tjernlund wrote: > > On Thu, 1970-01-01 at 00:00 +0000, Simon Goldschmidt wrote: > > > > ..... > > > > Reviewed-by: Andre Przywara <andre.przywara@arm.com> > > > > Reviewed-by: Simon Glass <sjg@chromium.org> > > > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> > > > > --- > > > > env/env.c | 80 +++++++++++++++++++++++++++++++++++--------------------- > > > > 1 file changed, 50 insertions(+), 30 deletions(-) > > > > > > > > diff --git a/env/env.c b/env/env.c > > > > index 906f28ee50a1..1182fdb545db 100644 > > > > --- a/env/env.c > > > > +++ b/env/env.c > > > > @@ -26,6 +26,41 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) > > > > return NULL; > > > > } > > > > > > > > +static enum env_location env_locations[] = { > > > > Don't use static/global variables. They cause a lot of relocation work/size > > and is less flexible. There is no way to #define ENVL_EEPROM to a function > > when a variable. > > Is that last sentence truncated? > > Can you elaborate a bit more on what is the source of the relocation > issues you're mentionning? Is that because of the section it ends up > in? Mainly that its adds relocation entries that take up space, more space than doing a simple assignment directly in code.
Hi, On Tue, Jan 30, 2018 at 11:02:49PM +0000, York Sun wrote: > On 01/30/2018 12:16 PM, York Sun wrote: > > On 01/30/2018 11:40 AM, York Sun wrote: > >> On 01/30/2018 12:19 AM, Simon Goldschmidt wrote: > >>> On 23.01.2018 21:16, Maxime Ripard wrote: > >>>> Now that we have everything in place to support multiple environment, let's > >>>> make sure the current code can use it. > >>>> > >>>> The priority used between the various environment is the same one that was > >>>> used in the code previously. > >>>> > >>>> At read / init times, the highest priority environment is going to be > >>>> detected, > >>> > >>> Does priority handling really work here? Most env drivers seem to ignore > >>> the return value of env_import and may thus return success although > >>> importing the environment failed (only reading the data from the device > >>> succeeded). > >>> > >>> This is from reading the code, I haven't had a chance to test this, yet. > >> > >> It is broken on my LS1043ARDB with simply NOR flash. I am trying to > >> determine what went wrong. > >> > > > > I found the problem. The variable "env_load_location" is static. It is > > probably not write-able during booting from flash. It is expected to be > > set during ENVOP_INIT. But if I print this variable, it has > > ENVL_UNKNOWN. I can make it work by moving env_load_location to global > > data structure. That would work for me. > > That being said, this addition of multiple environments really slows > > down the booting process for me. I see every time env_get_char() is > > called, env_driver_lookup() runs. A simple call of env_get_f() gets > > slowed down dramatically. I didn't find out where the most time is spent > > yet. > > > > Does anyone else experience this unbearable slowness? > > > > I found the problem. In patch #3 in this series, the default get_char() > was dropped so there is no driver for a plain NOR flash. A quick (and > maybe dirty) fix is this > > > diff --git a/env/env.c b/env/env.c > index edfb575..210bae2 100644 > --- a/env/env.c > +++ b/env/env.c > @@ -159,7 +159,7 @@ int env_get_char(int index) > int ret; > > if (!drv->get_char) > - continue; > + return *(uchar *)(gd->env_addr + index); > > if (!env_has_inited(drv->location)) > continue; And this too. > With this temporary fix, my flash chip works again and I can boot all > the way up in a timely manner. I still don't like to call > env_driver_lookup() thousands of times to get a simple env variable. > > Can Maxime post a quick post soon? Given that you already made all the debugging, and the patches, and I have no way to test, I guess it would make more sense if you did it :) Maxime -- Maxime Ripard, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering http://bootlin.com
On Thu, 1970-01-01 at 00:00 +0000, Simon Goldschmidt wrote: > CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe. > > > On 06.02.2018 09:20, Joakim Tjernlund wrote: > > On Thu, 1970-01-01 at 00:00 +0000, Simon Goldschmidt wrote: > > > > ..... > > > > Reviewed-by: Andre Przywara <andre.przywara@arm.com> > > > > Reviewed-by: Simon Glass <sjg@chromium.org> > > > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> > > > > --- > > > > env/env.c | 80 +++++++++++++++++++++++++++++++++++--------------------- > > > > 1 file changed, 50 insertions(+), 30 deletions(-) > > > > > > > > diff --git a/env/env.c b/env/env.c > > > > index 906f28ee50a1..1182fdb545db 100644 > > > > --- a/env/env.c > > > > +++ b/env/env.c > > > > @@ -26,6 +26,41 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) > > > > return NULL; > > > > } > > > > > > > > +static enum env_location env_locations[] = { > > > > Don't use static/global variables. They cause a lot of relocation work/size > > and is less flexible. > > In this specific case, I think this array should be const anyway, would > that prevent the relocation problems you see? > > > There is no way to #define ENVL_EEPROM to a function > > when a variable. > > ENVL_EEPROM is an enum value, why would you define it to a function? I got boards that very similar but differ in where/how env. is stored, like different flash so I need to be able to select at runtime how get my env., I haven't looked if this particular area is affected but ideally I would like if all env. related "constants" could be impl. with a function instead. Also, using static/global vars takes more space than simple assignments in code, ideally everything needed early (before reloc/ in SPL) should avoid relocations to save space. Jocke
On Wed, Feb 07, 2018 at 08:45:46AM +0000, Joakim Tjernlund wrote: > On Thu, 1970-01-01 at 00:00 +0000, Simon Goldschmidt wrote: > > CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe. > > > > > > On 06.02.2018 09:20, Joakim Tjernlund wrote: > > > On Thu, 1970-01-01 at 00:00 +0000, Simon Goldschmidt wrote: > > > > > > ..... > > > > > Reviewed-by: Andre Przywara <andre.przywara@arm.com> > > > > > Reviewed-by: Simon Glass <sjg@chromium.org> > > > > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> > > > > > --- > > > > > env/env.c | 80 +++++++++++++++++++++++++++++++++++--------------------- > > > > > 1 file changed, 50 insertions(+), 30 deletions(-) > > > > > > > > > > diff --git a/env/env.c b/env/env.c > > > > > index 906f28ee50a1..1182fdb545db 100644 > > > > > --- a/env/env.c > > > > > +++ b/env/env.c > > > > > @@ -26,6 +26,41 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) > > > > > return NULL; > > > > > } > > > > > > > > > > +static enum env_location env_locations[] = { > > > > > > Don't use static/global variables. They cause a lot of relocation work/size > > > and is less flexible. > > > > In this specific case, I think this array should be const anyway, would > > that prevent the relocation problems you see? > > > > > > There is no way to #define ENVL_EEPROM to a function > > > when a variable. > > > > ENVL_EEPROM is an enum value, why would you define it to a function? > > I got boards that very similar but differ in where/how env. is > stored, like different flash so I need to be able to select at > runtime how get my env., I haven't looked if this particular area is > affected but ideally I would like if all env. related "constants" > could be impl. with a function instead. It's exactly the point of this entire serie though, and why we merged it. You just need to override env_get_location in your board, and return the preferred location. Maxime -- Maxime Ripard, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering http://bootlin.com
1;5002;0c On Wed, Feb 07, 2018 at 09:25:55AM +0100, Simon Goldschmidt wrote: > On 07.02.2018 09:19, Maxime Ripard wrote: > > On Tue, Feb 06, 2018 at 09:09:07AM +0100, Simon Goldschmidt wrote: > > > On 23.01.2018 21:16, Maxime Ripard wrote: > > > > Now that we have everything in place to support multiple environment, let's > > > > make sure the current code can use it. > > > I get more build errors testing this feature: there's a global variable > > > 'env_ptr' declared in flash, nand, nvram and remote env drivers (declared as > > > extern in envrionment.h). From reading the code, it seems like these could > > > just be changed to static, since 'env_ptr' is not used outside these > > > drivers? > > Given Joakim's comment, I guess we should keep them !static, rename > > them to $env_env_ptr, and remove the definition in the > > include/environment that doesn't seem used anywhere. > > That's OK for me, I just wanted to point out the build error. > > However, I do think that having unnecessary non-static global variables is > not really good coding style as you risk name clashes. I'd really be > interested in a reason for this. If the relocation works with a static variable, I'm all for it. Maxime -- Maxime Ripard, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering http://bootlin.com
On 02/07/2018 12:43 AM, Maxime Ripard wrote: > Hi, > > On Tue, Jan 30, 2018 at 11:02:49PM +0000, York Sun wrote: >> On 01/30/2018 12:16 PM, York Sun wrote: >>> On 01/30/2018 11:40 AM, York Sun wrote: >>>> On 01/30/2018 12:19 AM, Simon Goldschmidt wrote: >>>>> On 23.01.2018 21:16, Maxime Ripard wrote: >>>>>> Now that we have everything in place to support multiple environment, let's >>>>>> make sure the current code can use it. >>>>>> >>>>>> The priority used between the various environment is the same one that was >>>>>> used in the code previously. >>>>>> >>>>>> At read / init times, the highest priority environment is going to be >>>>>> detected, >>>>> >>>>> Does priority handling really work here? Most env drivers seem to ignore >>>>> the return value of env_import and may thus return success although >>>>> importing the environment failed (only reading the data from the device >>>>> succeeded). >>>>> >>>>> This is from reading the code, I haven't had a chance to test this, yet. >>>> >>>> It is broken on my LS1043ARDB with simply NOR flash. I am trying to >>>> determine what went wrong. >>>> >>> >>> I found the problem. The variable "env_load_location" is static. It is >>> probably not write-able during booting from flash. It is expected to be >>> set during ENVOP_INIT. But if I print this variable, it has >>> ENVL_UNKNOWN. I can make it work by moving env_load_location to global >>> data structure. > > That would work for me. > >>> That being said, this addition of multiple environments really slows >>> down the booting process for me. I see every time env_get_char() is >>> called, env_driver_lookup() runs. A simple call of env_get_f() gets >>> slowed down dramatically. I didn't find out where the most time is spent >>> yet. >>> >>> Does anyone else experience this unbearable slowness? >>> >> >> I found the problem. In patch #3 in this series, the default get_char() >> was dropped so there is no driver for a plain NOR flash. A quick (and >> maybe dirty) fix is this >> >> >> diff --git a/env/env.c b/env/env.c >> index edfb575..210bae2 100644 >> --- a/env/env.c >> +++ b/env/env.c >> @@ -159,7 +159,7 @@ int env_get_char(int index) >> int ret; >> >> if (!drv->get_char) >> - continue; >> + return *(uchar *)(gd->env_addr + index); >> >> if (!env_has_inited(drv->location)) >> continue; > > And this too. If you agree with this fix (actually revert your change earlier), I can send out a patch. > >> With this temporary fix, my flash chip works again and I can boot all >> the way up in a timely manner. I still don't like to call >> env_driver_lookup() thousands of times to get a simple env variable. >> >> Can Maxime post a quick post soon? > > Given that you already made all the debugging, and the patches, and I > have no way to test, I guess it would make more sense if you did it :) Yes, I have tested on my boards. I will send out this patch. York
diff --git a/env/env.c b/env/env.c index 906f28ee50a1..1182fdb545db 100644 --- a/env/env.c +++ b/env/env.c @@ -26,6 +26,41 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) return NULL; } +static enum env_location env_locations[] = { +#ifdef CONFIG_ENV_IS_IN_EEPROM + ENVL_EEPROM, +#endif +#ifdef CONFIG_ENV_IS_IN_FAT + ENVL_FAT, +#endif +#ifdef CONFIG_ENV_IS_IN_FLASH + ENVL_FLASH, +#endif +#ifdef CONFIG_ENV_IS_IN_MMC + ENVL_MMC, +#endif +#ifdef CONFIG_ENV_IS_IN_NAND + ENVL_NAND, +#endif +#ifdef CONFIG_ENV_IS_IN_NVRAM + ENVL_NVRAM, +#endif +#ifdef CONFIG_ENV_IS_IN_REMOTE + ENVL_REMOTE, +#endif +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH + ENVL_SPI_FLASH, +#endif +#ifdef CONFIG_ENV_IS_IN_UBI + ENVL_UBI, +#endif +#ifdef CONFIG_ENV_IS_NOWHERE + ENVL_NOWHERE, +#endif +}; + +static enum env_location env_load_location = ENVL_UNKNOWN; + /** * env_get_location() - Returns the best env location for a board * @op: operations performed on the environment @@ -45,36 +80,21 @@ static struct env_driver *_env_driver_lookup(enum env_location loc) */ static enum env_location env_get_location(enum env_operation op, int prio) { - /* - * We support a single environment, so any environment asked - * with a priority that is not zero is out of our supported - * bounds. - */ - if (prio >= 1) - return ENVL_UNKNOWN; - - if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM) - return ENVL_EEPROM; - else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT) - return ENVL_FAT; - else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH) - return ENVL_FLASH; - else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC) - return ENVL_MMC; - else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND) - return ENVL_NAND; - else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM) - return ENVL_NVRAM; - else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE) - return ENVL_REMOTE; - else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH) - return ENVL_SPI_FLASH; - else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI) - return ENVL_UBI; - else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE) - return ENVL_NOWHERE; - else - return ENVL_UNKNOWN; + switch (op) { + case ENVOP_GET_CHAR: + case ENVOP_INIT: + case ENVOP_LOAD: + if (prio >= ARRAY_SIZE(env_locations)) + return ENVL_UNKNOWN; + + env_load_location = env_locations[prio]; + return env_load_location; + + case ENVOP_SAVE: + return env_load_location; + } + + return ENVL_UNKNOWN; }