Skip to content

Commit 53e74a1

Browse files
author
Ingo Molnar
committed
Merge tag 'perf-urgent-for-mingo-4.10-20170203' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/urgent fixes from Arnaldo Carvalho de Melo: - Reference count maps in callchains, fixing a SEGFAULT when referencing a map after it is freed (Krister Johansen) - Fix segfault on 'perf diff -o N' option (Namhyung Kim) - Fix 'perf diff -o/--order' option behavior (Namhyung Kim) Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
2 parents 34e00ac + aa33b9b commit 53e74a1

File tree

6 files changed

+40
-3
lines changed

6 files changed

+40
-3
lines changed

tools/perf/builtin-diff.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,7 @@ static int ui_init(void)
11991199
BUG_ON(1);
12001200
}
12011201

1202-
perf_hpp__register_sort_field(fmt);
1202+
perf_hpp__prepend_sort_field(fmt);
12031203
return 0;
12041204
}
12051205

tools/perf/ui/hist.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,12 @@ void perf_hpp_list__register_sort_field(struct perf_hpp_list *list,
521521
list_add_tail(&format->sort_list, &list->sorts);
522522
}
523523

524+
void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list,
525+
struct perf_hpp_fmt *format)
526+
{
527+
list_add(&format->sort_list, &list->sorts);
528+
}
529+
524530
void perf_hpp__column_unregister(struct perf_hpp_fmt *format)
525531
{
526532
list_del(&format->list);
@@ -560,6 +566,10 @@ void perf_hpp__setup_output_field(struct perf_hpp_list *list)
560566
perf_hpp_list__for_each_sort_list(list, fmt) {
561567
struct perf_hpp_fmt *pos;
562568

569+
/* skip sort-only fields ("sort_compute" in perf diff) */
570+
if (!fmt->entry && !fmt->color)
571+
continue;
572+
563573
perf_hpp_list__for_each_format(list, pos) {
564574
if (fmt_equal(fmt, pos))
565575
goto next;

tools/perf/util/callchain.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor)
437437
}
438438
call->ip = cursor_node->ip;
439439
call->ms.sym = cursor_node->sym;
440-
call->ms.map = cursor_node->map;
440+
call->ms.map = map__get(cursor_node->map);
441441

442442
if (cursor_node->branch) {
443443
call->branch_count = 1;
@@ -477,6 +477,7 @@ add_child(struct callchain_node *parent,
477477

478478
list_for_each_entry_safe(call, tmp, &new->val, list) {
479479
list_del(&call->list);
480+
map__zput(call->ms.map);
480481
free(call);
481482
}
482483
free(new);
@@ -761,6 +762,7 @@ merge_chain_branch(struct callchain_cursor *cursor,
761762
list->ms.map, list->ms.sym,
762763
false, NULL, 0, 0);
763764
list_del(&list->list);
765+
map__zput(list->ms.map);
764766
free(list);
765767
}
766768

@@ -811,7 +813,8 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
811813
}
812814

813815
node->ip = ip;
814-
node->map = map;
816+
map__zput(node->map);
817+
node->map = map__get(map);
815818
node->sym = sym;
816819
node->branch = branch;
817820
node->nr_loop_iter = nr_loop_iter;
@@ -1142,11 +1145,13 @@ static void free_callchain_node(struct callchain_node *node)
11421145

11431146
list_for_each_entry_safe(list, tmp, &node->parent_val, list) {
11441147
list_del(&list->list);
1148+
map__zput(list->ms.map);
11451149
free(list);
11461150
}
11471151

11481152
list_for_each_entry_safe(list, tmp, &node->val, list) {
11491153
list_del(&list->list);
1154+
map__zput(list->ms.map);
11501155
free(list);
11511156
}
11521157

@@ -1210,6 +1215,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
12101215
goto out;
12111216
*new = *chain;
12121217
new->has_children = false;
1218+
map__get(new->ms.map);
12131219
list_add_tail(&new->list, &head);
12141220
}
12151221
parent = parent->parent;
@@ -1230,6 +1236,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
12301236
out:
12311237
list_for_each_entry_safe(chain, new, &head, list) {
12321238
list_del(&chain->list);
1239+
map__zput(chain->ms.map);
12331240
free(chain);
12341241
}
12351242
return -ENOMEM;

tools/perf/util/callchain.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/list.h>
66
#include <linux/rbtree.h>
77
#include "event.h"
8+
#include "map.h"
89
#include "symbol.h"
910

1011
#define HELP_PAD "\t\t\t\t"
@@ -184,8 +185,13 @@ int callchain_merge(struct callchain_cursor *cursor,
184185
*/
185186
static inline void callchain_cursor_reset(struct callchain_cursor *cursor)
186187
{
188+
struct callchain_cursor_node *node;
189+
187190
cursor->nr = 0;
188191
cursor->last = &cursor->first;
192+
193+
for (node = cursor->first; node != NULL; node = node->next)
194+
map__zput(node->map);
189195
}
190196

191197
int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,

tools/perf/util/hist.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "util.h"
22
#include "build-id.h"
33
#include "hist.h"
4+
#include "map.h"
45
#include "session.h"
56
#include "sort.h"
67
#include "evlist.h"
@@ -1019,6 +1020,10 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
10191020
int max_stack_depth, void *arg)
10201021
{
10211022
int err, err2;
1023+
struct map *alm = NULL;
1024+
1025+
if (al && al->map)
1026+
alm = map__get(al->map);
10221027

10231028
err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent,
10241029
iter->evsel, al, max_stack_depth);
@@ -1058,6 +1063,8 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
10581063
if (!err)
10591064
err = err2;
10601065

1066+
map__put(alm);
1067+
10611068
return err;
10621069
}
10631070

tools/perf/util/hist.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ void perf_hpp_list__column_register(struct perf_hpp_list *list,
283283
struct perf_hpp_fmt *format);
284284
void perf_hpp_list__register_sort_field(struct perf_hpp_list *list,
285285
struct perf_hpp_fmt *format);
286+
void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list,
287+
struct perf_hpp_fmt *format);
286288

287289
static inline void perf_hpp__column_register(struct perf_hpp_fmt *format)
288290
{
@@ -294,6 +296,11 @@ static inline void perf_hpp__register_sort_field(struct perf_hpp_fmt *format)
294296
perf_hpp_list__register_sort_field(&perf_hpp_list, format);
295297
}
296298

299+
static inline void perf_hpp__prepend_sort_field(struct perf_hpp_fmt *format)
300+
{
301+
perf_hpp_list__prepend_sort_field(&perf_hpp_list, format);
302+
}
303+
297304
#define perf_hpp_list__for_each_format(_list, format) \
298305
list_for_each_entry(format, &(_list)->fields, list)
299306

0 commit comments

Comments
 (0)