Message ID | 844212451999302a41d87526d6616b1af7c781d1.1516723179.git-series.maxime.ripard@free-electrons.com |
---|---|
State | Accepted |
Delegated to: | Tom Rini |
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!
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
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
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
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
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
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; }