All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org,
	Arnaldo Carvalho de Melo <acme@redhat.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Borislav Petkov <bp@suse.de>, David Ahern <dsahern@gmail.com>,
	Don Zickus <dzickus@redhat.com>,
	Frederic Weisbecker <fweisbec@gmail.com>,
	Jiri Olsa <jolsa@redhat.com>, Namhyung Kim <namhyung@kernel.org>,
	Stephane Eranian <eranian@google.com>
Subject: [PATCH 1/7] perf tools: Introduce struct maps
Date: Wed, 27 May 2015 21:05:28 -0300	[thread overview]
Message-ID: <1432771534-1312-2-git-send-email-acme@kernel.org> (raw)
In-Reply-To: <1432771534-1312-1-git-send-email-acme@kernel.org>

From: Arnaldo Carvalho de Melo <acme@redhat.com>

That for now has the maps rbtree and the list for the dead maps, that
may be still referenced from some hist_entry, etc.

This paves the way for protecting the rbtree with a lock, then refcount
the maps and finally remove the removed_maps list, as it'll not ne
anymore needed.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-fl0fa6142pj8khj97fow3uw0@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/vmlinux-kallsyms.c |  2 +-
 tools/perf/util/event.c             |  2 +-
 tools/perf/util/map.c               | 64 +++++++++++++++++++++----------------
 tools/perf/util/map.h               | 16 ++++++----
 tools/perf/util/probe-event.c       |  2 +-
 tools/perf/util/symbol.c            |  4 +--
 6 files changed, 52 insertions(+), 38 deletions(-)

diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c
index 94ac6924df65..b34c5fc829ae 100644
--- a/tools/perf/tests/vmlinux-kallsyms.c
+++ b/tools/perf/tests/vmlinux-kallsyms.c
@@ -26,7 +26,7 @@ int test__vmlinux_matches_kallsyms(void)
 	struct map *kallsyms_map, *vmlinux_map, *map;
 	struct machine kallsyms, vmlinux;
 	enum map_type type = MAP__FUNCTION;
