From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Waiman Long <Waiman.Long@hp.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
Paul Mackerras <paulus@samba.org>, Ingo Molnar <mingo@redhat.com>,
linux-kernel@vger.kernel.org,
Scott J Norton <scott.norton@hp.com>,
Don Zickus <dzickus@redhat.com>, Jiri Olsa <jolsa@kernel.org>,
Adrian Hunter <adrian.hunter@intel.com>
Subject: Re: [PATCH v2] perf mem: improves DSO long names search speed with RB tree
Date: Wed, 17 Sep 2014 11:51:02 -0300 [thread overview]
Message-ID: <20140917145102.GA2770@kernel.org> (raw)
In-Reply-To: <1410894499-27609-2-git-send-email-Waiman.Long@hp.com>
Em Tue, Sep 16, 2014 at 03:08:19PM -0400, Waiman Long escreveu:
> +++ b/tools/perf/util/dso.c
> @@ -611,17 +611,93 @@ struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
> return dso;
> }
>
> +/*
> + * RB root of DSOs sorted by the long name
> + */
> +static struct rb_root dso__longname_root = { NULL };
Use RB_ROOT, like in:
[acme@zoo linux]$ grep -w rb_root mm/vmalloc.c
static struct rb_root vmap_area_root = RB_ROOT;
[acme@zoo linux]$
But then can't this be made non-static, i.e. at the 'struct machine'
level? I.e. it is more likely that DSOs with the same long name are
really the same thing on a single 'struct machine', not accross multiple
ones or even multiple sessions (i.e. across multiple 'struct machines').
IIRC Adrian also pointed this out.
- Arnaldo
> +/*
> + * Find a matching entry and/or link current entry to RB tree.
> + * Either one of the dso or name parameter must be non-NULL or the
> + * function will not work.
> + */
> +static struct dso *
> +dso__findlink_by_longname(struct dso *dso, const char *name)
> +{
> + struct rb_node **p = &dso__longname_root.rb_node;
> + struct rb_node *parent = NULL;
> + int warned = false;
> +
> + if (!name)
> + name = dso->long_name;
> + /*
> + * Find node with the matching name
> + */
> + while (*p) {
> + struct dso *this = rb_entry(*p, struct dso, longname_rb_node);
> + long rc = (long)strcmp(name, this->long_name);
> +
> + parent = *p;
> + if (rc == 0) {
> + /*
> + * In case the new DSO is a duplicate of an existing
> + * one, print an one-time warning & sort the entry
> + * by its DSO address.
> + */
> + if (!dso || (dso == this))
> + return this; /* Find matching dso */
> + if (!warned) {
> + pr_warning("Duplicated dso long name: %s\n",
> + name);
> + warned = true;
> + }
> + rc = (long)dso - (long)this;
> + }
> + if (rc < 0)
> + p = &parent->rb_left;
> + else
> + p = &parent->rb_right;
> + }
> + if (dso) {
> + /* Add new node and rebalance tree */
> + rb_link_node(&dso->longname_rb_node, parent, p);
> + rb_insert_color(&dso->longname_rb_node, &dso__longname_root);
> + }
> + return NULL;
> +}
> +
> +static inline struct dso *
> +dso__find_by_longname(const char *name)
> +{
> + return dso__findlink_by_longname(NULL, name);
> +}
> +
> +/*
> + * Unlink the longname-sorted RB tree node
> + */
> +static inline void dso__unlink_longname_node(struct dso *dso)
> +{
> + rb_erase(&dso->longname_rb_node, &dso__longname_root);
> +}
> +
> void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
> {
> if (name == NULL)
> return;
>
> + if (dso->long_name) {
> + if (!strcmp(dso->long_name, name))
> + return;
> + dso__unlink_longname_node(dso);
> + }
> +
> if (dso->long_name_allocated)
> free((char *)dso->long_name);
>
> dso->long_name = name;
> dso->long_name_len = strlen(name);
> dso->long_name_allocated = name_allocated;
> + (void)dso__findlink_by_longname(dso, name);
> }
>
> void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
> @@ -695,6 +771,8 @@ struct dso *dso__new(const char *name)
> if (dso != NULL) {
> int i;
> strcpy(dso->name, name);
> + RB_CLEAR_NODE(&dso->longname_rb_node);
> + dso->long_name = NULL;
> dso__set_long_name(dso, dso->name, false);
> dso__set_short_name(dso, dso->name, false);
> for (i = 0; i < MAP__NR_TYPES; ++i)
> @@ -733,6 +811,10 @@ void dso__delete(struct dso *dso)
> zfree((char **)&dso->long_name);
> dso->long_name_allocated = false;
> }
> + if (dso->long_name) {
> + dso__unlink_longname_node(dso);
> + dso->long_name = NULL;
> + }
>
> dso__data_close(dso);
> dso_cache__free(&dso->data.cache);
> @@ -822,10 +904,7 @@ struct dso *dsos__find(const struct list_head *head, const char *name, bool cmp_
> return pos;
> return NULL;
> }
> - list_for_each_entry(pos, head, node)
> - if (strcmp(pos->long_name, name) == 0)
> - return pos;
> - return NULL;
> + return dso__find_by_longname(name);
> }
>
> struct dso *__dsos__findnew(struct list_head *head, const char *name)
> diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
> index ad553ba..81a75ee 100644
> --- a/tools/perf/util/dso.h
> +++ b/tools/perf/util/dso.h
> @@ -76,6 +76,7 @@ struct dso {
> struct list_head node;
> struct rb_root symbols[MAP__NR_TYPES];
> struct rb_root symbol_names[MAP__NR_TYPES];
> + struct rb_node longname_rb_node;
> void *a2l;
> char *symsrc_filename;
> unsigned int a2l_fails;
> --
> 1.7.1
next prev parent reply other threads:[~2014-09-17 14:51 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-16 19:08 [PATCH v2 0/1] perf mem: improves DSO long names search speed with RB tree Waiman Long
2014-09-16 19:08 ` [PATCH v2] " Waiman Long
2014-09-17 6:22 ` Adrian Hunter
2014-09-17 14:08 ` Waiman Long
2014-09-17 14:51 ` Arnaldo Carvalho de Melo [this message]
2014-09-17 17:55 ` Waiman Long
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140917145102.GA2770@kernel.org \
--to=acme@kernel.org \
--cc=Waiman.Long@hp.com \
--cc=adrian.hunter@intel.com \
--cc=dzickus@redhat.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=paulus@samba.org \
--cc=peterz@infradead.org \
--cc=scott.norton@hp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.