Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull perf fixes from Ingo Molnar:
"Tooling fixes and an Intel PMU driver fixlet"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf: Do not allow optimized switch for non-cloned events
perf/x86/intel: ignore CondChgd bit to avoid false NMI handling
perf symbols: Get kernel start address by symbol name
perf tools: Fix segfault in cumulative.callchain report

+48 -38
+9
arch/x86/kernel/cpu/perf_event_intel.c
··· 1382 1382 intel_pmu_lbr_read(); 1383 1383 1384 1384 /* 1385 + * CondChgd bit 63 doesn't mean any overflow status. Ignore 1386 + * and clear the bit. 1387 + */ 1388 + if (__test_and_clear_bit(63, (unsigned long *)&status)) { 1389 + if (!status) 1390 + goto done; 1391 + } 1392 + 1393 + /* 1385 1394 * PEBS overflow sets bit 62 in the global status register 1386 1395 */ 1387 1396 if (__test_and_clear_bit(62, (unsigned long *)&status)) {
+1 -1
kernel/events/core.c
··· 2320 2320 next_parent = rcu_dereference(next_ctx->parent_ctx); 2321 2321 2322 2322 /* If neither context have a parent context; they cannot be clones. */ 2323 - if (!parent && !next_parent) 2323 + if (!parent || !next_parent) 2324 2324 goto unlock; 2325 2325 2326 2326 if (next_parent == ctx || next_ctx == parent || next_parent == parent) {
+16 -5
tools/perf/ui/browsers/hists.c
··· 17 17 #include "../util.h" 18 18 #include "../ui.h" 19 19 #include "map.h" 20 + #include "annotate.h" 20 21 21 22 struct hist_browser { 22 23 struct ui_browser b; ··· 1594 1593 bi->to.sym->name) > 0) 1595 1594 annotate_t = nr_options++; 1596 1595 } else { 1597 - 1598 1596 if (browser->selection != NULL && 1599 1597 browser->selection->sym != NULL && 1600 - !browser->selection->map->dso->annotate_warned && 1601 - asprintf(&options[nr_options], "Annotate %s", 1602 - browser->selection->sym->name) > 0) 1603 - annotate = nr_options++; 1598 + !browser->selection->map->dso->annotate_warned) { 1599 + struct annotation *notes; 1600 + 1601 + notes = symbol__annotation(browser->selection->sym); 1602 + 1603 + if (notes->src && 1604 + asprintf(&options[nr_options], "Annotate %s", 1605 + browser->selection->sym->name) > 0) 1606 + annotate = nr_options++; 1607 + } 1604 1608 } 1605 1609 1606 1610 if (thread != NULL && ··· 1662 1656 1663 1657 if (choice == annotate || choice == annotate_t || choice == annotate_f) { 1664 1658 struct hist_entry *he; 1659 + struct annotation *notes; 1665 1660 int err; 1666 1661 do_annotate: 1667 1662 if (!objdump_path && perf_session_env__lookup_objdump(env)) ··· 1685 1678 he->ms.sym = he->branch_info->to.sym; 1686 1679 he->ms.map = he->branch_info->to.map; 1687 1680 } 1681 + 1682 + notes = symbol__annotation(he->ms.sym); 1683 + if (!notes->src) 1684 + continue; 1688 1685 1689 1686 /* 1690 1687 * Don't let this be freed, say, by hists__decay_entry.
+22 -32
tools/perf/util/machine.c
··· 496 496 u64 start; 497 497 }; 498 498 499 - static int symbol__in_kernel(void *arg, const char *name, 500 - char type __maybe_unused, u64 start) 501 - { 502 - struct process_args *args = arg; 503 - 504 - if (strchr(name, '[')) 505 - return 0; 506 - 507 - args->start = start; 508 - return 1; 509 - } 510 - 511 499 static void machine__get_kallsyms_filename(struct machine *machine, char *buf, 512 500 size_t bufsz) 513 501 { ··· 505 517 scnprintf(buf, bufsz, "%s/proc/kallsyms", machine->root_dir); 506 518 } 507 519 508 - /* Figure out the start address of kernel map from /proc/kallsyms */ 509 - static u64 machine__get_kernel_start_addr(struct machine *machine) 520 + const char *ref_reloc_sym_names[] = {"_text", "_stext", NULL}; 521 + 522 + /* Figure out the start address of kernel map from /proc/kallsyms. 523 + * Returns the name of the start symbol in *symbol_name. Pass in NULL as 524 + * symbol_name if it's not that important. 525 + */ 526 + static u64 machine__get_kernel_start_addr(struct machine *machine, 527 + const char **symbol_name) 510 528 { 511 529 char filename[PATH_MAX]; 512 - struct process_args args; 530 + int i; 531 + const char *name; 532 + u64 addr = 0; 513 533 514 534 machine__get_kallsyms_filename(machine, filename, PATH_MAX); 515 535 516 536 if (symbol__restricted_filename(filename, "/proc/kallsyms")) 517 537 return 0; 518 538 519 - if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) 520 - return 0; 539 + for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) { 540 + addr = kallsyms__get_function_start(filename, name); 541 + if (addr) 542 + break; 543 + } 521 544 522 - return args.start; 545 + if (symbol_name) 546 + *symbol_name = name; 547 + 548 + return addr; 523 549 } 524 550 525 551 int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel) 526 552 { 527 553 enum map_type type; 528 - u64 start = machine__get_kernel_start_addr(machine); 554 + u64 start = machine__get_kernel_start_addr(machine, NULL); 529 555 530 556 for (type = 0; type < MAP__NR_TYPES; ++type) { 531 557 struct kmap *kmap; ··· 854 852 return 0; 855 853 } 856 854 857 - const char *ref_reloc_sym_names[] = {"_text", "_stext", NULL}; 858 - 859 855 int machine__create_kernel_maps(struct machine *machine) 860 856 { 861 857 struct dso *kernel = machine__get_kernel(machine); 862 - char filename[PATH_MAX]; 863 858 const char *name; 864 - u64 addr = 0; 865 - int i; 866 - 867 - machine__get_kallsyms_filename(machine, filename, PATH_MAX); 868 - 869 - for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) { 870 - addr = kallsyms__get_function_start(filename, name); 871 - if (addr) 872 - break; 873 - } 859 + u64 addr = machine__get_kernel_start_addr(machine, &name); 874 860 if (!addr) 875 861 return -1; 876 862