lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <tip-wi19xczk0t2a41r1i2chuio5@git.kernel.org>
Date:	Thu, 28 May 2015 02:31:36 -0700
From:	tip-bot for Arnaldo Carvalho de Melo <tipbot@...or.com>
To:	linux-tip-commits@...r.kernel.org
Cc:	mingo@...nel.org, eranian@...gle.com, linux-kernel@...r.kernel.org,
	fweisbec@...il.com, namhyung@...nel.org, jolsa@...hat.com,
	dsahern@...il.com, acme@...hat.com, bp@...e.de, tglx@...utronix.de,
	adrian.hunter@...el.com, hpa@...or.com, dzickus@...hat.com
Subject: [tip:perf/core] perf tools: Reference count struct map

Commit-ID:  84c2cafa288939e11d21c7830e32b2aee21b723e
Gitweb:     http://git.kernel.org/tip/84c2cafa288939e11d21c7830e32b2aee21b723e
Author:     Arnaldo Carvalho de Melo <acme@...hat.com>
AuthorDate: Mon, 25 May 2015 16:59:56 -0300
Committer:  Arnaldo Carvalho de Melo <acme@...hat.com>
CommitDate: Wed, 27 May 2015 20:27:30 -0300

perf tools: Reference count struct map

We have pointers to struct map instances in several places, like in the
hist_entry instances, so we need a way to know when we can destroy them,
otherwise we may either keep leaking them or end up referencing deleted
instances.

Start fixing it by reference counting them.

This patch puts the reference count for struct map in place, replacing
direct map__delete() calls with map__put() ones and then grabbing a
reference count when adding it to the maps struct where maps for a
struct thread are kept.

Next we'll grab reference counts when setting pointers to struct map
instances, in places like in the hist_entry code.

Cc: Adrian Hunter <adrian.hunter@...el.com>
Cc: Borislav Petkov <bp@...e.de>
Cc: David Ahern <dsahern@...il.com>
Cc: Don Zickus <dzickus@...hat.com>
Cc: Frederic Weisbecker <fweisbec@...il.com>
Cc: Jiri Olsa <jolsa@...hat.com>
Cc: Namhyung Kim <namhyung@...nel.org>
Cc: Stephane Eranian <eranian@...gle.com>
Link: http://lkml.kernel.org/n/tip-wi19xczk0t2a41r1i2chuio5@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@...hat.com>
---
 tools/perf/util/machine.c     |  3 ++-
 tools/perf/util/map.c         | 21 +++++++++++++++------
 tools/perf/util/map.h         | 11 +++++++++++
 tools/perf/util/probe-event.c |  6 +++---
 tools/perf/util/symbol-elf.c  |  2 ++
 tools/perf/util/symbol.c      |  7 +++++--
 6 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 6bf8457..0c0e61c 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -759,7 +759,6 @@ void machine__destroy_kernel_maps(struct machine *machine)
 				kmap->ref_reloc_sym = NULL;
 		}
 
-		map__delete(machine->vmlinux_maps[type]);
 		machine->vmlinux_maps[type] = NULL;
 	}
 }
@@ -1247,6 +1246,7 @@ int machine__process_mmap2_event(struct machine *machine,
 
 	thread__insert_map(thread, map);
 	thread__put(thread);
+	map__put(map);
 	return 0;
 
 out_problem_map:
@@ -1297,6 +1297,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
 
 	thread__insert_map(thread, map);
 	thread__put(thread);
+	map__put(map);
 	return 0;
 
 out_problem_map:
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 4d3a92d..af57232 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -139,6 +139,7 @@ void map__init(struct map *map, enum map_type type,
 	map->groups   = NULL;
 	map->referenced = false;
 	map->erange_warned = false;
+	atomic_set(&map->refcnt, 1);
 }
 
 struct map *map__new(struct machine *machine, u64 start, u64 len,
@@ -229,6 +230,12 @@ void map__delete(struct map *map)
 	free(map);
 }
 
+void map__put(struct map *map)
+{
+	if (map && atomic_dec_and_test(&map->refcnt))
+		map__delete(map);
+}
+
 void map__fixup_start(struct map *map)
 {
 	struct rb_root *symbols = &map->dso->symbols[map->type];
@@ -448,7 +455,7 @@ static void __maps__purge(struct maps *maps)
 
 		next = rb_next(&pos->rb_node);
 		rb_erase_init(&pos->rb_node, root);
-		map__delete(pos);
+		map__put(pos);
 	}
 }
 
