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:
"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

+114 -77
+38 -28
arch/x86/kernel/cpu/perf_event_intel.c
··· 2533 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 2536 struct intel_shared_regs *allocate_shared_regs(int cpu) 2565 2537 { 2566 2538 struct intel_shared_regs *regs; ··· 2713 2741 &format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */ 2714 2742 &format_attr_ldlat.attr, /* PEBS load latency */ 2715 2743 NULL, 2744 + }; 2745 + 2746 + static __initconst const struct x86_pmu core_pmu = { 2747 + .name = "core", 2748 + .handle_irq = x86_pmu_handle_irq, 2749 + .disable_all = x86_pmu_disable_all, 2750 + .enable_all = core_pmu_enable_all, 2751 + .enable = core_pmu_enable_event, 2752 + .disable = x86_pmu_disable_event, 2753 + .hw_config = x86_pmu_hw_config, 2754 + .schedule_events = x86_schedule_events, 2755 + .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, 2756 + .perfctr = MSR_ARCH_PERFMON_PERFCTR0, 2757 + .event_map = intel_pmu_event_map, 2758 + .max_events = ARRAY_SIZE(intel_perfmon_event_map), 2759 + .apic = 1, 2760 + /* 2761 + * Intel PMCs cannot be accessed sanely above 32-bit width, 2762 + * so we install an artificial 1<<31 period regardless of 2763 + * the generic event period: 2764 + */ 2765 + .max_period = (1ULL<<31) - 1, 2766 + .get_event_constraints = intel_get_event_constraints, 2767 + .put_event_constraints = intel_put_event_constraints, 2768 + .event_constraints = intel_core_event_constraints, 2769 + .guest_get_msrs = core_guest_get_msrs, 2770 + .format_attrs = intel_arch_formats_attr, 2771 + .events_sysfs_show = intel_event_sysfs_show, 2772 + 2773 + /* 2774 + * Virtual (or funny metal) CPU can define x86_pmu.extra_regs 2775 + * together with PMU version 1 and thus be using core_pmu with 2776 + * shared_regs. We need following callbacks here to allocate 2777 + * it properly. 2778 + */ 2779 + .cpu_prepare = intel_pmu_cpu_prepare, 2780 + .cpu_starting = intel_pmu_cpu_starting, 2781 + .cpu_dying = intel_pmu_cpu_dying, 2716 2782 }; 2717 2783 2718 2784 static __initconst const struct x86_pmu intel_pmu = {
+12
arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c
··· 1 1 /* Nehalem/SandBridge/Haswell uncore support */ 2 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 11 /* SNB event control */ 5 12 #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff 6 13 #define SNB_UNC_CTL_UMASK_MASK 0x0000ff00 ··· 479 472 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC), 480 473 .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), 481 474 }, 475 + { /* IMC */ 476 + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_U_IMC), 477 + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), 478 + }, 482 479 { /* end: all zeroes */ }, 483 480 }; 484 481 ··· 513 502 IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver), /* 3rd Gen Core processor */ 514 503 IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */ 515 504 IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */ 505 + IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core ULT Mobile Processor */ 516 506 { /* end marker */ } 517 507 }; 518 508
-4
include/linux/pci_ids.h
··· 2541 2541 2542 2542 #define PCI_VENDOR_ID_INTEL 0x8086 2543 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 2544 #define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320 2549 2545 #define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321 2550 2546 #define PCI_DEVICE_ID_INTEL_PXH_0 0x0329
+1 -1
tools/lib/api/Makefile
··· 16 16 LIBFILE = $(OUTPUT)libapi.a 17 17 18 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 20 CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 21 21 22 22 RM = rm -f
+1 -1
tools/lib/traceevent/event-parse.c
··· 3865 3865 } else if (el_size == 4) { 3866 3866 trace_seq_printf(s, "%u", *(uint32_t *)num); 3867 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 3869 } else { 3870 3870 trace_seq_printf(s, "BAD SIZE:%d 0x%x", 3871 3871 el_size, *(uint8_t *)num);
+8 -7
tools/perf/bench/futex-requeue.c
··· 132 132 if (!fshared) 133 133 futex_flag = FUTEX_PRIVATE_FLAG; 134 134 135 + if (nrequeue > nthreads) 136 + nrequeue = nthreads; 137 + 135 138 printf("Run summary [PID %d]: Requeuing %d threads (from [%s] %p to %p), " 136 139 "%d at a time.\n\n", getpid(), nthreads, 137 140 fshared ? "shared":"private", &futex1, &futex2, nrequeue); ··· 164 161 165 162 /* Ok, all threads are patiently blocked, start requeueing */ 166 163 gettimeofday(&start, NULL); 167 - for (nrequeued = 0; nrequeued < nthreads; nrequeued += nrequeue) { 164 + while (nrequeued < nthreads) { 168 165 /* 169 166 * Do not wakeup any tasks blocked on futex1, allowing 170 167 * us to really measure futex_wait functionality. 171 168 */ 172 - futex_cmp_requeue(&futex1, 0, &futex2, 0, 173 - nrequeue, futex_flag); 169 + nrequeued += futex_cmp_requeue(&futex1, 0, &futex2, 0, 170 + nrequeue, futex_flag); 174 171 } 172 + 175 173 gettimeofday(&end, NULL); 176 174 timersub(&end, &start, &runtime); 177 - 178 - if (nrequeued > nthreads) 179 - nrequeued = nthreads; 180 175 181 176 update_stats(&requeued_stats, nrequeued); 182 177 update_stats(&requeuetime_stats, runtime.tv_usec); ··· 185 184 } 186 185 187 186 /* everybody should be blocked on futex2, wake'em up */ 188 - nrequeued = futex_wake(&futex2, nthreads, futex_flag); 187 + nrequeued = futex_wake(&futex2, nrequeued, futex_flag); 189 188 if (nthreads != nrequeued) 190 189 warnx("couldn't wakeup all tasks (%d/%d)", nrequeued, nthreads); 191 190
+10 -2
tools/perf/bench/numa.c
··· 180 180 OPT_INTEGER('H', "thp" , &p0.thp, "MADV_NOHUGEPAGE < 0 < MADV_HUGEPAGE"), 181 181 OPT_BOOLEAN('c', "show_convergence", &p0.show_convergence, "show convergence details"), 182 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 184 OPT_BOOLEAN('S', "serialize-startup", &p0.serialize_startup,"serialize thread startup"), 185 185 186 186 /* Special option string parsing callbacks: */ ··· 828 828 td = g->threads + task_nr; 829 829 830 830 node = numa_node_of_cpu(td->curr_cpu); 831 + if (node < 0) /* curr_cpu was likely still -1 */ 832 + return 0; 833 + 831 834 node_present[node] = 1; 832 835 } 833 836 ··· 884 881 885 882 for (p = 0; p < g->p.nr_proc; p++) { 886 883 unsigned int nodes = count_process_nodes(p); 884 + 885 + if (!nodes) { 886 + *strong = 0; 887 + return; 888 + } 887 889 888 890 nodes_min = min(nodes, nodes_min); 889 891 nodes_max = max(nodes, nodes_max); ··· 1403 1395 if (!name) 1404 1396 name = "main,"; 1405 1397 1406 - if (g->p.show_quiet) 1398 + if (!g->p.show_quiet) 1407 1399 printf(" %-30s %15.3f, %-15s %s\n", name, val, txt_unit, txt_short); 1408 1400 else 1409 1401 printf(" %14.3f %s\n", val, txt_long);
+29 -29
tools/perf/builtin-kmem.c
··· 319 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 324 struct rb_node **node = &page_alloc_tree.rb_node; 325 325 struct rb_node *parent = NULL; ··· 331 331 parent = *node; 332 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 335 if (cmp < 0) 336 336 node = &parent->rb_left; 337 337 else if (cmp > 0) ··· 345 345 346 346 data = zalloc(sizeof(*data)); 347 347 if (data != NULL) { 348 - data->page = stat->page; 349 - data->order = stat->order; 350 - data->gfp_flags = stat->gfp_flags; 351 - data->migrate_type = stat->migrate_type; 348 + data->page = pstat->page; 349 + data->order = pstat->order; 350 + data->gfp_flags = pstat->gfp_flags; 351 + data->migrate_type = pstat->migrate_type; 352 352 353 353 rb_link_node(&data->node, parent, node); 354 354 rb_insert_color(&data->node, &page_alloc_tree); ··· 375 375 unsigned int migrate_type = perf_evsel__intval(evsel, sample, 376 376 "migratetype"); 377 377 u64 bytes = kmem_page_size << order; 378 - struct page_stat *stat; 378 + struct page_stat *pstat; 379 379 struct page_stat this = { 380 380 .order = order, 381 381 .gfp_flags = gfp_flags, ··· 401 401 * This is to find the current page (with correct gfp flags and 402 402 * migrate type) at free event. 403 403 */ 404 - stat = search_page(page, true); 405 - if (stat == NULL) 404 + pstat = search_page(page, true); 405 + if (pstat == NULL) 406 406 return -ENOMEM; 407 407 408 - stat->order = order; 409 - stat->gfp_flags = gfp_flags; 410 - stat->migrate_type = migrate_type; 408 + pstat->order = order; 409 + pstat->gfp_flags = gfp_flags; 410 + pstat->migrate_type = migrate_type; 411 411 412 412 this.page = page; 413 - stat = search_page_alloc_stat(&this, true); 414 - if (stat == NULL) 413 + pstat = search_page_alloc_stat(&this, true); 414 + if (pstat == NULL) 415 415 return -ENOMEM; 416 416 417 - stat->nr_alloc++; 418 - stat->alloc_bytes += bytes; 417 + pstat->nr_alloc++; 418 + pstat->alloc_bytes += bytes; 419 419 420 420 order_stats[order][migrate_type]++; 421 421 ··· 428 428 u64 page; 429 429 unsigned int order = perf_evsel__intval(evsel, sample, "order"); 430 430 u64 bytes = kmem_page_size << order; 431 - struct page_stat *stat; 431 + struct page_stat *pstat; 432 432 struct page_stat this = { 433 433 .order = order, 434 434 }; ··· 441 441 nr_page_frees++; 442 442 total_page_free_bytes += bytes; 443 443 444 - stat = search_page(page, false); 445 - if (stat == NULL) { 444 + pstat = search_page(page, false); 445 + if (pstat == NULL) { 446 446 pr_debug2("missing free at page %"PRIx64" (order: %d)\n", 447 447 page, order); 448 448 ··· 453 453 } 454 454 455 455 this.page = page; 456 - this.gfp_flags = stat->gfp_flags; 457 - this.migrate_type = stat->migrate_type; 456 + this.gfp_flags = pstat->gfp_flags; 457 + this.migrate_type = pstat->migrate_type; 458 458 459 - rb_erase(&stat->node, &page_tree); 460 - free(stat); 459 + rb_erase(&pstat->node, &page_tree); 460 + free(pstat); 461 461 462 - stat = search_page_alloc_stat(&this, false); 463 - if (stat == NULL) 462 + pstat = search_page_alloc_stat(&this, false); 463 + if (pstat == NULL) 464 464 return -ENOENT; 465 465 466 - stat->nr_free++; 467 - stat->free_bytes += bytes; 466 + pstat->nr_free++; 467 + pstat->free_bytes += bytes; 468 468 469 469 return 0; 470 470 } ··· 640 640 nr_page_frees, total_page_free_bytes / 1024); 641 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 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 646 nr_page_allocs - nr_alloc_freed, 647 647 (total_page_alloc_bytes - total_alloc_freed_bytes) / 1024); 648 648 printf("%-30s: %'16lu [ %'16"PRIu64" KB ]\n", "Total free-only requests",
+1 -1
tools/perf/builtin-report.c
··· 329 329 fprintf(stdout, "\n\n"); 330 330 } 331 331 332 - if (sort_order == default_sort_order && 332 + if (sort_order == NULL && 333 333 parent_pattern == default_parent_pattern) { 334 334 fprintf(stdout, "#\n# (%s)\n#\n", help); 335 335
+1 -1
tools/perf/builtin-top.c
··· 733 733 "Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" 734 734 "Check /proc/sys/kernel/kptr_restrict.\n\n" 735 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 737 " modules" : ""); 738 738 if (use_browser <= 0) 739 739 sleep(5);
+8 -2
tools/perf/builtin-trace.c
··· 2241 2241 if (err < 0) 2242 2242 goto out_error_mmap; 2243 2243 2244 + if (!target__none(&trace->opts.target)) 2245 + perf_evlist__enable(evlist); 2246 + 2244 2247 if (forks) 2245 2248 perf_evlist__start_workload(evlist); 2246 - else 2247 - perf_evlist__enable(evlist); 2248 2249 2249 2250 trace->multiple_threads = evlist->threads->map[0] == -1 || 2250 2251 evlist->threads->nr > 1 || ··· 2273 2272 2274 2273 if (interrupted) 2275 2274 goto out_disable; 2275 + 2276 + if (done && !draining) { 2277 + perf_evlist__disable(evlist); 2278 + draining = true; 2279 + } 2276 2280 } 2277 2281 } 2278 2282
+2
tools/perf/util/probe-event.c
··· 1084 1084 * 1085 1085 * TODO:Group name support 1086 1086 */ 1087 + if (!arg) 1088 + return -EINVAL; 1087 1089 1088 1090 ptr = strpbrk(arg, ";=@+%"); 1089 1091 if (ptr && *ptr == '=') { /* Event name */
+3 -1
tools/perf/util/probe-finder.c
··· 578 578 /* Search child die for local variables and parameters. */ 579 579 if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) { 580 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 583 pr_warning("Failed to find '%s' in this function.\n", 583 584 pf->pvar->var); 584 585 ret = -ENOENT; 586 + } 585 587 } 586 588 if (ret >= 0) 587 589 ret = convert_variable(&vr_die, pf);