diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-06 13:47:25 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-06 13:47:25 -0400 |
| commit | d8fce2db7220fc46067c825fc417fb295eac7d0a (patch) | |
| tree | 8d6f4403f4433956a02e0ed490b4f3b54005d817 | |
| parent | 02f0f5721e2c2791f57767c18a8ab94cdf48849d (diff) | |
| parent | 74f40c1f437674f5ab4a3977f1894ea6db535dee (diff) | |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar:
"Mostly tooling fixes, but also an uncore PMU driver fix and an uncore
PMU driver hardware-enablement addition"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf probe: Fix segfault if passed with ''.
perf report: Fix -T/--threads option to work again
perf bench numa: Fix immediate meeting of convergence condition
perf bench numa: Fixes of --quiet argument
perf bench futex: Fix hung wakeup tasks after requeueing
perf probe: Fix bug with global variables handling
perf top: Fix a segfault when kernel map is restricted.
tools lib traceevent: Fix build failure on 32-bit arch
perf kmem: Fix compiles on RHEL6/OL6
tools lib api: Undefine _FORTIFY_SOURCE before setting it
perf kmem: Consistently use PRIu64 for printing u64 values
perf trace: Disable events and drain events when forked workload ends
perf trace: Enable events when doing system wide tracing and starting a workload
perf/x86/intel/uncore: Move PCI IDs for IMC to uncore driver
perf/x86/intel/uncore: Add support for Intel Haswell ULT (lower power Mobile Processor) IMC uncore PMUs
perf/x86/intel: Add cpu_(prepare|starting|dying) for core_pmu
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel.c | 66 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c | 12 | ||||
| -rw-r--r-- | include/linux/pci_ids.h | 4 | ||||
| -rw-r--r-- | tools/lib/api/Makefile | 2 | ||||
| -rw-r--r-- | tools/lib/traceevent/event-parse.c | 2 | ||||
| -rw-r--r-- | tools/perf/bench/futex-requeue.c | 15 | ||||
| -rw-r--r-- | tools/perf/bench/numa.c | 12 | ||||
| -rw-r--r-- | tools/perf/builtin-kmem.c | 58 | ||||
| -rw-r--r-- | tools/perf/builtin-report.c | 2 | ||||
| -rw-r--r-- | tools/perf/builtin-top.c | 2 | ||||
| -rw-r--r-- | tools/perf/builtin-trace.c | 10 | ||||
| -rw-r--r-- | tools/perf/util/probe-event.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/probe-finder.c | 4 |
13 files changed, 114 insertions, 77 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 219d3fb423a1..960e85de13fb 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
| @@ -2533,34 +2533,6 @@ ssize_t intel_event_sysfs_show(char *page, u64 config) | |||
| 2533 | return x86_event_sysfs_show(page, config, event); | 2533 | return x86_event_sysfs_show(page, config, event); |
| 2534 | } | 2534 | } |
| 2535 | 2535 | ||
| 2536 | static __initconst const struct x86_pmu core_pmu = { | ||
| 2537 | .name = "core", | ||
| 2538 | .handle_irq = x86_pmu_handle_irq, | ||
| 2539 | .disable_all = x86_pmu_disable_all, | ||
| 2540 | .enable_all = core_pmu_enable_all, | ||
| 2541 | .enable = core_pmu_enable_event, | ||
| 2542 | .disable = x86_pmu_disable_event, | ||
| 2543 | .hw_config = x86_pmu_hw_config, | ||
| 2544 | .schedule_events = x86_schedule_events, | ||
| 2545 | .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, | ||
| 2546 | .perfctr = MSR_ARCH_PERFMON_PERFCTR0, | ||
| 2547 | .event_map = intel_pmu_event_map, | ||
| 2548 | .max_events = ARRAY_SIZE(intel_perfmon_event_map), | ||
| 2549 | .apic = 1, | ||
| 2550 | /* | ||
| 2551 | * Intel PMCs cannot be accessed sanely above 32 bit width, | ||
| 2552 | * so we install an artificial 1<<31 period regardless of | ||
| 2553 | * the generic event period: | ||
| 2554 | */ | ||
| 2555 | .max_period = (1ULL << 31) - 1, | ||
| 2556 | .get_event_constraints = intel_get_event_constraints, | ||
| 2557 | .put_event_constraints = intel_put_event_constraints, | ||
| 2558 | .event_constraints = intel_core_event_constraints, | ||
| 2559 | .guest_get_msrs = core_guest_get_msrs, | ||
| 2560 | .format_attrs = intel_arch_formats_attr, | ||
| 2561 | .events_sysfs_show = intel_event_sysfs_show, | ||
| 2562 | }; | ||
| 2563 | |||
| 2564 | struct intel_shared_regs *allocate_shared_regs(int cpu) | 2536 | struct intel_shared_regs *allocate_shared_regs(int cpu) |
| 2565 | { | 2537 | { |
| 2566 | struct intel_shared_regs *regs; | 2538 | struct intel_shared_regs *regs; |
| @@ -2743,6 +2715,44 @@ static struct attribute *intel_arch3_formats_attr[] = { | |||
| 2743 | NULL, | 2715 | NULL, |
| 2744 | }; | 2716 | }; |
| 2745 | 2717 | ||
| 2718 | static __initconst const struct x86_pmu core_pmu = { | ||
| 2719 | .name = "core", | ||
| 2720 | .handle_irq = x86_pmu_handle_irq, | ||
| 2721 | .disable_all = x86_pmu_disable_all, | ||
| 2722 | .enable_all = core_pmu_enable_all, | ||
| 2723 | .enable = core_pmu_enable_event, | ||
| 2724 | .disable = x86_pmu_disable_event, | ||
| 2725 | .hw_config = x86_pmu_hw_config, | ||
| 2726 | .schedule_events = x86_schedule_events, | ||
| 2727 | .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, | ||
| 2728 | .perfctr = MSR_ARCH_PERFMON_PERFCTR0, | ||
| 2729 | .event_map = intel_pmu_event_map, | ||
| 2730 | .max_events = ARRAY_SIZE(intel_perfmon_event_map), | ||
| 2731 | .apic = 1, | ||
| 2732 | /* | ||
| 2733 | * Intel PMCs cannot be accessed sanely above 32-bit width, | ||
| 2734 | * so we install an artificial 1<<31 period regardless of | ||
| 2735 | * the generic event period: | ||
| 2736 | */ | ||
| 2737 | .max_period = (1ULL<<31) - 1, | ||
| 2738 | .get_event_constraints = intel_get_event_constraints, | ||
| 2739 | .put_event_constraints = intel_put_event_constraints, | ||
| 2740 | .event_constraints = intel_core_event_constraints, | ||
| 2741 | .guest_get_msrs = core_guest_get_msrs, | ||
| 2742 | .format_attrs = intel_arch_formats_attr, | ||
| 2743 | .events_sysfs_show = intel_event_sysfs_show, | ||
| 2744 | |||
| 2745 | /* | ||
| 2746 | * Virtual (or funny metal) CPU can define x86_pmu.extra_regs | ||
| 2747 | * together with PMU version 1 and thus be using core_pmu with | ||
| 2748 | * shared_regs. We need following callbacks here to allocate | ||
| 2749 | * it properly. | ||
| 2750 | */ | ||
| 2751 | .cpu_prepare = intel_pmu_cpu_prepare, | ||
| 2752 | .cpu_starting = intel_pmu_cpu_starting, | ||
| 2753 | .cpu_dying = intel_pmu_cpu_dying, | ||
| 2754 | }; | ||
| 2755 | |||
| 2746 | static __initconst const struct x86_pmu intel_pmu = { | 2756 | static __initconst const struct x86_pmu intel_pmu = { |
| 2747 | .name = "Intel", | 2757 | .name = "Intel", |
| 2748 | .handle_irq = intel_pmu_handle_irq, | 2758 | .handle_irq = intel_pmu_handle_irq, |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c index 3001015b755c..4562e9e22c60 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c | |||
| @@ -1,6 +1,13 @@ | |||
| 1 | /* Nehalem/SandBridge/Haswell uncore support */ | 1 | /* Nehalem/SandBridge/Haswell uncore support */ |
| 2 | #include "perf_event_intel_uncore.h" | 2 | #include "perf_event_intel_uncore.h" |
| 3 | 3 | ||
| 4 | /* Uncore IMC PCI IDs */ | ||
| 5 | #define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100 | ||
| 6 | #define PCI_DEVICE_ID_INTEL_IVB_IMC 0x0154 | ||
| 7 | #define PCI_DEVICE_ID_INTEL_IVB_E3_IMC 0x0150 | ||
| 8 | #define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00 | ||
| 9 | #define PCI_DEVICE_ID_INTEL_HSW_U_IMC 0x0a04 | ||
| 10 | |||
| 4 | /* SNB event control */ | 11 | /* SNB event control */ |
| 5 | #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff | 12 | #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff |
| 6 | #define SNB_UNC_CTL_UMASK_MASK 0x0000ff00 | 13 | #define SNB_UNC_CTL_UMASK_MASK 0x0000ff00 |
| @@ -472,6 +479,10 @@ static const struct pci_device_id hsw_uncore_pci_ids[] = { | |||
| 472 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC), | 479 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC), |
| 473 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | 480 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), |
| 474 | }, | 481 | }, |
| 482 | { /* IMC */ | ||
| 483 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_U_IMC), | ||
| 484 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
| 485 | }, | ||
| 475 | { /* end: all zeroes */ }, | 486 | { /* end: all zeroes */ }, |
| 476 | }; | 487 | }; |
| 477 | 488 | ||
| @@ -502,6 +513,7 @@ static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = { | |||
| 502 | IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver), /* 3rd Gen Core processor */ | 513 | IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver), /* 3rd Gen Core processor */ |
| 503 | IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */ | 514 | IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */ |
| 504 | IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */ | 515 | IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */ |
| 516 | IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core ULT Mobile Processor */ | ||
| 505 | { /* end marker */ } | 517 | { /* end marker */ } |
| 506 | }; | 518 | }; |
| 507 | 519 | ||
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 38cff8f6716d..2f7b9a40f627 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -2541,10 +2541,6 @@ | |||
| 2541 | 2541 | ||
| 2542 | #define PCI_VENDOR_ID_INTEL 0x8086 | 2542 | #define PCI_VENDOR_ID_INTEL 0x8086 |
| 2543 | #define PCI_DEVICE_ID_INTEL_EESSC 0x0008 | 2543 | #define PCI_DEVICE_ID_INTEL_EESSC 0x0008 |
| 2544 | #define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100 | ||
| 2545 | #define PCI_DEVICE_ID_INTEL_IVB_IMC 0x0154 | ||
| 2546 | #define PCI_DEVICE_ID_INTEL_IVB_E3_IMC 0x0150 | ||
| 2547 | #define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00 | ||
| 2548 | #define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320 | 2544 | #define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320 |
| 2549 | #define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321 | 2545 | #define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321 |
| 2550 | #define PCI_DEVICE_ID_INTEL_PXH_0 0x0329 | 2546 | #define PCI_DEVICE_ID_INTEL_PXH_0 0x0329 |
diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index d8fe29fc19a4..8bd960658463 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile | |||
| @@ -16,7 +16,7 @@ MAKEFLAGS += --no-print-directory | |||
| 16 | LIBFILE = $(OUTPUT)libapi.a | 16 | LIBFILE = $(OUTPUT)libapi.a |
| 17 | 17 | ||
| 18 | CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) | 18 | CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) |
| 19 | CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 -fPIC | 19 | CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC |
| 20 | CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 | 20 | CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 |
| 21 | 21 | ||
| 22 | RM = rm -f | 22 | RM = rm -f |
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index e0917c0f5d9f..29f94f6f0d9e 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
| @@ -3865,7 +3865,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
| 3865 | } else if (el_size == 4) { | 3865 | } else if (el_size == 4) { |
| 3866 | trace_seq_printf(s, "%u", *(uint32_t *)num); | 3866 | trace_seq_printf(s, "%u", *(uint32_t *)num); |
| 3867 | } else if (el_size == 8) { | 3867 | } else if (el_size == 8) { |
| 3868 | trace_seq_printf(s, "%lu", *(uint64_t *)num); | 3868 | trace_seq_printf(s, "%"PRIu64, *(uint64_t *)num); |
| 3869 | } else { | 3869 | } else { |
| 3870 | trace_seq_printf(s, "BAD SIZE:%d 0x%x", | 3870 | trace_seq_printf(s, "BAD SIZE:%d 0x%x", |
| 3871 | el_size, *(uint8_t *)num); | 3871 | el_size, *(uint8_t *)num); |
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index bedff6b5b3cf..ad0d9b5342fb 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c | |||
| @@ -132,6 +132,9 @@ int bench_futex_requeue(int argc, const char **argv, | |||
| 132 | if (!fshared) | 132 | if (!fshared) |
| 133 | futex_flag = FUTEX_PRIVATE_FLAG; | 133 | futex_flag = FUTEX_PRIVATE_FLAG; |
| 134 | 134 | ||
| 135 | if (nrequeue > nthreads) | ||
| 136 | nrequeue = nthreads; | ||
| 137 | |||
| 135 | printf("Run summary [PID %d]: Requeuing %d threads (from [%s] %p to %p), " | 138 | printf("Run summary [PID %d]: Requeuing %d threads (from [%s] %p to %p), " |
| 136 | "%d at a time.\n\n", getpid(), nthreads, | 139 | "%d at a time.\n\n", getpid(), nthreads, |
| 137 | fshared ? "shared":"private", &futex1, &futex2, nrequeue); | 140 | fshared ? "shared":"private", &futex1, &futex2, nrequeue); |
| @@ -161,20 +164,18 @@ int bench_futex_requeue(int argc, const char **argv, | |||
| 161 | 164 | ||
| 162 | /* Ok, all threads are patiently blocked, start requeueing */ | 165 | /* Ok, all threads are patiently blocked, start requeueing */ |
| 163 | gettimeofday(&start, NULL); | 166 | gettimeofday(&start, NULL); |
| 164 | for (nrequeued = 0; nrequeued < nthreads; nrequeued += nrequeue) { | 167 | while (nrequeued < nthreads) { |
| 165 | /* | 168 | /* |
| 166 | * Do not wakeup any tasks blocked on futex1, allowing | 169 | * Do not wakeup any tasks blocked on futex1, allowing |
| 167 | * us to really measure futex_wait functionality. | 170 | * us to really measure futex_wait functionality. |
| 168 | */ | 171 | */ |
| 169 | futex_cmp_requeue(&futex1, 0, &futex2, 0, | 172 | nrequeued += futex_cmp_requeue(&futex1, 0, &futex2, 0, |
| 170 | nrequeue, futex_flag); | 173 | nrequeue, futex_flag); |
| 171 | } | 174 | } |
| 175 | |||
| 172 | gettimeofday(&end, NULL); | 176 | gettimeofday(&end, NULL); |
| 173 | timersub(&end, &start, &runtime); | 177 | timersub(&end, &start, &runtime); |
| 174 | 178 | ||
| 175 | if (nrequeued > nthreads) | ||
| 176 | nrequeued = nthreads; | ||
| 177 | |||
| 178 | update_stats(&requeued_stats, nrequeued); | 179 | update_stats(&requeued_stats, nrequeued); |
| 179 | update_stats(&requeuetime_stats, runtime.tv_usec); | 180 | update_stats(&requeuetime_stats, runtime.tv_usec); |
| 180 | 181 | ||
| @@ -184,7 +185,7 @@ int bench_futex_requeue(int argc, const char **argv, | |||
| 184 | } | 185 | } |
| 185 | 186 | ||
| 186 | /* everybody should be blocked on futex2, wake'em up */ | 187 | /* everybody should be blocked on futex2, wake'em up */ |
| 187 | nrequeued = futex_wake(&futex2, nthreads, futex_flag); | 188 | nrequeued = futex_wake(&futex2, nrequeued, futex_flag); |
| 188 | if (nthreads != nrequeued) | 189 | if (nthreads != nrequeued) |
| 189 | warnx("couldn't wakeup all tasks (%d/%d)", nrequeued, nthreads); | 190 | warnx("couldn't wakeup all tasks (%d/%d)", nrequeued, nthreads); |
| 190 | 191 | ||
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index ebfa163b80b5..ba5efa4710b5 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c | |||
| @@ -180,7 +180,7 @@ static const struct option options[] = { | |||
| 180 | OPT_INTEGER('H', "thp" , &p0.thp, "MADV_NOHUGEPAGE < 0 < MADV_HUGEPAGE"), | 180 | OPT_INTEGER('H', "thp" , &p0.thp, "MADV_NOHUGEPAGE < 0 < MADV_HUGEPAGE"), |
| 181 | OPT_BOOLEAN('c', "show_convergence", &p0.show_convergence, "show convergence details"), | 181 | OPT_BOOLEAN('c', "show_convergence", &p0.show_convergence, "show convergence details"), |
| 182 | OPT_BOOLEAN('m', "measure_convergence", &p0.measure_convergence, "measure convergence latency"), | 182 | OPT_BOOLEAN('m', "measure_convergence", &p0.measure_convergence, "measure convergence latency"), |
| 183 | OPT_BOOLEAN('q', "quiet" , &p0.show_quiet, "bzero the initial allocations"), | 183 | OPT_BOOLEAN('q', "quiet" , &p0.show_quiet, "quiet mode"), |
| 184 | OPT_BOOLEAN('S', "serialize-startup", &p0.serialize_startup,"serialize thread startup"), | 184 | OPT_BOOLEAN('S', "serialize-startup", &p0.serialize_startup,"serialize thread startup"), |
| 185 | 185 | ||
| 186 | /* Special option string parsing callbacks: */ | 186 | /* Special option string parsing callbacks: */ |
| @@ -828,6 +828,9 @@ static int count_process_nodes(int process_nr) | |||
| 828 | td = g->threads + task_nr; | 828 | td = g->threads + task_nr; |
| 829 | 829 | ||
| 830 | node = numa_node_of_cpu(td->curr_cpu); | 830 | node = numa_node_of_cpu(td->curr_cpu); |
| 831 | if (node < 0) /* curr_cpu was likely still -1 */ | ||
| 832 | return 0; | ||
| 833 | |||
| 831 | node_present[node] = 1; | 834 | node_present[node] = 1; |
| 832 | } | 835 | } |
| 833 | 836 | ||
| @@ -882,6 +885,11 @@ static void calc_convergence_compression(int *strong) | |||
| 882 | for (p = 0; p < g->p.nr_proc; p++) { | 885 | for (p = 0; p < g->p.nr_proc; p++) { |
| 883 | unsigned int nodes = count_process_nodes(p); | 886 | unsigned int nodes = count_process_nodes(p); |
| 884 | 887 | ||
| 888 | if (!nodes) { | ||
| 889 | *strong = 0; | ||
| 890 | return; | ||
| 891 | } | ||
| 892 | |||
| 885 | nodes_min = min(nodes, nodes_min); | 893 | nodes_min = min(nodes, nodes_min); |
| 886 | nodes_max = max(nodes, nodes_max); | 894 | nodes_max = max(nodes, nodes_max); |
| 887 | } | 895 | } |
| @@ -1395,7 +1403,7 @@ static void print_res(const char *name, double val, | |||
| 1395 | if (!name) | 1403 | if (!name) |
| 1396 | name = "main,"; | 1404 | name = "main,"; |
| 1397 | 1405 | ||
| 1398 | if (g->p.show_quiet) | 1406 | if (!g->p.show_quiet) |
| 1399 | printf(" %-30s %15.3f, %-15s %s\n", name, val, txt_unit, txt_short); | 1407 | printf(" %-30s %15.3f, %-15s %s\n", name, val, txt_unit, txt_short); |
| 1400 | else | 1408 | else |
| 1401 | printf(" %14.3f %s\n", val, txt_long); | 1409 | printf(" %14.3f %s\n", val, txt_long); |
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 63ea01349b6e..1634186d537c 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
| @@ -319,7 +319,7 @@ static int page_stat_cmp(struct page_stat *a, struct page_stat *b) | |||
| 319 | return 0; | 319 | return 0; |
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | static struct page_stat *search_page_alloc_stat(struct page_stat *stat, bool create) | 322 | static struct page_stat *search_page_alloc_stat(struct page_stat *pstat, bool create) |
| 323 | { | 323 | { |
| 324 | struct rb_node **node = &page_alloc_tree.rb_node; | 324 | struct rb_node **node = &page_alloc_tree.rb_node; |
| 325 | struct rb_node *parent = NULL; | 325 | struct rb_node *parent = NULL; |
| @@ -331,7 +331,7 @@ static struct page_stat *search_page_alloc_stat(struct page_stat *stat, bool cre | |||
| 331 | parent = *node; | 331 | parent = *node; |
| 332 | data = rb_entry(*node, struct page_stat, node); | 332 | data = rb_entry(*node, struct page_stat, node); |
| 333 | 333 | ||
| 334 | cmp = page_stat_cmp(data, stat); | 334 | cmp = page_stat_cmp(data, pstat); |
| 335 | if (cmp < 0) | 335 | if (cmp < 0) |
| 336 | node = &parent->rb_left; | 336 | node = &parent->rb_left; |
| 337 | else if (cmp > 0) | 337 | else if (cmp > 0) |
| @@ -345,10 +345,10 @@ static struct page_stat *search_page_alloc_stat(struct page_stat *stat, bool cre | |||
| 345 | 345 | ||
| 346 | data = zalloc(sizeof(*data)); | 346 | data = zalloc(sizeof(*data)); |
| 347 | if (data != NULL) { | 347 | if (data != NULL) { |
| 348 | data->page = stat->page; | 348 | data->page = pstat->page; |
| 349 | data->order = stat->order; | 349 | data->order = pstat->order; |
| 350 | data->gfp_flags = stat->gfp_flags; | 350 | data->gfp_flags = pstat->gfp_flags; |
| 351 | data->migrate_type = stat->migrate_type; | 351 | data->migrate_type = pstat->migrate_type; |
| 352 | 352 | ||
| 353 | rb_link_node(&data->node, parent, node); | 353 | rb_link_node(&data->node, parent, node); |
| 354 | rb_insert_color(&data->node, &page_alloc_tree); | 354 | rb_insert_color(&data->node, &page_alloc_tree); |
| @@ -375,7 +375,7 @@ static int perf_evsel__process_page_alloc_event(struct perf_evsel *evsel, | |||
| 375 | unsigned int migrate_type = perf_evsel__intval(evsel, sample, | 375 | unsigned int migrate_type = perf_evsel__intval(evsel, sample, |
| 376 | "migratetype"); | 376 | "migratetype"); |
| 377 | u64 bytes = kmem_page_size << order; | 377 | u64 bytes = kmem_page_size << order; |
| 378 | struct page_stat *stat; | 378 | struct page_stat *pstat; |
| 379 | struct page_stat this = { | 379 | struct page_stat this = { |
| 380 | .order = order, | 380 | .order = order, |
| 381 | .gfp_flags = gfp_flags, | 381 | .gfp_flags = gfp_flags, |
| @@ -401,21 +401,21 @@ static int perf_evsel__process_page_alloc_event(struct perf_evsel *evsel, | |||
| 401 | * This is to find the current page (with correct gfp flags and | 401 | * This is to find the current page (with correct gfp flags and |
| 402 | * migrate type) at free event. | 402 | * migrate type) at free event. |
| 403 | */ | 403 | */ |
| 404 | stat = search_page(page, true); | 404 | pstat = search_page(page, true); |
| 405 | if (stat == NULL) | 405 | if (pstat == NULL) |
| 406 | return -ENOMEM; | 406 | return -ENOMEM; |
| 407 | 407 | ||
| 408 | stat->order = order; | 408 | pstat->order = order; |
| 409 | stat->gfp_flags = gfp_flags; | 409 | pstat->gfp_flags = gfp_flags; |
| 410 | stat->migrate_type = migrate_type; | 410 | pstat->migrate_type = migrate_type; |
| 411 | 411 | ||
| 412 | this.page = page; | 412 | this.page = page; |
| 413 | stat = search_page_alloc_stat(&this, true); | 413 | pstat = search_page_alloc_stat(&this, true); |
| 414 | if (stat == NULL) | 414 | if (pstat == NULL) |
| 415 | return -ENOMEM; | 415 | return -ENOMEM; |
| 416 | 416 | ||
| 417 | stat->nr_alloc++; | 417 | pstat->nr_alloc++; |
| 418 | stat->alloc_bytes += bytes; | 418 | pstat->alloc_bytes += bytes; |
| 419 | 419 | ||
| 420 | order_stats[order][migrate_type]++; | 420 | order_stats[order][migrate_type]++; |
| 421 | 421 | ||
| @@ -428,7 +428,7 @@ static int perf_evsel__process_page_free_event(struct perf_evsel *evsel, | |||
| 428 | u64 page; | 428 | u64 page; |
| 429 | unsigned int order = perf_evsel__intval(evsel, sample, "order"); | 429 | unsigned int order = perf_evsel__intval(evsel, sample, "order"); |
| 430 | u64 bytes = kmem_page_size << order; | 430 | u64 bytes = kmem_page_size << order; |
| 431 | struct page_stat *stat; | 431 | struct page_stat *pstat; |
| 432 | struct page_stat this = { | 432 | struct page_stat this = { |
| 433 | .order = order, | 433 | .order = order, |
| 434 | }; | 434 | }; |
| @@ -441,8 +441,8 @@ static int perf_evsel__process_page_free_event(struct perf_evsel *evsel, | |||
| 441 | nr_page_frees++; | 441 | nr_page_frees++; |
| 442 | total_page_free_bytes += bytes; | 442 | total_page_free_bytes += bytes; |
| 443 | 443 | ||
| 444 | stat = search_page(page, false); | 444 | pstat = search_page(page, false); |
| 445 | if (stat == NULL) { | 445 | if (pstat == NULL) { |
| 446 | pr_debug2("missing free at page %"PRIx64" (order: %d)\n", | 446 | pr_debug2("missing free at page %"PRIx64" (order: %d)\n", |
| 447 | page, order); | 447 | page, order); |
| 448 | 448 | ||
| @@ -453,18 +453,18 @@ static int perf_evsel__process_page_free_event(struct perf_evsel *evsel, | |||
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | this.page = page; | 455 | this.page = page; |
| 456 | this.gfp_flags = stat->gfp_flags; | 456 | this.gfp_flags = pstat->gfp_flags; |
| 457 | this.migrate_type = stat->migrate_type; | 457 | this.migrate_type = pstat->migrate_type; |
| 458 | 458 | ||
| 459 | rb_erase(&stat->node, &page_tree); | 459 | rb_erase(&pstat->node, &page_tree); |
| 460 | free(stat); | 460 | free(pstat); |
| 461 | 461 | ||
| 462 | stat = search_page_alloc_stat(&this, false); | 462 | pstat = search_page_alloc_stat(&this, false); |
| 463 | if (stat == NULL) | 463 | if (pstat == NULL) |
| 464 | return -ENOENT; | 464 | return -ENOENT; |
| 465 | 465 | ||
| 466 | stat->nr_free++; | 466 | pstat->nr_free++; |
| 467 | stat->free_bytes += bytes; | 467 | pstat->free_bytes += bytes; |
| 468 | 468 | ||
| 469 | return 0; | 469 | return 0; |
| 470 | } | 470 | } |
| @@ -640,9 +640,9 @@ static void print_page_summary(void) | |||
| 640 | nr_page_frees, total_page_free_bytes / 1024); | 640 | nr_page_frees, total_page_free_bytes / 1024); |
| 641 | printf("\n"); | 641 | printf("\n"); |
| 642 | 642 | ||
| 643 | printf("%-30s: %'16lu [ %'16"PRIu64" KB ]\n", "Total alloc+freed requests", | 643 | printf("%-30s: %'16"PRIu64" [ %'16"PRIu64" KB ]\n", "Total alloc+freed requests", |
| 644 | nr_alloc_freed, (total_alloc_freed_bytes) / 1024); | 644 | nr_alloc_freed, (total_alloc_freed_bytes) / 1024); |
| 645 | printf("%-30s: %'16lu [ %'16"PRIu64" KB ]\n", "Total alloc-only requests", | 645 | printf("%-30s: %'16"PRIu64" [ %'16"PRIu64" KB ]\n", "Total alloc-only requests", |
| 646 | nr_page_allocs - nr_alloc_freed, | 646 | nr_page_allocs - nr_alloc_freed, |
| 647 | (total_page_alloc_bytes - total_alloc_freed_bytes) / 1024); | 647 | (total_page_alloc_bytes - total_alloc_freed_bytes) / 1024); |
| 648 | printf("%-30s: %'16lu [ %'16"PRIu64" KB ]\n", "Total free-only requests", | 648 | printf("%-30s: %'16lu [ %'16"PRIu64" KB ]\n", "Total free-only requests", |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 476cdf7afcca..b63aeda719be 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -329,7 +329,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, | |||
| 329 | fprintf(stdout, "\n\n"); | 329 | fprintf(stdout, "\n\n"); |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | if (sort_order == default_sort_order && | 332 | if (sort_order == NULL && |
| 333 | parent_pattern == default_parent_pattern) { | 333 | parent_pattern == default_parent_pattern) { |
| 334 | fprintf(stdout, "#\n# (%s)\n#\n", help); | 334 | fprintf(stdout, "#\n# (%s)\n#\n", help); |
| 335 | 335 | ||
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 1cb3436276d1..6a4d5d41c671 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -733,7 +733,7 @@ static void perf_event__process_sample(struct perf_tool *tool, | |||
| 733 | "Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" | 733 | "Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" |
| 734 | "Check /proc/sys/kernel/kptr_restrict.\n\n" | 734 | "Check /proc/sys/kernel/kptr_restrict.\n\n" |
| 735 | "Kernel%s samples will not be resolved.\n", | 735 | "Kernel%s samples will not be resolved.\n", |
| 736 | !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ? | 736 | al.map && !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ? |
| 737 | " modules" : ""); | 737 | " modules" : ""); |
| 738 | if (use_browser <= 0) | 738 | if (use_browser <= 0) |
| 739 | sleep(5); | 739 | sleep(5); |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index e124741be187..e122970361f2 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -2241,10 +2241,11 @@ static int trace__run(struct trace *trace, int argc, const char **argv) | |||
| 2241 | if (err < 0) | 2241 | if (err < 0) |
| 2242 | goto out_error_mmap; | 2242 | goto out_error_mmap; |
| 2243 | 2243 | ||
| 2244 | if (!target__none(&trace->opts.target)) | ||
| 2245 | perf_evlist__enable(evlist); | ||
| 2246 | |||
| 2244 | if (forks) | 2247 | if (forks) |
| 2245 | perf_evlist__start_workload(evlist); | 2248 | perf_evlist__start_workload(evlist); |
| 2246 | else | ||
| 2247 | perf_evlist__enable(evlist); | ||
| 2248 | 2249 | ||
| 2249 | trace->multiple_threads = evlist->threads->map[0] == -1 || | 2250 | trace->multiple_threads = evlist->threads->map[0] == -1 || |
| 2250 | evlist->threads->nr > 1 || | 2251 | evlist->threads->nr > 1 || |
| @@ -2272,6 +2273,11 @@ next_event: | |||
| 2272 | 2273 | ||
| 2273 | if (interrupted) | 2274 | if (interrupted) |
| 2274 | goto out_disable; | 2275 | goto out_disable; |
| 2276 | |||
| 2277 | if (done && !draining) { | ||
| 2278 | perf_evlist__disable(evlist); | ||
| 2279 | draining = true; | ||
| 2280 | } | ||
| 2275 | } | 2281 | } |
| 2276 | } | 2282 | } |
| 2277 | 2283 | ||
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index d8bb616ff57c..d05b77cf35f7 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
| @@ -1084,6 +1084,8 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) | |||
| 1084 | * | 1084 | * |
| 1085 | * TODO:Group name support | 1085 | * TODO:Group name support |
| 1086 | */ | 1086 | */ |
| 1087 | if (!arg) | ||
| 1088 | return -EINVAL; | ||
| 1087 | 1089 | ||
| 1088 | ptr = strpbrk(arg, ";=@+%"); | 1090 | ptr = strpbrk(arg, ";=@+%"); |
| 1089 | if (ptr && *ptr == '=') { /* Event name */ | 1091 | if (ptr && *ptr == '=') { /* Event name */ |
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index b5bf9d5efeaf..2a76e14db732 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
| @@ -578,10 +578,12 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf) | |||
| 578 | /* Search child die for local variables and parameters. */ | 578 | /* Search child die for local variables and parameters. */ |
| 579 | if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) { | 579 | if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) { |
| 580 | /* Search again in global variables */ | 580 | /* Search again in global variables */ |
| 581 | if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die)) | 581 | if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, |
| 582 | 0, &vr_die)) { | ||
| 582 | pr_warning("Failed to find '%s' in this function.\n", | 583 | pr_warning("Failed to find '%s' in this function.\n", |
| 583 | pf->pvar->var); | 584 | pf->pvar->var); |
| 584 | ret = -ENOENT; | 585 | ret = -ENOENT; |
| 586 | } | ||
| 585 | } | 587 | } |
| 586 | if (ret >= 0) | 588 | if (ret >= 0) |
| 587 | ret = convert_variable(&vr_die, pf); | 589 | ret = convert_variable(&vr_die, pf); |
