FAILED: patch "[PATCH] perf callchain: Reference count maps" failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
aa33b9b9a2ebb00d33c83a5312d4fbf2d5aeba36Mon Sep 17 00:00:00 2001
From: Krister Johansen <[email protected]>
Date: Thu, 5 Jan 2017 22:23:31 -0800
Subject: [PATCH] perf callchain: Reference count maps
If dso__load_kcore frees all of the existing maps, but one has already been attached to a callchain cursor node, then we can get a SIGSEGV in any function that happens to try to use this invalid cursor. Use the existing map refcount mechanism to forestall cleanup of a map until the cursor iterates past the node.
tools/perf/util/callchain.c +9 -2
@@ -437,7 +437,7 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor) } call->ip = cursor_node->ip; call->ms.sym = cursor_node->sym; - call->ms.map = cursor_node->map; + call->ms.map =map__get (cursor_node->map);if (cursor_node->branch) { call->branch_count =1 ;
@@ -477,6 +477,7 @@ add_child(struct callchain_node *parent,list_for_each_entry_safe (call, tmp, &new->val, list) {list_del (&call->list); +map__zput (call->ms.map);free (call); }free (new);
@@ -761,6 +762,7 @@ merge_chain_branch(struct callchain_cursor *cursor, list->ms.map, list->ms.sym, false, NULL, 0, 0);list_del (&list->list); +map__zput (list->ms.map);free (list); }
@@ -811,7 +813,8 @@ int callchain_cursor_append(struct callchain_cursor *cursor, } node->ip = ip; - node->map = map; +map__zput (node->map); + node->map =map__get (map); node->sym = sym; node->branch = branch; node->nr_loop_iter = nr_loop_iter;
@@ -1142,11 +1145,13 @@ static void free_callchain_node(struct callchain_node *node)list_for_each_entry_safe (list, tmp, &node->parent_val, list) {list_del (&list->list); +map__zput (list->ms.map);free (list); }list_for_each_entry_safe (list, tmp, &node->val, list) {list_del (&list->list); +map__zput (list->ms.map);free (list); }
@@ -1210,6 +1215,7 @@ int callchain_node__make_parent_list(struct callchain_node *node) goto out; *new = *chain; new->has_children = false; +map__get (new->ms.map);list_add_tail (&new->list, &head); } parent = parent->parent;
@@ -1230,6 +1236,7 @@ int callchain_node__make_parent_list(struct callchain_node *node) out:list_for_each_entry_safe (chain, new, &head, list) {list_del (&chain->list); +map__zput (chain->ms.map);free (chain); }return -ENOMEM ;
tools/perf/util/callchain.h +6 -0
@@ -5,6 +5,7 @@#include <linux/list.h> #include <linux/rbtree.h> #include "event.h" +#include "map.h" #include "symbol.h" #define HELP_PAD "\t\t\t\t"
@@ -184,8 +185,13 @@ int callchain_merge(struct callchain_cursor *cursor,*/ static inline void callchain_cursor_reset (struct callchain_cursor *cursor) { +struct callchain_cursor_node *node; + cursor->nr =0 ; cursor->last = &cursor->first; + +for (node = cursor->first; node !=NULL ; node = node->next) +map__zput (node->map); } int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
tools/perf/util/hist.c +7 -0
@@ -1,6 +1,7 @@#include "util.h" #include "build-id.h" #include "hist.h" +#include "map.h" #include "session.h" #include "sort.h" #include "evlist.h"
@@ -1019,6 +1020,10 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, int max_stack_depth, void *arg) { int err, err2; +struct map *alm =NULL ; + +if (al && al->map) + alm =map__get (al->map); err =sample__resolve_callchain (iter->sample, &callchain_cursor, &iter->parent, iter->evsel, al, max_stack_depth);
@@ -1058,6 +1063,8 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,if (!err) err = err2; +map__put (alm); +return err; }