From: Greg Kroah-Hartman Date: Thu, 9 Mar 2017 18:45:08 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.4.53~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=38660a6689131aa57284d3d82baef870021a1baa;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: perf-callchain-reference-count-maps.patch --- diff --git a/queue-4.9/perf-callchain-reference-count-maps.patch b/queue-4.9/perf-callchain-reference-count-maps.patch new file mode 100644 index 00000000000..0459a991760 --- /dev/null +++ b/queue-4.9/perf-callchain-reference-count-maps.patch @@ -0,0 +1,152 @@ +From aa33b9b9a2ebb00d33c83a5312d4fbf2d5aeba36 Mon Sep 17 00:00:00 2001 +From: Krister Johansen +Date: Thu, 5 Jan 2017 22:23:31 -0800 +Subject: perf callchain: Reference count maps + +From: Krister Johansen + +commit aa33b9b9a2ebb00d33c83a5312d4fbf2d5aeba36 upstream. + +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. + +Signed-off-by: Krister Johansen +Tested-by: Arnaldo Carvalho de Melo +Cc: Frederic Weisbecker +Cc: Masami Hiramatsu +Cc: Namhyung Kim +Fixes: 84c2cafa2889 ("perf tools: Reference count struct map") +Link: http://lkml.kernel.org/r/20170106062331.GB2707@templeofstupid.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/util/callchain.c | 11 +++++++++-- + tools/perf/util/callchain.h | 6 ++++++ + tools/perf/util/hist.c | 7 +++++++ + 3 files changed, 22 insertions(+), 2 deletions(-) + +--- a/tools/perf/util/callchain.c ++++ b/tools/perf/util/callchain.c +@@ -437,7 +437,7 @@ fill_node(struct callchain_node *node, s + } + 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); + list_add_tail(&call->list, &node->val); + + callchain_cursor_advance(cursor); +@@ -462,6 +462,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); +@@ -730,6 +731,7 @@ merge_chain_branch(struct callchain_curs + callchain_cursor_append(cursor, list->ip, + list->ms.map, list->ms.sym); + list_del(&list->list); ++ map__zput(list->ms.map); + free(list); + } + +@@ -778,7 +780,8 @@ int callchain_cursor_append(struct callc + } + + node->ip = ip; +- node->map = map; ++ map__zput(node->map); ++ node->map = map__get(map); + node->sym = sym; + + cursor->nr++; +@@ -945,11 +948,13 @@ static void free_callchain_node(struct c + + 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); + } + +@@ -1013,6 +1018,7 @@ int callchain_node__make_parent_list(str + goto out; + *new = *chain; + new->has_children = false; ++ map__get(new->ms.map); + list_add_tail(&new->list, &head); + } + parent = parent->parent; +@@ -1033,6 +1039,7 @@ int callchain_node__make_parent_list(str + out: + list_for_each_entry_safe(chain, new, &head, list) { + list_del(&chain->list); ++ map__zput(chain->ms.map); + free(chain); + } + return -ENOMEM; +--- a/tools/perf/util/callchain.h ++++ b/tools/perf/util/callchain.h +@@ -5,6 +5,7 @@ + #include + #include + #include "event.h" ++#include "map.h" + #include "symbol.h" + + #define HELP_PAD "\t\t\t\t" +@@ -174,8 +175,13 @@ int callchain_merge(struct callchain_cur + */ + 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, +--- a/tools/perf/util/hist.c ++++ b/tools/perf/util/hist.c +@@ -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_ent + 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 @@ out: + if (!err) + err = err2; + ++ map__put(alm); ++ + return err; + } + diff --git a/queue-4.9/series b/queue-4.9/series index 9b626747dad..a366a64167b 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -83,3 +83,4 @@ pci-hv-fix-wslot_to_devfn-to-fix-warnings-on-device-removal.patch pci-hotplug-pnv-php-disable-msi-and-pci-device-properly.patch pci-altera-fix-tlp_cfg_dw0-for-tlp-write.patch drivers-hv-vmbus-raise-retry-wait-limits-in-vmbus_post_msg.patch +perf-callchain-reference-count-maps.patch