-	struct rb_root *maps = &vmlinux.kmaps.maps[type];
+	struct maps *maps = &vmlinux.kmaps.maps[type];
 	u64 mem_start, mem_end;
 
 	/*
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 9d3bba175423..c1925968a8af 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -331,7 +331,7 @@ int perf_event__synthesize_modules(struct perf_tool *tool,
 	int rc = 0;
 	struct map *pos;
 	struct map_groups *kmaps = &machine->kmaps;
-	struct rb_root *maps = &kmaps->maps[MAP__FUNCTION];
+	struct maps *maps = &kmaps->maps[MAP__FUNCTION];
 	union perf_event *event = zalloc((sizeof(event->mmap) +
 					  machine->id_hdr_size));
 	if (event == NULL) {
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 898ab92a98dd..adf012c4d650 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -418,48 +418,58 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
 	return ip + map->reloc;
 }
 
+static void maps__init(struct maps *maps)
+{
+	maps->entries = RB_ROOT;
+	INIT_LIST_HEAD(&maps->removed_maps);
+}
+
 void map_groups__init(struct map_groups *mg, struct machine *machine)
 {
 	int i;
 	for (i = 0; i < MAP__NR_TYPES; ++i) {
-		mg->maps[i] = RB_ROOT;
-		INIT_LIST_HEAD(&mg->removed_maps[i]);
+		maps__init(&mg->maps[i]);
 	}
 	mg->machine = machine;
 	atomic_set(&mg->refcnt, 1);
 }
 
-static void maps__delete(struct rb_root *maps)
+static void maps__purge(struct maps *maps)
 {
-	struct rb_node *next = rb_first(maps);
+	struct rb_root *root = &maps->entries;
+	struct rb_node *next = rb_first(root);
 
 	while (next) {
 		struct map *pos = rb_entry(next, struct map, rb_node);
 
 		next = rb_next(&pos->rb_node);
-		rb_erase(&pos->rb_node, maps);
+		rb_erase(&pos->rb_node, root);
 		map__delete(pos);
 	}
 }
 
-static void maps__delete_removed(struct list_head *maps)
+static void maps__purge_removed_maps(struct maps *maps)
 {
 	struct map *pos, *n;
 
-	list_for_each_entry_safe(pos, n, maps, node) {
+	list_for_each_entry_safe(pos, n, &maps->removed_maps, node) {
 		list_del(&pos->node);
 		map__delete(pos);
 	}
 }
 
+static void maps__exit(struct maps *maps)
+{
+	maps__purge(maps);
+	maps__purge_removed_maps(maps);
+}
+
 void map_groups__exit(struct map_groups *mg)
 {
 	int i;
 
-	for (i = 0; i < MAP__NR_TYPES; ++i) {
-		maps__delete(&mg->maps[i]);
-		maps__delete_removed(&mg->removed_maps[i]);
-	}
+	for (i = 0; i < MAP__NR_TYPES; ++i)
+		maps__exit(&mg->maps[i]);
 }
 
 bool map_groups__empty(struct map_groups *mg)
@@ -469,7 +479,7 @@ bool map_groups__empty(struct map_groups *mg)
 	for (i = 0; i < MAP__NR_TYPES; ++i) {
 		if (maps__first(&mg->maps[i]))
 			return false;
-		if (!list_empty(&mg->removed_maps[i]))
+		if (!list_empty(&mg->maps[i].removed_maps))
 			return false;
 	}
 
@@ -523,7 +533,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
 {
 	struct rb_node *nd;
 
-	for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
+	for (nd = rb_first(&mg->maps[type].entries); nd; nd = rb_next(nd)) {
 		struct map *pos = rb_entry(nd, struct map, rb_node);
 		struct symbol *sym = map__find_symbol_by_name(pos, name, filter);
 
@@ -560,7 +570,7 @@ size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
 	size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
 	struct rb_node *nd;
 
-	for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
+	for (nd = rb_first(&mg->maps[type].entries); nd; nd = rb_next(nd)) {
 		struct map *pos = rb_entry(nd, struct map, rb_node);
 		printed += fprintf(fp, "Map:");
 		printed += map__fprintf(pos, fp);
@@ -587,7 +597,7 @@ static size_t __map_groups__fprintf_removed_maps(struct map_groups *mg,
 	struct map *pos;
 	size_t printed = 0;
 
-	list_for_each_entry(pos, &mg->removed_maps[type], node) {
+	list_for_each_entry(pos, &mg->maps[type].removed_maps, node) {
 		printed += fprintf(fp, "Map:");
 		printed += map__fprintf(pos, fp);
 		if (verbose > 1) {
@@ -617,7 +627,7 @@ size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
 int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
 				   FILE *fp)
 {
-	struct rb_root *root = &mg->maps[map->type];
+	struct rb_root *root = &mg->maps[map->type].entries;
 	struct rb_node *next = rb_first(root);
 	int err = 0;
 
@@ -671,7 +681,7 @@ move_map:
 		 * If we have references, just move them to a separate list.
 		 */
 		if (pos->referenced)
-			list_add_tail(&pos->node, &mg->removed_maps[map->type]);
+			list_add_tail(&pos->node, &mg->maps[map->type].removed_maps);
 		else
 			map__delete(pos);
 