@@ -458,7 +465,7 @@ static void __maps__purge_removed_maps(struct maps *maps)
 
 	list_for_each_entry_safe(pos, n, &maps->removed_maps, node) {
 		list_del_init(&pos->node);
-		map__delete(pos);
+		map__put(pos);
 	}
 }
 
@@ -682,7 +689,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
 
 			if (before == NULL) {
 				err = -ENOMEM;
-				goto move_map;
+				goto put_map;
 			}
 
 			before->end = map->start;
@@ -696,7 +703,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
 
 			if (after == NULL) {
 				err = -ENOMEM;
-				goto move_map;
+				goto put_map;
 			}
 
 			after->start = map->end;
@@ -704,14 +711,14 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
 			if (verbose >= 2)
 				map__fprintf(after, fp);
 		}
-move_map:
+put_map:
 		/*
 		 * If we have references, just move them to a separate list.
 		 */
 		if (pos->referenced)
 			list_add_tail(&pos->node, &maps->removed_maps);
 		else
-			map__delete(pos);
+			map__put(pos);
 
 		if (err)
 			goto out;
@@ -772,6 +779,7 @@ static void __maps__insert(struct maps *maps, struct map *map)
 
 	rb_link_node(&map->rb_node, parent, p);
 	rb_insert_color(&map->rb_node, &maps->entries);
+	map__get(map);
 }
 
 void maps__insert(struct maps *maps, struct map *map)
@@ -784,6 +792,7 @@ void maps__insert(struct maps *maps, struct map *map)
 static void __maps__remove(struct maps *maps, struct map *map)
 {
 	rb_erase_init(&map->rb_node, &maps->entries);
+	map__put(map);
 }
 
 void maps__remove(struct maps *maps, struct map *map)
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 6796f27..b8df09d 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -52,6 +52,7 @@ struct map {
 
 	struct dso		*dso;
 	struct map_groups	*groups;
+	atomic_t		refcnt;
 };
 
 struct kmap {
@@ -150,6 +151,16 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
 struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
 void map__delete(struct map *map);
 struct map *map__clone(struct map *map);
+
+static inline struct map *map__get(struct map *map)
+{
+	if (map)
+		atomic_inc(&map->refcnt);
+	return map;
+}
+
+void map__put(struct map *map);
+
 int map__overlap(struct map *l, struct map *r);
 size_t map__fprintf(struct map *map, FILE *fp);
 size_t map__fprintf_dsoname(struct map *map, FILE *fp);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 32471d0..b0b8a80 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -195,7 +195,7 @@ static void put_target_map(struct map *map, bool user)
 {
 	if (map && user) {
 		/* Only the user map needs to be released */
-		map__delete(map);
+		map__put(map);
 	}
 }
 
@@ -1791,7 +1791,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
 
 out:
 	if (map && !is_kprobe) {
-		map__delete(map);
+		map__put(map);
 	}
 
 	return ret;
@@ -2884,7 +2884,7 @@ int show_available_funcs(const char *target, struct strfilter *_filter,
 	dso__fprintf_symbols_by_name(map->dso, map->type, stdout);
 end:
 	if (user) {
-		map__delete(map);
+		map__put(map);
 	}
 	exit_symbol_maps();
 
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 9d526a5..fa10116 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -972,8 +972,10 @@ int dso__load_sym(struct dso *dso, struct map *map,
 					map->unmap_ip = map__unmap_ip;
 					/* Ensure maps are correctly ordered */
 					if (kmaps) {
+						map__get(map);
 						map_groups__remove(kmaps, map);
 						map_groups__insert(kmaps, map);
+						map__put(map);
 					}
 				}
 
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 743a9b3..a3e80d6 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1180,13 +1180,16 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
 			map->pgoff	= new_map->pgoff;
 			map->map_ip	= new_map->map_ip;
 			map->unmap_ip	= new_map->unmap_ip;
-			map__delete(new_map);
 			/* Ensure maps are correctly ordered */
+			map__get(map);
 			map_groups__remove(kmaps, map);
 			map_groups__insert(kmaps, map);
+			map__put(map);
 		} else {
 			map_groups__insert(kmaps, new_map);
 		}
+
+		map__put(new_map);
 	}
 
 	/*
@@ -1212,7 +1215,7 @@ out_err:
 	while (!list_empty(&md.maps)) {
 		map = list_entry(md.maps.next, struct map, node);
 		list_del_init(&map->node);
-		map__delete(map);
+		map__put(map);
 	}
 	close(fd);
 	return -EINVAL;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