Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
"A kernel crash fix plus three tooling fixes"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/core: Fix crash in perf_event_read()
perf callchain: Reference count maps
perf diff: Fix -o/--order option behavior (again)
perf diff: Fix segfault on 'perf diff -o N' option

Changed files
+55 -13
kernel
events
tools
+15 -10
kernel/events/core.c
··· 3487 3487 int ret; 3488 3488 }; 3489 3489 3490 - static int find_cpu_to_read(struct perf_event *event, int local_cpu) 3490 + static int __perf_event_read_cpu(struct perf_event *event, int event_cpu) 3491 3491 { 3492 - int event_cpu = event->oncpu; 3493 3492 u16 local_pkg, event_pkg; 3494 3493 3495 3494 if (event->group_caps & PERF_EV_CAP_READ_ACTIVE_PKG) { 3496 - event_pkg = topology_physical_package_id(event_cpu); 3497 - local_pkg = topology_physical_package_id(local_cpu); 3495 + int local_cpu = smp_processor_id(); 3496 + 3497 + event_pkg = topology_physical_package_id(event_cpu); 3498 + local_pkg = topology_physical_package_id(local_cpu); 3498 3499 3499 3500 if (event_pkg == local_pkg) 3500 3501 return local_cpu; ··· 3625 3624 3626 3625 static int perf_event_read(struct perf_event *event, bool group) 3627 3626 { 3628 - int ret = 0, cpu_to_read, local_cpu; 3627 + int event_cpu, ret = 0; 3629 3628 3630 3629 /* 3631 3630 * If event is enabled and currently active on a CPU, update the ··· 3638 3637 .ret = 0, 3639 3638 }; 3640 3639 3641 - local_cpu = get_cpu(); 3642 - cpu_to_read = find_cpu_to_read(event, local_cpu); 3643 - put_cpu(); 3640 + event_cpu = READ_ONCE(event->oncpu); 3641 + if ((unsigned)event_cpu >= nr_cpu_ids) 3642 + return 0; 3643 + 3644 + preempt_disable(); 3645 + event_cpu = __perf_event_read_cpu(event, event_cpu); 3644 3646 3645 3647 /* 3646 3648 * Purposely ignore the smp_call_function_single() return 3647 3649 * value. 3648 3650 * 3649 - * If event->oncpu isn't a valid CPU it means the event got 3651 + * If event_cpu isn't a valid CPU it means the event got 3650 3652 * scheduled out and that will have updated the event count. 3651 3653 * 3652 3654 * Therefore, either way, we'll have an up-to-date event count 3653 3655 * after this. 3654 3656 */ 3655 - (void)smp_call_function_single(cpu_to_read, __perf_event_read, &data, 1); 3657 + (void)smp_call_function_single(event_cpu, __perf_event_read, &data, 1); 3658 + preempt_enable(); 3656 3659 ret = data.ret; 3657 3660 } else if (event->state == PERF_EVENT_STATE_INACTIVE) { 3658 3661 struct perf_event_context *ctx = event->ctx;
+1 -1
tools/perf/builtin-diff.c
··· 1199 1199 BUG_ON(1); 1200 1200 } 1201 1201 1202 - perf_hpp__register_sort_field(fmt); 1202 + perf_hpp__prepend_sort_field(fmt); 1203 1203 return 0; 1204 1204 } 1205 1205
+10
tools/perf/ui/hist.c
··· 521 521 list_add_tail(&format->sort_list, &list->sorts); 522 522 } 523 523 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 + 524 530 void perf_hpp__column_unregister(struct perf_hpp_fmt *format) 525 531 { 526 532 list_del(&format->list); ··· 565 559 /* append sort keys to output field */ 566 560 perf_hpp_list__for_each_sort_list(list, fmt) { 567 561 struct perf_hpp_fmt *pos; 562 + 563 + /* skip sort-only fields ("sort_compute" in perf diff) */ 564 + if (!fmt->entry && !fmt->color) 565 + continue; 568 566 569 567 perf_hpp_list__for_each_format(list, pos) { 570 568 if (fmt_equal(fmt, pos))
+9 -2
tools/perf/util/callchain.c
··· 437 437 } 438 438 call->ip = cursor_node->ip; 439 439 call->ms.sym = cursor_node->sym; 440 - call->ms.map = cursor_node->map; 440 + call->ms.map = map__get(cursor_node->map); 441 441 442 442 if (cursor_node->branch) { 443 443 call->branch_count = 1; ··· 477 477 478 478 list_for_each_entry_safe(call, tmp, &new->val, list) { 479 479 list_del(&call->list); 480 + map__zput(call->ms.map); 480 481 free(call); 481 482 } 482 483 free(new); ··· 762 761 list->ms.map, list->ms.sym, 763 762 false, NULL, 0, 0); 764 763 list_del(&list->list); 764 + map__zput(list->ms.map); 765 765 free(list); 766 766 } 767 767 ··· 813 811 } 814 812 815 813 node->ip = ip; 816 - node->map = map; 814 + map__zput(node->map); 815 + node->map = map__get(map); 817 816 node->sym = sym; 818 817 node->branch = branch; 819 818 node->nr_loop_iter = nr_loop_iter; ··· 1145 1142 1146 1143 list_for_each_entry_safe(list, tmp, &node->parent_val, list) { 1147 1144 list_del(&list->list); 1145 + map__zput(list->ms.map); 1148 1146 free(list); 1149 1147 } 1150 1148 1151 1149 list_for_each_entry_safe(list, tmp, &node->val, list) { 1152 1150 list_del(&list->list); 1151 + map__zput(list->ms.map); 1153 1152 free(list); 1154 1153 } 1155 1154 ··· 1215 1210 goto out; 1216 1211 *new = *chain; 1217 1212 new->has_children = false; 1213 + map__get(new->ms.map); 1218 1214 list_add_tail(&new->list, &head); 1219 1215 } 1220 1216 parent = parent->parent; ··· 1236 1230 out: 1237 1231 list_for_each_entry_safe(chain, new, &head, list) { 1238 1232 list_del(&chain->list); 1233 + map__zput(chain->ms.map); 1239 1234 free(chain); 1240 1235 } 1241 1236 return -ENOMEM;
+6
tools/perf/util/callchain.h
··· 5 5 #include <linux/list.h> 6 6 #include <linux/rbtree.h> 7 7 #include "event.h" 8 + #include "map.h" 8 9 #include "symbol.h" 9 10 10 11 #define HELP_PAD "\t\t\t\t" ··· 185 184 */ 186 185 static inline void callchain_cursor_reset(struct callchain_cursor *cursor) 187 186 { 187 + struct callchain_cursor_node *node; 188 + 188 189 cursor->nr = 0; 189 190 cursor->last = &cursor->first; 191 + 192 + for (node = cursor->first; node != NULL; node = node->next) 193 + map__zput(node->map); 190 194 } 191 195 192 196 int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
+7
tools/perf/util/hist.c
··· 1 1 #include "util.h" 2 2 #include "build-id.h" 3 3 #include "hist.h" 4 + #include "map.h" 4 5 #include "session.h" 5 6 #include "sort.h" 6 7 #include "evlist.h" ··· 1020 1019 int max_stack_depth, void *arg) 1021 1020 { 1022 1021 int err, err2; 1022 + struct map *alm = NULL; 1023 + 1024 + if (al && al->map) 1025 + alm = map__get(al->map); 1023 1026 1024 1027 err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent, 1025 1028 iter->evsel, al, max_stack_depth); ··· 1062 1057 err2 = iter->ops->finish_entry(iter, al); 1063 1058 if (!err) 1064 1059 err = err2; 1060 + 1061 + map__put(alm); 1065 1062 1066 1063 return err; 1067 1064 }
+7
tools/perf/util/hist.h
··· 283 283 struct perf_hpp_fmt *format); 284 284 void perf_hpp_list__register_sort_field(struct perf_hpp_list *list, 285 285 struct perf_hpp_fmt *format); 286 + void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list, 287 + struct perf_hpp_fmt *format); 286 288 287 289 static inline void perf_hpp__column_register(struct perf_hpp_fmt *format) 288 290 { ··· 294 292 static inline void perf_hpp__register_sort_field(struct perf_hpp_fmt *format) 295 293 { 296 294 perf_hpp_list__register_sort_field(&perf_hpp_list, format); 295 + } 296 + 297 + static inline void perf_hpp__prepend_sort_field(struct perf_hpp_fmt *format) 298 + { 299 + perf_hpp_list__prepend_sort_field(&perf_hpp_list, format); 297 300 } 298 301 299 302 #define perf_hpp_list__for_each_format(_list, format) \