[Skiboot] [PATCH] core/device: Remove redundant malloc
Oliver
oohall at gmail.com
Tue Feb 19 16:42:58 AEDT 2019
On Tue, Feb 19, 2019 at 4:28 PM Jordan Niethe <jniethe5 at gmail.com> wrote:
>
> From: jordan <jpn at pasglop.ozlabs.ibm.com>
>
> Currently dt_new_addr() / dt_new_2addr() malloc a scatch buffer for the
> node name. This is then duplicated in new_node(). This makes the initial
> allocation redundant. To address this the allocation was removed from
> dt_new_addr() / dt_new_2addr() and new_node() was changed to a varadic
> function to accomodate the different name format.
>
> Ideally vsnprintf() would be used to calculate the length of the
> resulting name so a buffer could be dynamically allocated.
> This would then be filled with another call to vsnprintf(). However the
> implemenation of vsnprintf() does not behave correctly when called with
> a size of 0 so this is not possible.
> Instead a statically allocated buffer is used. This assumes a maximum
> length for a name.
> The optimization for ro memory names in take_name() is no longer
> peformed. This is because the arguements to new_node() are intended for
> vsnprintf() and can not be readly checked using is_rodata().
> This does not significantly impact memory usage.
So on P9 systems we have a lot of cores and each core has a seperate
DT node which is populated with static strings. It might be worth
looking into how this affects memory usage there.
Also, we could check if there is a format string indicator (the %) in
the name and still do the rodata trick if we can be sure that it's a
static string.
>
> Signed-off-by: Jordan Niethe <jniethe5 at gmail.com>
> ---
> core/device.c | 41 ++++++++++++++++++++---------------------
> 1 file changed, 20 insertions(+), 21 deletions(-)
>
> diff --git a/core/device.c b/core/device.c
> index 6364a60e93ec..7f8bb929a184 100644
> --- a/core/device.c
> +++ b/core/device.c
> @@ -44,15 +44,31 @@ static void free_name(const char *name)
> free((char *)name);
> }
>
> -static struct dt_node *new_node(const char *name)
> +static struct dt_node *new_node(const char *fmt, ...)
> {
> + const size_t max_name = 256;
you can drop this and use sizeof(name) as the param for vsnprintf()
> + char name[max_name];
bring this down one line for REVERSE-CHRISTMAS-TREE variable declarations
> struct dt_node *node = malloc(sizeof *node);
> + size_t len = 0;
> + va_list args;
> +
> if (!node) {
> prerror("Failed to allocate node\n");
> abort();
> }
>
> - node->name = take_name(name);
> + va_start(args, fmt);
> + len = vsnprintf(name, max_name, fmt, args);
> + va_end(args);
> +
> + len++;
is len being used at all here?
> +
> + node->name = strdup(name);
> + if (!node->name) {
> + prerror("Failed to allocate copy of name");
> + abort();
> + }
> +
> node->parent = NULL;
> list_head_init(&node->properties);
> list_head_init(&node->children);
> @@ -208,18 +224,10 @@ struct dt_node *dt_find_by_name_addr(struct dt_node *parent, const char *name,
> struct dt_node *dt_new_addr(struct dt_node *parent, const char *name,
> uint64_t addr)
> {
> - char *lname;
> struct dt_node *new;
> - size_t len;
>
> assert(parent);
> - len = strlen(name) + STR_MAX_CHARS(addr) + 2;
> - lname = malloc(len);
> - if (!lname)
> - return NULL;
> - snprintf(lname, len, "%s@%llx", name, (long long)addr);
> - new = new_node(lname);
> - free(lname);
> + new = new_node("%s@%llx", name, (long long)addr);
> if (!dt_attach_root(parent, new)) {
> dt_destroy(new);
> return NULL;
> @@ -230,19 +238,10 @@ struct dt_node *dt_new_addr(struct dt_node *parent, const char *name,
> struct dt_node *dt_new_2addr(struct dt_node *parent, const char *name,
> uint64_t addr0, uint64_t addr1)
> {
> - char *lname;
> struct dt_node *new;
> - size_t len;
> assert(parent);
>
> - len = strlen(name) + 2*STR_MAX_CHARS(addr0) + 3;
> - lname = malloc(len);
> - if (!lname)
> - return NULL;
> - snprintf(lname, len, "%s@%llx,%llx",
> - name, (long long)addr0, (long long)addr1);
> - new = new_node(lname);
> - free(lname);
> + new = new_node("%s@%llx,%llx", name, (long long)addr0, (long long)addr1);
> if (!dt_attach_root(parent, new)) {
> dt_destroy(new);
> return NULL;
> --
> 2.19.1
>
More information about the Skiboot
mailing list