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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'perf-tools-fixes-for-v6.0-2022-09-08' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

Pull perf tools fixes from Arnaldo Carvalho de Melo:

- Fix per-thread mmaps for multi-threaded targets, noticed with
'perf top --pid' with multithreaded targets

- Fix synthesis failure warnings in 'perf record'

- Fix L2 Topdown metrics disappearance for raw events in 'perf stat'

- Fix out of bound access in some CPU masks

- Fix segfault if there is no CPU PMU table and a metric is sought,
noticed when building with NO_JEVENTS=1

- Skip dummy event attr check in 'perf script' fixing nonsensical
warning about UREGS attribute not set, as 'dummy' events have no
samples

- Fix 'iregs' field handling with dummy events on hybrid systems in
'perf script'

- Prevent potential memory leak in c2c_he_zalloc() in 'perf c2c'

- Don't install data files with x permissions

- Fix types for print format in dlfilter-show-cycles

- Switch deprecated openssl MD5_* functions to new EVP API in 'genelf'

- Remove redundant word 'contention' in 'perf lock' help message

* tag 'perf-tools-fixes-for-v6.0-2022-09-08' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux:
perf record: Fix synthesis failure warnings
perf tools: Don't install data files with x permissions
perf script: Fix Cannot print 'iregs' field for hybrid systems
perf lock: Remove redundant word 'contention' in help message
perf dlfilter dlfilter-show-cycles: Fix types for print format
libperf evlist: Fix per-thread mmaps for multi-threaded targets
perf c2c: Prevent potential memory leak in c2c_he_zalloc()
perf genelf: Switch deprecated openssl MD5_* functions to new EVP API
tools/perf: Fix out of bound access to cpu mask array
perf affinity: Fix out of bound access to "sched_cpus" mask
perf stat: Fix L2 Topdown metrics disappear for raw events
perf script: Skip dummy event attr check
perf metric: Return early if no CPU PMU table exists

