diff options
| -rw-r--r-- | arch/x86/events/amd/core.c | 21 | ||||
| -rw-r--r-- | arch/x86/events/perf_event.h | 5 |
2 files changed, 23 insertions, 3 deletions
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 049ada8d4e9c..86a9bec18dab 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c | |||
| @@ -369,7 +369,7 @@ static int amd_pmu_cpu_prepare(int cpu) | |||
| 369 | 369 | ||
| 370 | WARN_ON_ONCE(cpuc->amd_nb); | 370 | WARN_ON_ONCE(cpuc->amd_nb); |
| 371 | 371 | ||
| 372 | if (boot_cpu_data.x86_max_cores < 2) | 372 | if (!x86_pmu.amd_nb_constraints) |
| 373 | return NOTIFY_OK; | 373 | return NOTIFY_OK; |
| 374 | 374 | ||
| 375 | cpuc->amd_nb = amd_alloc_nb(cpu); | 375 | cpuc->amd_nb = amd_alloc_nb(cpu); |
| @@ -388,7 +388,7 @@ static void amd_pmu_cpu_starting(int cpu) | |||
| 388 | 388 | ||
| 389 | cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; | 389 | cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; |
| 390 | 390 | ||
| 391 | if (boot_cpu_data.x86_max_cores < 2) | 391 | if (!x86_pmu.amd_nb_constraints) |
| 392 | return; | 392 | return; |
| 393 | 393 | ||
| 394 | nb_id = amd_get_nb_id(cpu); | 394 | nb_id = amd_get_nb_id(cpu); |
| @@ -414,7 +414,7 @@ static void amd_pmu_cpu_dead(int cpu) | |||
| 414 | { | 414 | { |
| 415 | struct cpu_hw_events *cpuhw; | 415 | struct cpu_hw_events *cpuhw; |
| 416 | 416 | ||
| 417 | if (boot_cpu_data.x86_max_cores < 2) | 417 | if (!x86_pmu.amd_nb_constraints) |
| 418 | return; | 418 | return; |
| 419 | 419 | ||
| 420 | cpuhw = &per_cpu(cpu_hw_events, cpu); | 420 | cpuhw = &per_cpu(cpu_hw_events, cpu); |
| @@ -648,6 +648,8 @@ static __initconst const struct x86_pmu amd_pmu = { | |||
| 648 | .cpu_prepare = amd_pmu_cpu_prepare, | 648 | .cpu_prepare = amd_pmu_cpu_prepare, |
| 649 | .cpu_starting = amd_pmu_cpu_starting, | 649 | .cpu_starting = amd_pmu_cpu_starting, |
| 650 | .cpu_dead = amd_pmu_cpu_dead, | 650 | .cpu_dead = amd_pmu_cpu_dead, |
| 651 | |||
| 652 | .amd_nb_constraints = 1, | ||
| 651 | }; | 653 | }; |
| 652 | 654 | ||
| 653 | static int __init amd_core_pmu_init(void) | 655 | static int __init amd_core_pmu_init(void) |
| @@ -674,6 +676,11 @@ static int __init amd_core_pmu_init(void) | |||
| 674 | x86_pmu.eventsel = MSR_F15H_PERF_CTL; | 676 | x86_pmu.eventsel = MSR_F15H_PERF_CTL; |
| 675 | x86_pmu.perfctr = MSR_F15H_PERF_CTR; | 677 | x86_pmu.perfctr = MSR_F15H_PERF_CTR; |
| 676 | x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE; | 678 | x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE; |
| 679 | /* | ||
| 680 | * AMD Core perfctr has separate MSRs for the NB events, see | ||
| 681 | * the amd/uncore.c driver. | ||
| 682 | */ | ||
| 683 | x86_pmu.amd_nb_constraints = 0; | ||
| 677 | 684 | ||
| 678 | pr_cont("core perfctr, "); | 685 | pr_cont("core perfctr, "); |
| 679 | return 0; | 686 | return 0; |
| @@ -693,6 +700,14 @@ __init int amd_pmu_init(void) | |||
| 693 | if (ret) | 700 | if (ret) |
| 694 | return ret; | 701 | return ret; |
| 695 | 702 | ||
| 703 | if (num_possible_cpus() == 1) { | ||
| 704 | /* | ||
| 705 | * No point in allocating data structures to serialize | ||
| 706 | * against other CPUs, when there is only the one CPU. | ||
| 707 | */ | ||
| 708 | x86_pmu.amd_nb_constraints = 0; | ||
| 709 | } | ||
| 710 | |||
| 696 | /* Events are common for all AMDs */ | 711 | /* Events are common for all AMDs */ |
| 697 | memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, | 712 | memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, |
| 698 | sizeof(hw_cache_event_ids)); | 713 | sizeof(hw_cache_event_ids)); |
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index ba6ef18528c9..716d0482f5db 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h | |||
| @@ -608,6 +608,11 @@ struct x86_pmu { | |||
| 608 | atomic_t lbr_exclusive[x86_lbr_exclusive_max]; | 608 | atomic_t lbr_exclusive[x86_lbr_exclusive_max]; |
| 609 | 609 | ||
| 610 | /* | 610 | /* |
| 611 | * AMD bits | ||
| 612 | */ | ||
| 613 | unsigned int amd_nb_constraints : 1; | ||
| 614 | |||
| 615 | /* | ||
| 611 | * Extra registers for events | 616 | * Extra registers for events |
| 612 | */ | 617 | */ |
| 613 | struct extra_reg *extra_regs; | 618 | struct extra_reg *extra_regs; |
