From patchwork Thu Feb 27 13:56:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rasmus Villemoes X-Patchwork-Id: 236949 List-Id: U-Boot discussion From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Thu, 27 Feb 2020 13:56:10 +0000 Subject: [PATCH 1/4] env: remove callback.o for an SPL build In-Reply-To: <20200227135600.28853-1-rasmus.villemoes@prevas.dk> References: <20200227135600.28853-1-rasmus.villemoes@prevas.dk> Message-ID: <20200227135600.28853-2-rasmus.villemoes@prevas.dk> env.h says this about about callback declarations (U_BOOT_ENV_CALLBACK): * For SPL these are silently dropped to reduce code size, since environment * callbacks are not supported with SPL. So env_callback_init() does a lot of work to not find anything in the guaranteed empty env_clbk list. Drop callback.o entirely from the link and stub out the only public function defined in callback.o. This cuts about 600 bytes from the SPL on my ppc build. Signed-off-by: Rasmus Villemoes Reviewed-by: Simon Glass --- env/Makefile | 2 +- include/env_callback.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/env/Makefile b/env/Makefile index e2a165b8f1..c4ad654328 100644 --- a/env/Makefile +++ b/env/Makefile @@ -7,9 +7,9 @@ obj-$(CONFIG_$(SPL_TPL_)ENV_SUPPORT) += common.o obj-$(CONFIG_$(SPL_TPL_)ENV_SUPPORT) += env.o obj-$(CONFIG_$(SPL_TPL_)ENV_SUPPORT) += attr.o obj-$(CONFIG_$(SPL_TPL_)ENV_SUPPORT) += flags.o -obj-$(CONFIG_$(SPL_TPL_)ENV_SUPPORT) += callback.o ifndef CONFIG_SPL_BUILD +obj-y += callback.o obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o extra-$(CONFIG_ENV_IS_EMBEDDED) += embedded.o obj-$(CONFIG_ENV_IS_IN_EEPROM) += embedded.o diff --git a/include/env_callback.h b/include/env_callback.h index 74da20eec3..05e9516a0f 100644 --- a/include/env_callback.h +++ b/include/env_callback.h @@ -72,6 +72,12 @@ "serial#:serialno," \ CONFIG_ENV_CALLBACK_LIST_STATIC +#ifndef CONFIG_SPL_BUILD void env_callback_init(struct env_entry *var_entry); +#else +static inline void env_callback_init(struct env_entry *var_entry) +{ +} +#endif #endif /* __ENV_CALLBACK_H__ */ From patchwork Thu Feb 27 13:56:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rasmus Villemoes X-Patchwork-Id: 236950 List-Id: U-Boot discussion From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Thu, 27 Feb 2020 13:56:11 +0000 Subject: [PATCH 2/4] lib/hashtable.c: create helper for calling env_entry::callback In-Reply-To: <20200227135600.28853-1-rasmus.villemoes@prevas.dk> References: <20200227135600.28853-1-rasmus.villemoes@prevas.dk> Message-ID: <20200227135600.28853-3-rasmus.villemoes@prevas.dk> This is preparation for compiling out the "call the callback" code and associated error handling for SPL, where ->callback is always NULL. Signed-off-by: Rasmus Villemoes Reviewed-by: Simon Glass --- lib/hashtable.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/hashtable.c b/lib/hashtable.c index 907e8a642f..574ec6af86 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -222,6 +222,15 @@ int hmatch_r(const char *match, int last_idx, struct env_entry **retval, return 0; } +static int +do_callback(const struct env_entry *e, const char *name, const char *value, + enum env_op op, int flags) +{ + if (e->callback) + return e->callback(name, value, op, flags); + return 0; +} + /* * Compare an existing entry with the desired key, and overwrite if the action * is ENV_ENTER. This is simply a helper function for hsearch_r(). @@ -247,9 +256,8 @@ static inline int _compare_and_overwrite_entry(struct env_entry item, } /* If there is a callback, call it */ - if (htab->table[idx].entry.callback && - htab->table[idx].entry.callback(item.key, - item.data, env_op_overwrite, flag)) { + if (do_callback(&htab->table[idx].entry, item.key, + item.data, env_op_overwrite, flag)) { debug("callback() rejected setting variable " "%s, skipping it!\n", item.key); __set_errno(EINVAL); @@ -402,9 +410,8 @@ int hsearch_r(struct env_entry item, enum env_action action, } /* If there is a callback, call it */ - if (htab->table[idx].entry.callback && - htab->table[idx].entry.callback(item.key, item.data, - env_op_create, flag)) { + if (do_callback(&htab->table[idx].entry, item.key, item.data, + env_op_create, flag)) { debug("callback() rejected setting variable " "%s, skipping it!\n", item.key); _hdelete(item.key, htab, &htab->table[idx].entry, idx); @@ -473,8 +480,8 @@ int hdelete_r(const char *key, struct hsearch_data *htab, int flag) } /* If there is a callback, call it */ - if (htab->table[idx].entry.callback && - htab->table[idx].entry.callback(key, NULL, env_op_delete, flag)) { + if (do_callback(&htab->table[idx].entry, key, NULL, + env_op_delete, flag)) { debug("callback() rejected deleting variable " "%s, skipping it!\n", key); __set_errno(EINVAL); From patchwork Thu Feb 27 13:56:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rasmus Villemoes X-Patchwork-Id: 236951 List-Id: U-Boot discussion From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Thu, 27 Feb 2020 13:56:11 +0000 Subject: [PATCH 3/4] lib/hashtable.c: don't test ->callback in SPL In-Reply-To: <20200227135600.28853-1-rasmus.villemoes@prevas.dk> References: <20200227135600.28853-1-rasmus.villemoes@prevas.dk> Message-ID: <20200227135600.28853-4-rasmus.villemoes@prevas.dk> In SPL, environment callbacks are not supported, so e->callback is always NULL. Removing this makes the SPL a little smaller (about 400 bytes in my ppc build) with no functional change. Signed-off-by: Rasmus Villemoes Reviewed-by: Simon Glass --- lib/hashtable.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/hashtable.c b/lib/hashtable.c index 574ec6af86..c4e1e2bd45 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -226,8 +226,10 @@ static int do_callback(const struct env_entry *e, const char *name, const char *value, enum env_op op, int flags) { +#ifndef CONFIG_SPL_BUILD if (e->callback) return e->callback(name, value, op, flags); +#endif return 0; } From patchwork Thu Feb 27 13:56:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rasmus Villemoes X-Patchwork-Id: 236952 List-Id: U-Boot discussion From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Thu, 27 Feb 2020 13:56:12 +0000 Subject: [PATCH 4/4] make env_entry::callback conditional on !CONFIG_SPL_BUILD In-Reply-To: <20200227135600.28853-1-rasmus.villemoes@prevas.dk> References: <20200227135600.28853-1-rasmus.villemoes@prevas.dk> Message-ID: <20200227135600.28853-5-rasmus.villemoes@prevas.dk> The callback member of struct env_entry is always NULL for an SPL build. Removing it thus saves a bit of run-time memory in the SPL (when CONFIG_SPL_ENV_SUPPORT=y) since struct env_entry is embedded in struct env_entry_node - i.e. about 2KB for the normal case of 512+change hash table entries. Two small fixups are needed for this, all other references to the callback member are already under !CONFIG_SPL_BUILD: Don't initialize .callback in set_flags() - hsearch_r doesn't use that value anyway. And make env_callback_init() initialize ->callback to NULL for a new entry instead of relying on an unused or deleted entry having NULL in ->callback. Signed-off-by: Rasmus Villemoes Reviewed-by: Simon Glass --- env/callback.c | 2 ++ env/flags.c | 1 - include/search.h | 2 ++ lib/hashtable.c | 1 - 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/env/callback.c b/env/callback.c index f0904cfdc5..4054b9ef58 100644 --- a/env/callback.c +++ b/env/callback.c @@ -55,6 +55,8 @@ void env_callback_init(struct env_entry *var_entry) first_call = 0; } + var_entry->callback = NULL; + /* look in the ".callbacks" var for a reference to this variable */ if (callback_list != NULL) ret = env_attr_lookup(callback_list, var_name, callback_name); diff --git a/env/flags.c b/env/flags.c index 418d6cc742..b88fe7ba9c 100644 --- a/env/flags.c +++ b/env/flags.c @@ -457,7 +457,6 @@ static int set_flags(const char *name, const char *value, void *priv) e.key = name; e.data = NULL; - e.callback = NULL; hsearch_r(e, ENV_FIND, &ep, &env_htab, 0); /* does the env variable actually exist? */ diff --git a/include/search.h b/include/search.h index 0469a852e0..8f87dc72ce 100644 --- a/include/search.h +++ b/include/search.h @@ -29,8 +29,10 @@ enum env_action { struct env_entry { const char *key; char *data; +#ifndef CONFIG_SPL_BUILD int (*callback)(const char *name, const char *value, enum env_op op, int flags); +#endif int flags; }; diff --git a/lib/hashtable.c b/lib/hashtable.c index c4e1e2bd45..f82f2463cf 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -450,7 +450,6 @@ static void _hdelete(const char *key, struct hsearch_data *htab, debug("hdelete: DELETING key \"%s\"\n", key); free((void *)ep->key); free(ep->data); - ep->callback = NULL; ep->flags = 0; htab->table[idx].used = USED_DELETED;