mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-08 18:35:20 +02:00
perf tools: Replace map->referenced & maps->removed_maps with map->refcnt
Use just reference counts, so that when no more hist_entry instances references a map and the thread instance goes away by processing a PERF_RECORD_EXIT, we can delete the maps. 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-oym7lfhcc7ss6xpz44h7nbxs@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
35a23ff928
commit
5c24b67aae
|
@ -313,8 +313,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
|
||||||
memset(&he->stat, 0, sizeof(he->stat));
|
memset(&he->stat, 0, sizeof(he->stat));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (he->ms.map)
|
map__get(he->ms.map);
|
||||||
he->ms.map->referenced = true;
|
|
||||||
|
|
||||||
if (he->branch_info) {
|
if (he->branch_info) {
|
||||||
/*
|
/*
|
||||||
|
@ -324,6 +323,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
|
||||||
*/
|
*/
|
||||||
he->branch_info = malloc(sizeof(*he->branch_info));
|
he->branch_info = malloc(sizeof(*he->branch_info));
|
||||||
if (he->branch_info == NULL) {
|
if (he->branch_info == NULL) {
|
||||||
|
map__zput(he->ms.map);
|
||||||
free(he->stat_acc);
|
free(he->stat_acc);
|
||||||
free(he);
|
free(he);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -332,17 +332,13 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
|
||||||
memcpy(he->branch_info, template->branch_info,
|
memcpy(he->branch_info, template->branch_info,
|
||||||
sizeof(*he->branch_info));
|
sizeof(*he->branch_info));
|
||||||
|
|
||||||
if (he->branch_info->from.map)
|
map__get(he->branch_info->from.map);
|
||||||
he->branch_info->from.map->referenced = true;
|
map__get(he->branch_info->to.map);
|
||||||
if (he->branch_info->to.map)
|
|
||||||
he->branch_info->to.map->referenced = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (he->mem_info) {
|
if (he->mem_info) {
|
||||||
if (he->mem_info->iaddr.map)
|
map__get(he->mem_info->iaddr.map);
|
||||||
he->mem_info->iaddr.map->referenced = true;
|
map__get(he->mem_info->daddr.map);
|
||||||
if (he->mem_info->daddr.map)
|
|
||||||
he->mem_info->daddr.map->referenced = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol_conf.use_callchain)
|
if (symbol_conf.use_callchain)
|
||||||
|
@ -407,9 +403,8 @@ static struct hist_entry *hists__findnew_entry(struct hists *hists,
|
||||||
* the history counter to increment.
|
* the history counter to increment.
|
||||||
*/
|
*/
|
||||||
if (he->ms.map != entry->ms.map) {
|
if (he->ms.map != entry->ms.map) {
|
||||||
he->ms.map = entry->ms.map;
|
map__put(he->ms.map);
|
||||||
if (he->ms.map)
|
he->ms.map = map__get(entry->ms.map);
|
||||||
he->ms.map->referenced = true;
|
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -933,8 +928,20 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
|
||||||
void hist_entry__delete(struct hist_entry *he)
|
void hist_entry__delete(struct hist_entry *he)
|
||||||
{
|
{
|
||||||
thread__zput(he->thread);
|
thread__zput(he->thread);
|
||||||
zfree(&he->branch_info);
|
map__zput(he->ms.map);
|
||||||
zfree(&he->mem_info);
|
|
||||||
|
if (he->branch_info) {
|
||||||
|
map__zput(he->branch_info->from.map);
|
||||||
|
map__zput(he->branch_info->to.map);
|
||||||
|
zfree(&he->branch_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (he->mem_info) {
|
||||||
|
map__zput(he->mem_info->iaddr.map);
|
||||||
|
map__zput(he->mem_info->daddr.map);
|
||||||
|
zfree(&he->mem_info);
|
||||||
|
}
|
||||||
|
|
||||||
zfree(&he->stat_acc);
|
zfree(&he->stat_acc);
|
||||||
free_srcline(he->srcline);
|
free_srcline(he->srcline);
|
||||||
free_callchain(he->callchain);
|
free_callchain(he->callchain);
|
||||||
|
|
|
@ -137,7 +137,6 @@ void map__init(struct map *map, enum map_type type,
|
||||||
map->unmap_ip = map__unmap_ip;
|
map->unmap_ip = map__unmap_ip;
|
||||||
RB_CLEAR_NODE(&map->rb_node);
|
RB_CLEAR_NODE(&map->rb_node);
|
||||||
map->groups = NULL;
|
map->groups = NULL;
|
||||||
map->referenced = false;
|
|
||||||
map->erange_warned = false;
|
map->erange_warned = false;
|
||||||
atomic_set(&map->refcnt, 1);
|
atomic_set(&map->refcnt, 1);
|
||||||
}
|
}
|
||||||
|
@ -439,7 +438,6 @@ static void maps__init(struct maps *maps)
|
||||||
{
|
{
|
||||||
maps->entries = RB_ROOT;
|
maps->entries = RB_ROOT;
|
||||||
pthread_rwlock_init(&maps->lock, NULL);
|
pthread_rwlock_init(&maps->lock, NULL);
|
||||||
INIT_LIST_HEAD(&maps->removed_maps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void map_groups__init(struct map_groups *mg, struct machine *machine)
|
void map_groups__init(struct map_groups *mg, struct machine *machine)
|
||||||
|
@ -466,21 +464,10 @@ static void __maps__purge(struct maps *maps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __maps__purge_removed_maps(struct maps *maps)
|
|
||||||
{
|
|
||||||
struct map *pos, *n;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pos, n, &maps->removed_maps, node) {
|
|
||||||
list_del_init(&pos->node);
|
|
||||||
map__put(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void maps__exit(struct maps *maps)
|
static void maps__exit(struct maps *maps)
|
||||||
{
|
{
|
||||||
pthread_rwlock_wrlock(&maps->lock);
|
pthread_rwlock_wrlock(&maps->lock);
|
||||||
__maps__purge(maps);
|
__maps__purge(maps);
|
||||||
__maps__purge_removed_maps(maps);
|
|
||||||
pthread_rwlock_unlock(&maps->lock);
|
pthread_rwlock_unlock(&maps->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,8 +486,6 @@ bool map_groups__empty(struct map_groups *mg)
|
||||||
for (i = 0; i < MAP__NR_TYPES; ++i) {
|
for (i = 0; i < MAP__NR_TYPES; ++i) {
|
||||||
if (maps__first(&mg->maps[i]))
|
if (maps__first(&mg->maps[i]))
|
||||||
return false;
|
return false;
|
||||||
if (!list_empty(&mg->maps[i].removed_maps))
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -621,7 +606,7 @@ size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
|
||||||
return printed += maps__fprintf(&mg->maps[type], fp);
|
return printed += maps__fprintf(&mg->maps[type], fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t map_groups__fprintf_maps(struct map_groups *mg, FILE *fp)
|
size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
|
||||||
{
|
{
|
||||||
size_t printed = 0, i;
|
size_t printed = 0, i;
|
||||||
for (i = 0; i < MAP__NR_TYPES; ++i)
|
for (i = 0; i < MAP__NR_TYPES; ++i)
|
||||||
|
@ -629,39 +614,6 @@ static size_t map_groups__fprintf_maps(struct map_groups *mg, FILE *fp)
|
||||||
return printed;
|
return printed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t __map_groups__fprintf_removed_maps(struct map_groups *mg,
|
|
||||||
enum map_type type, FILE *fp)
|
|
||||||
{
|
|
||||||
struct map *pos;
|
|
||||||
size_t printed = 0;
|
|
||||||
|
|
||||||
list_for_each_entry(pos, &mg->maps[type].removed_maps, node) {
|
|
||||||
printed += fprintf(fp, "Map:");
|
|
||||||
printed += map__fprintf(pos, fp);
|
|
||||||
if (verbose > 1) {
|
|
||||||
printed += dso__fprintf(pos->dso, type, fp);
|
|
||||||
printed += fprintf(fp, "--\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return printed;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t map_groups__fprintf_removed_maps(struct map_groups *mg,
|
|
||||||
FILE *fp)
|
|
||||||
{
|
|
||||||
size_t printed = 0, i;
|
|
||||||
for (i = 0; i < MAP__NR_TYPES; ++i)
|
|
||||||
printed += __map_groups__fprintf_removed_maps(mg, i, fp);
|
|
||||||
return printed;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
|
|
||||||
{
|
|
||||||
size_t printed = map_groups__fprintf_maps(mg, fp);
|
|
||||||
printed += fprintf(fp, "Removed maps:\n");
|
|
||||||
return printed + map_groups__fprintf_removed_maps(mg, fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
|
static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
|
||||||
{
|
{
|
||||||
struct rb_root *root;
|
struct rb_root *root;
|
||||||
|
@ -719,13 +671,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
|
||||||
map__fprintf(after, fp);
|
map__fprintf(after, fp);
|
||||||
}
|
}
|
||||||
put_map:
|
put_map:
|
||||||
/*
|
map__put(pos);
|
||||||
* If we have references, just move them to a separate list.
|
|
||||||
*/
|
|
||||||
if (pos->referenced)
|
|
||||||
list_add_tail(&pos->node, &maps->removed_maps);
|
|
||||||
else
|
|
||||||
map__put(pos);
|
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -34,7 +34,6 @@ struct map {
|
||||||
u64 start;
|
u64 start;
|
||||||
u64 end;
|
u64 end;
|
||||||
u8 /* enum map_type */ type;
|
u8 /* enum map_type */ type;
|
||||||
bool referenced;
|
|
||||||
bool erange_warned;
|
bool erange_warned;
|
||||||
u32 priv;
|
u32 priv;
|
||||||
u32 prot;
|
u32 prot;
|
||||||
|
@ -63,7 +62,6 @@ struct kmap {
|
||||||
struct maps {
|
struct maps {
|
||||||
struct rb_root entries;
|
struct rb_root entries;
|
||||||
pthread_rwlock_t lock;
|
pthread_rwlock_t lock;
|
||||||
struct list_head removed_maps;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct map_groups {
|
struct map_groups {
|
||||||
|
@ -161,6 +159,14 @@ static inline struct map *map__get(struct map *map)
|
||||||
|
|
||||||
void map__put(struct map *map);
|
void map__put(struct map *map);
|
||||||
|
|
||||||
|
static inline void __map__zput(struct map **map)
|
||||||
|
{
|
||||||
|
map__put(*map);
|
||||||
|
*map = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define map__zput(map) __map__zput(&map)
|
||||||
|
|
||||||
int map__overlap(struct map *l, struct map *r);
|
int map__overlap(struct map *l, struct map *r);
|
||||||
size_t map__fprintf(struct map *map, FILE *fp);
|
size_t map__fprintf(struct map *map, FILE *fp);
|
||||||
size_t map__fprintf_dsoname(struct map *map, FILE *fp);
|
size_t map__fprintf_dsoname(struct map *map, FILE *fp);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user