+129 -39
+50
tools/lib/perf/evlist.c
··· 486 486 if (ops->idx) 487 487 ops->idx(evlist, evsel, mp, idx); 488 488 489 + pr_debug("idx %d: mmapping fd %d\n", idx, *output); 489 490 if (ops->mmap(map, mp, *output, evlist_cpu) < 0) 490 491 return -1; 491 492 ··· 495 494 if (!idx) 496 495 perf_evlist__set_mmap_first(evlist, map, overwrite); 497 496 } else { 497 + pr_debug("idx %d: set output fd %d -> %d\n", idx, fd, *output); 498 498 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0) 499 499 return -1; 500 500 ··· 522 520 } 523 521 524 522 static int 523 + mmap_per_thread(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, 524 + struct perf_mmap_param *mp) 525 + { 526 + int nr_threads = perf_thread_map__nr(evlist->threads); 527 + int nr_cpus = perf_cpu_map__nr(evlist->all_cpus); 528 + int cpu, thread, idx = 0; 529 + int nr_mmaps = 0; 530 + 531 + pr_debug("%s: nr cpu values (may include -1) %d nr threads %d\n", 532 + __func__, nr_cpus, nr_threads); 533 + 534 + /* per-thread mmaps */ 535 + for (thread = 0; thread < nr_threads; thread++, idx++) { 536 + int output = -1; 537 + int output_overwrite = -1; 538 + 539 + if (mmap_per_evsel(evlist, ops, idx, mp, 0, thread, &output, 540 + &output_overwrite, &nr_mmaps)) 541 + goto out_unmap; 542 + } 543 + 544 + /* system-wide mmaps i.e. per-cpu */ 545 + for (cpu = 1; cpu < nr_cpus; cpu++, idx++) { 546 + int output = -1; 547 + int output_overwrite = -1; 548 + 549 + if (mmap_per_evsel(evlist, ops, idx, mp, cpu, 0, &output, 550 + &output_overwrite, &nr_mmaps)) 551 + goto out_unmap; 552 + } 553 + 554 + if (nr_mmaps != evlist->nr_mmaps) 555 + pr_err("Miscounted nr_mmaps %d vs %d\n", nr_mmaps, evlist->nr_mmaps); 556 + 557 + return 0; 558 + 559 + out_unmap: 560 + perf_evlist__munmap(evlist); 561 + return -1; 562 + } 563 + 564 + static int 525 565 mmap_per_cpu(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, 526 566 struct perf_mmap_param *mp) 527 567 { ··· 571 527 int nr_cpus = perf_cpu_map__nr(evlist->all_cpus); 572 528 int nr_mmaps = 0; 573 529 int cpu, thread; 530 + 531 + pr_debug("%s: nr cpu values %d nr threads %d\n", __func__, nr_cpus, nr_threads); 574 532 575 533 for (cpu = 0; cpu < nr_cpus; cpu++) { 576 534 int output = -1; ··· 615 569 struct perf_evlist_mmap_ops *ops, 616 570 struct perf_mmap_param *mp) 617 571 { 572 + const struct perf_cpu_map *cpus = evlist->all_cpus; 618 573 struct perf_evsel *evsel; 619 574 620 575 if (!ops || !ops->get || !ops->mmap) ··· 634 587 635 588 if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) 636 589 return -ENOMEM; 590 + 591 + if (perf_cpu_map__empty(cpus)) 592 + return mmap_per_thread(evlist, ops, mp); 637 593 638 594 return mmap_per_cpu(evlist, ops, mp); 639 595 }
+12 -12
tools/perf/Makefile.perf
··· 954 954 $(call QUIET_INSTALL, bpf-headers) \ 955 955 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \ 956 956 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf/linux'; \ 957 - $(INSTALL) include/bpf/*.h -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \ 958 - $(INSTALL) include/bpf/linux/*.h -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf/linux' 957 + $(INSTALL) include/bpf/*.h -m 644 -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \ 958 + $(INSTALL) include/bpf/linux/*.h -m 644 -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf/linux' 959 959 $(call QUIET_INSTALL, bpf-examples) \ 960 960 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'; \ 961 - $(INSTALL) examples/bpf/*.c -t '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf' 961 + $(INSTALL) examples/bpf/*.c -m 644 -t '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf' 962 962 endif 963 963 $(call QUIET_INSTALL, perf-archive) \ 964 964 $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' ··· 967 967 ifndef NO_LIBAUDIT 968 968 $(call QUIET_INSTALL, strace/groups) \ 969 969 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'; \ 970 - $(INSTALL) trace/strace/groups/* -t '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)' 970 + $(INSTALL) trace/strace/groups/* -m 644 -t '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)' 971 971 endif 972 972 ifndef NO_LIBPERL 973 973 $(call QUIET_INSTALL, perl-scripts) \ 974 974 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \ 975 - $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \ 976 - $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'; \ 975 + $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -m 644 -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \ 976 + $(INSTALL) scripts/perl/*.pl -m 644 -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'; \ 977 977 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'; \ 978 978 $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin' 979 979 endif ··· 990 990 $(INSTALL) $(DLFILTERS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/dlfilters'; 991 991 $(call QUIET_INSTALL, perf_completion-script) \ 992 992 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'; \ 993 - $(INSTALL) perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf' 993 + $(INSTALL) perf-completion.sh -m 644 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf' 994 994 $(call QUIET_INSTALL, perf-tip) \ 995 995 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(tip_instdir_SQ)'; \ 996 - $(INSTALL) Documentation/tips.txt -t '$(DESTDIR_SQ)$(tip_instdir_SQ)' 996 + $(INSTALL) Documentation/tips.txt -m 644 -t '$(DESTDIR_SQ)$(tip_instdir_SQ)' 997 997 998 998 install-tests: all install-gtk 999 999 $(call QUIET_INSTALL, tests) \ 1000 1000 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ 1001 - $(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ 1001 + $(INSTALL) tests/attr.py -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ 1002 1002 $(INSTALL) tests/pe-file.exe* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ 1003 1003 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ 1004 - $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ 1004 + $(INSTALL) tests/attr/* -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ 1005 1005 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ 1006 1006 $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ 1007 1007 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ 1008 - $(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ 1009 - $(INSTALL) tests/shell/lib/*.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib' 1008 + $(INSTALL) tests/shell/lib/*.sh -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ 1009 + $(INSTALL) tests/shell/lib/*.py -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib' 1010 1010 1011 1011 install-bin: install-tools install-tests install-traceevent-plugins 1012 1012
+9 -3
tools/perf/builtin-c2c.c
··· 146 146 147 147 c2c_he->cpuset = bitmap_zalloc(c2c.cpus_cnt); 148 148 if (!c2c_he->cpuset) 149 - return NULL; 149 + goto out_free; 150 150 151 151 c2c_he->nodeset = bitmap_zalloc(c2c.nodes_cnt); 152 152 if (!c2c_he->nodeset) 153 - return NULL; 153 + goto out_free; 154 154 155 155 c2c_he->node_stats = zalloc(c2c.nodes_cnt * sizeof(*c2c_he->node_stats)); 156 156 if (!c2c_he->node_stats) 157 - return NULL; 157 + goto out_free; 158 158 159 159 init_stats(&c2c_he->cstats.lcl_hitm); 160 160 init_stats(&c2c_he->cstats.rmt_hitm); ··· 163 163 init_stats(&c2c_he->cstats.load); 164 164 165 165 return &c2c_he->he; 166 + 167 + out_free: 168 + free(c2c_he->nodeset); 169 + free(c2c_he->cpuset); 170 + free(c2c_he); 171 + return NULL; 166 172 } 167 173 168 174 static void c2c_he_free(void *he)
+1 -2
tools/perf/builtin-lock.c
··· 1874 1874 NULL 1875 1875 }; 1876 1876 const char *const lock_subcommands[] = { "record", "report", "script", 1877 - "info", "contention", 1878 - "contention", NULL }; 1877 + "info", "contention", NULL }; 1879 1878 const char *lock_usage[] = { 1880 1879 NULL, 1881 1880 NULL
+26 -8
tools/perf/builtin-record.c
··· 1906 1906 1907 1907 err = perf_event__synthesize_bpf_events(session, process_synthesized_event, 1908 1908 machine, opts); 1909 - if (err < 0) 1909 + if (err < 0) { 1910 1910 pr_warning("Couldn't synthesize bpf events.\n"); 1911 + err = 0; 1912 + } 1911 1913 1912 1914 if (rec->opts.synth & PERF_SYNTH_CGROUP) { 1913 1915 err = perf_event__synthesize_cgroups(tool, process_synthesized_event, 1914 1916 machine); 1915 - if (err < 0) 1917 + if (err < 0) { 1916 1918 pr_warning("Couldn't synthesize cgroup events.\n"); 1919 + err = 0; 1920 + } 1917 1921 } 1918 1922 1919 1923 if (rec->opts.nr_threads_synthesize > 1) { ··· 3362 3358 3363 3359 struct option *record_options = __record_options; 3364 3360 3365 - static void record__mmap_cpu_mask_init(struct mmap_cpu_mask *mask, struct perf_cpu_map *cpus) 3361 + static int record__mmap_cpu_mask_init(struct mmap_cpu_mask *mask, struct perf_cpu_map *cpus) 3366 3362 { 3367 3363 struct perf_cpu cpu; 3368 3364 int idx; 3369 3365 3370 3366 if (cpu_map__is_dummy(cpus)) 3371 - return; 3367 + return 0; 3372 3368 3373 - perf_cpu_map__for_each_cpu(cpu, idx, cpus) 3369 + perf_cpu_map__for_each_cpu(cpu, idx, cpus) { 3370 + /* Return ENODEV is input cpu is greater than max cpu */ 3371 + if ((unsigned long)cpu.cpu > mask->nbits) 3372 + return -ENODEV; 3374 3373 set_bit(cpu.cpu, mask->bits); 3374 + } 3375 + 3376 + return 0; 3375 3377 } 3376 3378 3377 3379 static int record__mmap_cpu_mask_init_spec(struct mmap_cpu_mask *mask, const char *mask_spec) ··· 3389 3379 return -ENOMEM; 3390 3380 3391 3381 bitmap_zero(mask->bits, mask->nbits); 3392 - record__mmap_cpu_mask_init(mask, cpus); 3382 + if (record__mmap_cpu_mask_init(mask, cpus)) 3383 + return -ENODEV; 3384 + 3393 3385 perf_cpu_map__put(cpus); 3394 3386 3395 3387 return 0; ··· 3473 3461 pr_err("Failed to allocate CPUs mask\n"); 3474 3462 return ret; 3475 3463 } 3476 - record__mmap_cpu_mask_init(&cpus_mask, cpus); 3464 + 3465 + ret = record__mmap_cpu_mask_init(&cpus_mask, cpus); 3466 + if (ret) { 3467 + pr_err("Failed to init cpu mask\n"); 3468 + goto out_free_cpu_mask; 3469 + } 3477 3470 3478 3471 ret = record__thread_mask_alloc(&full_mask, cpu__max_cpu().cpu); 3479 3472 if (ret) { ··· 3719 3702 if (ret) 3720 3703 return ret; 3721 3704 3722 - record__mmap_cpu_mask_init(&rec->thread_masks->maps, cpus); 3705 + if (record__mmap_cpu_mask_init(&rec->thread_masks->maps, cpus)) 3706 + return -ENODEV; 3723 3707 3724 3708 rec->nr_threads = 1; 3725 3709
+5
tools/perf/builtin-script.c
··· 445 445 struct perf_event_attr *attr = &evsel->core.attr; 446 446 bool allow_user_set; 447 447 448 + if (evsel__is_dummy_event(evsel)) 449 + return 0; 450 + 448 451 if (perf_header__has_feat(&session->header, HEADER_STAT)) 449 452 return 0; 450 453 ··· 569 566 struct evsel *evsel; 570 567 571 568 evlist__for_each_entry(evlist, evsel) { 569 + if (evsel__is_dummy_event(evsel)) 570 + continue; 572 571 if (output_type(evsel->core.attr.type) == (int)type) 573 572 return evsel; 574 573 }
+3 -2
tools/perf/builtin-stat.c
··· 1932 1932 free(str); 1933 1933 } 1934 1934 1935 + if (!stat_config.topdown_level) 1936 + stat_config.topdown_level = TOPDOWN_MAX_LEVEL; 1937 + 1935 1938 if (!evsel_list->core.nr_entries) { 1936 1939 if (target__has_cpu(&target)) 1937 1940 default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK; ··· 1951 1948 } 1952 1949 if (evlist__add_default_attrs(evsel_list, default_attrs1) < 0) 1953 1950 return -1; 1954 - 1955 - stat_config.topdown_level = TOPDOWN_MAX_LEVEL; 1956 1951 /* Platform specific attrs */ 1957 1952 if (evlist__add_default_attrs(evsel_list, default_null_attrs) < 0) 1958 1953 return -1;
+2 -2
tools/perf/dlfilters/dlfilter-show-cycles.c
··· 98 98 static void print_vals(__u64 cycles, __u64 delta) 99 99 { 100 100 if (delta) 101 - printf("%10llu %10llu ", cycles, delta); 101 + printf("%10llu %10llu ", (unsigned long long)cycles, (unsigned long long)delta); 102 102 else 103 - printf("%10llu %10s ", cycles, ""); 103 + printf("%10llu %10s ", (unsigned long long)cycles, ""); 104 104 } 105 105 106 106 int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx)
+7 -1
tools/perf/util/affinity.c
··· 49 49 { 50 50 int cpu_set_size = get_cpu_set_size(); 51 51 52 - if (cpu == -1) 52 + /* 53 + * Return: 54 + * - if cpu is -1 55 + * - restrict out of bound access to sched_cpus 56 + */ 57 + if (cpu == -1 || ((cpu >= (cpu_set_size * 8)))) 53 58 return; 59 + 54 60 a->changed = true; 55 61 set_bit(cpu, a->sched_cpus); 56 62 /*
+11 -9
tools/perf/util/genelf.c
··· 30 30 31 31 #define BUILD_ID_URANDOM /* different uuid for each run */ 32 32 33 - // FIXME, remove this and fix the deprecation warnings before its removed and 34 - // We'll break for good here... 35 - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 36 - 37 33 #ifdef HAVE_LIBCRYPTO_SUPPORT 38 34 39 35 #define BUILD_ID_MD5 ··· 41 45 #endif 42 46 43 47 #ifdef BUILD_ID_MD5 48 + #include <openssl/evp.h> 44 49 #include <openssl/md5.h> 45 50 #endif 46 51 #endif ··· 139 142 static void 140 143 gen_build_id(struct buildid_note *note, unsigned long load_addr, const void *code, size_t csize) 141 144 { 142 - MD5_CTX context; 145 + EVP_MD_CTX *mdctx; 143 146 144 147 if (sizeof(note->build_id) < 16) 145 148 errx(1, "build_id too small for MD5"); 146 149 147 - MD5_Init(&context); 148 - MD5_Update(&context, &load_addr, sizeof(load_addr)); 149 - MD5_Update(&context, code, csize); 150 - MD5_Final((unsigned char *)note->build_id, &context); 150 + mdctx = EVP_MD_CTX_new(); 151 + if (!mdctx) 152 + errx(2, "failed to create EVP_MD_CTX"); 153 + 154 + EVP_DigestInit_ex(mdctx, EVP_md5(), NULL); 155 + EVP_DigestUpdate(mdctx, &load_addr, sizeof(load_addr)); 156 + EVP_DigestUpdate(mdctx, code, csize); 157 + EVP_DigestFinal_ex(mdctx, (unsigned char *)note->build_id, NULL); 158 + EVP_MD_CTX_free(mdctx); 151 159 } 152 160 #endif 153 161
+3
tools/perf/util/metricgroup.c
··· 1655 1655 struct evlist *perf_evlist = *(struct evlist **)opt->value; 1656 1656 const struct pmu_events_table *table = pmu_events_table__find(); 1657 1657 1658 + if (!table) 1659 + return -EINVAL; 1660 + 1658 1661 return parse_groups(perf_evlist, str, metric_no_group, 1659 1662 metric_no_merge, NULL, metric_events, table); 1660 1663 }