@@ -689,7 +699,7 @@ int map_groups__clone(struct map_groups *mg,
 		      struct map_groups *parent, enum map_type type)
 {
 	struct map *map;
-	struct rb_root *maps = &parent->maps[type];
+	struct maps *maps = &parent->maps[type];
 
 	for (map = maps__first(maps); map; map = map__next(map)) {
 		struct map *new = map__clone(map);
@@ -700,9 +710,9 @@ int map_groups__clone(struct map_groups *mg,
 	return 0;
 }
 
-void maps__insert(struct rb_root *maps, struct map *map)
+void maps__insert(struct maps *maps, struct map *map)
 {
-	struct rb_node **p = &maps->rb_node;
+	struct rb_node **p = &maps->entries.rb_node;
 	struct rb_node *parent = NULL;
 	const u64 ip = map->start;
 	struct map *m;
@@ -717,17 +727,17 @@ void maps__insert(struct rb_root *maps, struct map *map)
 	}
 
 	rb_link_node(&map->rb_node, parent, p);
-	rb_insert_color(&map->rb_node, maps);
+	rb_insert_color(&map->rb_node, &maps->entries);
 }
 
-void maps__remove(struct rb_root *maps, struct map *map)
+void maps__remove(struct maps *maps, struct map *map)
 {
-	rb_erase(&map->rb_node, maps);
+	rb_erase(&map->rb_node, &maps->entries);
 }
 
-struct map *maps__find(struct rb_root *maps, u64 ip)
+struct map *maps__find(struct maps *maps, u64 ip)
 {
-	struct rb_node **p = &maps->rb_node;
+	struct rb_node **p = &maps->entries.rb_node;
 	struct rb_node *parent = NULL;
 	struct map *m;
 
@@ -745,9 +755,9 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
 	return NULL;
 }
 
-struct map *maps__first(struct rb_root *maps)
+struct map *maps__first(struct maps *maps)
 {
-	struct rb_node *first = rb_first(maps);
+	struct rb_node *first = rb_first(&maps->entries);
 
 	if (first)
 		return rb_entry(first, struct map, rb_node);
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index f2b27566d986..e3702fd468c5 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -58,9 +58,13 @@ struct kmap {
 	struct map_groups	*kmaps;
 };
 
+struct maps {
+	struct rb_root	 entries;
+	struct list_head removed_maps;
+};
+
 struct map_groups {
-	struct rb_root	 maps[MAP__NR_TYPES];
-	struct list_head removed_maps[MAP__NR_TYPES];
+	struct maps	 maps[MAP__NR_TYPES];
 	struct machine	 *machine;
 	atomic_t	 refcnt;
 };
@@ -162,10 +166,10 @@ void map__reloc_vmlinux(struct map *map);
 
 size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
 				  FILE *fp);
-void maps__insert(struct rb_root *maps, struct map *map);
-void maps__remove(struct rb_root *maps, struct map *map);
-struct map *maps__find(struct rb_root *maps, u64 addr);
-struct map *maps__first(struct rb_root *maps);
+void maps__insert(struct maps *maps, struct map *map);
+void maps__remove(struct maps *maps, struct map *map);
+struct map *maps__find(struct maps *maps, u64 addr);
+struct map *maps__first(struct maps *maps);
 struct map *map__next(struct map *map);
 void map_groups__init(struct map_groups *mg, struct machine *machine);
 void map_groups__exit(struct map_groups *mg);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 97da98481d89..32471d0839d1 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -163,7 +163,7 @@ static u64 kernel_get_symbol_address_by_name(const char *name, bool reloc)
 static struct map *kernel_get_module_map(const char *module)
 {
 	struct map_groups *grp = &host_machine->kmaps;
-	struct rb_root *maps = &grp->maps[MAP__FUNCTION];
+	struct maps *maps = &grp->maps[MAP__FUNCTION];
 	struct map *pos;
 
 	/* A file path -- this is an offline module */
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index b9e3eb581884..c8a3e79c5da2 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -202,7 +202,7 @@ void symbols__fixup_end(struct rb_root *symbols)
 
 void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
 {
-	struct rb_root *maps = &mg->maps[type];
+	struct maps *maps = &mg->maps[type];
 	struct map *next, *curr;
 
 	curr = maps__first(maps);
@@ -1520,7 +1520,7 @@ out:
 struct map *map_groups__find_by_name(struct map_groups *mg,
 				     enum map_type type, const char *name)
 {
-	struct rb_root *maps = &mg->maps[type];
+	struct maps *maps = &mg->maps[type];
 	struct map *map;
 
 	for (map = maps__first(maps); map; map = map__next(map)) {
-- 
2.1.0


  reply	other threads:[~2015-05-28  0:06 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-28  0:05 [GIT PULL 0/7] perf/core refactorings and improvements Arnaldo Carvalho de Melo
2015-05-28  0:05 ` Arnaldo Carvalho de Melo [this message]
2015-05-28  0:05 ` [PATCH 2/7] perf tools: Protect accesses the map rbtrees with a rw lock Arnaldo Carvalho de Melo
2015-05-28  0:05 ` [PATCH 3/7] perf tools: Check if a map is still in use when deleting it Arnaldo Carvalho de Melo
2015-05-28  0:05 ` [PATCH 4/7] perf tools: Reference count struct map Arnaldo Carvalho de Melo
2015-05-28  0:05 ` [PATCH 5/7] perf tools: Add hint for 'Too many events are opened.' error message Arnaldo Carvalho de Melo
2015-05-28  0:05 ` [PATCH 6/7] perf annotation: Add symbol__get_annotation Arnaldo Carvalho de Melo
2015-05-28  0:05 ` [PATCH 7/7] perf tools: Move branch option parsing to own file Arnaldo Carvalho de Melo
2015-05-28  0:27 ` [GIT PULL 0/7] perf/core refactorings and improvements Arnaldo Carvalho de Melo
2015-05-28  9:27   ` Ingo Molnar

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=1432771534-1312-2-git-send-email-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=bp@suse.de \
    --cc=dsahern@gmail.com \
    --cc=dzickus@redhat.com \
    --cc=eranian@google.com \
    --cc=fweisbec@gmail.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    /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.