diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-28 19:27:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-28 19:27:16 -0400 |
commit | b49c3170bf2803329c0daff8e386e08f50f1729d (patch) | |
tree | 81749e52e9c000b76b17d098b566bcd1b77d4d2a | |
parent | ed99d3673e082b78b20208f346d2cd375483a779 (diff) | |
parent | f92b7604149a55cb601fc0b52911b1e11f0f2514 (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:
"Misc kernel fixes: a virtualization environment related fix, an uncore
PMU driver removal handling fix, a PowerPC fix and new events for
Knights Landing"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86/intel: Honour the CPUID for number of fixed counters in hypervisors
perf/powerpc: Don't call perf_event_disable() from atomic context
perf/core: Protect PMU device removal with a 'pmu_bus_running' check, to fix CONFIG_DEBUG_TEST_DRIVER_REMOVE=y kernel panic
perf/x86/intel/cstate: Add C-state residency events for Knights Landing
-rw-r--r-- | arch/powerpc/kernel/hw_breakpoint.c | 2 | ||||
-rw-r--r-- | arch/x86/events/intel/core.c | 10 | ||||
-rw-r--r-- | arch/x86/events/intel/cstate.c | 30 | ||||
-rw-r--r-- | include/linux/perf_event.h | 1 | ||||
-rw-r--r-- | kernel/events/core.c | 23 |
5 files changed, 52 insertions, 14 deletions
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index 9781c69eae57..03d089b3ed72 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c | |||
@@ -275,7 +275,7 @@ int hw_breakpoint_handler(struct die_args *args) | |||
275 | if (!stepped) { | 275 | if (!stepped) { |
276 | WARN(1, "Unable to handle hardware breakpoint. Breakpoint at " | 276 | WARN(1, "Unable to handle hardware breakpoint. Breakpoint at " |
277 | "0x%lx will be disabled.", info->address); | 277 | "0x%lx will be disabled.", info->address); |
278 | perf_event_disable(bp); | 278 | perf_event_disable_inatomic(bp); |
279 | goto out; | 279 | goto out; |
280 | } | 280 | } |
281 | /* | 281 | /* |
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index eab0915f5995..a74a2dbc0180 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c | |||
@@ -3607,10 +3607,14 @@ __init int intel_pmu_init(void) | |||
3607 | 3607 | ||
3608 | /* | 3608 | /* |
3609 | * Quirk: v2 perfmon does not report fixed-purpose events, so | 3609 | * Quirk: v2 perfmon does not report fixed-purpose events, so |
3610 | * assume at least 3 events: | 3610 | * assume at least 3 events, when not running in a hypervisor: |
3611 | */ | 3611 | */ |
3612 | if (version > 1) | 3612 | if (version > 1) { |
3613 | x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); | 3613 | int assume = 3 * !boot_cpu_has(X86_FEATURE_HYPERVISOR); |
3614 | |||
3615 | x86_pmu.num_counters_fixed = | ||
3616 | max((int)edx.split.num_counters_fixed, assume); | ||
3617 | } | ||
3614 | 3618 | ||
3615 | if (boot_cpu_has(X86_FEATURE_PDCM)) { | 3619 | if (boot_cpu_has(X86_FEATURE_PDCM)) { |
3616 | u64 capabilities; | 3620 | u64 capabilities; |
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 3ca87b5a8677..4f5ac726335f 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c | |||
@@ -48,7 +48,8 @@ | |||
48 | * Scope: Core | 48 | * Scope: Core |
49 | * MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter | 49 | * MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter |
50 | * perf code: 0x02 | 50 | * perf code: 0x02 |
51 | * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,SKL | 51 | * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW |
52 | * SKL,KNL | ||
52 | * Scope: Core | 53 | * Scope: Core |
53 | * MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter | 54 | * MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter |
54 | * perf code: 0x03 | 55 | * perf code: 0x03 |
@@ -56,15 +57,16 @@ | |||
56 | * Scope: Core | 57 | * Scope: Core |
57 | * MSR_PKG_C2_RESIDENCY: Package C2 Residency Counter. | 58 | * MSR_PKG_C2_RESIDENCY: Package C2 Residency Counter. |
58 | * perf code: 0x00 | 59 | * perf code: 0x00 |
59 | * Available model: SNB,IVB,HSW,BDW,SKL | 60 | * Available model: SNB,IVB,HSW,BDW,SKL,KNL |
60 | * Scope: Package (physical package) | 61 | * Scope: Package (physical package) |
61 | * MSR_PKG_C3_RESIDENCY: Package C3 Residency Counter. | 62 | * MSR_PKG_C3_RESIDENCY: Package C3 Residency Counter. |
62 | * perf code: 0x01 | 63 | * perf code: 0x01 |
63 | * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL | 64 | * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL |
64 | * Scope: Package (physical package) | 65 | * Scope: Package (physical package) |
65 | * MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter. | 66 | * MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter. |
66 | * perf code: 0x02 | 67 | * perf code: 0x02 |
67 | * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,SKL | 68 | * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW |
69 | * SKL,KNL | ||
68 | * Scope: Package (physical package) | 70 | * Scope: Package (physical package) |
69 | * MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter. | 71 | * MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter. |
70 | * perf code: 0x03 | 72 | * perf code: 0x03 |
@@ -118,6 +120,7 @@ struct cstate_model { | |||
118 | 120 | ||
119 | /* Quirk flags */ | 121 | /* Quirk flags */ |
120 | #define SLM_PKG_C6_USE_C7_MSR (1UL << 0) | 122 | #define SLM_PKG_C6_USE_C7_MSR (1UL << 0) |
123 | #define KNL_CORE_C6_MSR (1UL << 1) | ||
121 | 124 | ||
122 | struct perf_cstate_msr { | 125 | struct perf_cstate_msr { |
123 | u64 msr; | 126 | u64 msr; |
@@ -488,6 +491,18 @@ static const struct cstate_model slm_cstates __initconst = { | |||
488 | .quirks = SLM_PKG_C6_USE_C7_MSR, | 491 | .quirks = SLM_PKG_C6_USE_C7_MSR, |
489 | }; | 492 | }; |
490 | 493 | ||
494 | |||
495 | static const struct cstate_model knl_cstates __initconst = { | ||
496 | .core_events = BIT(PERF_CSTATE_CORE_C6_RES), | ||
497 | |||
498 | .pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) | | ||
499 | BIT(PERF_CSTATE_PKG_C3_RES) | | ||
500 | BIT(PERF_CSTATE_PKG_C6_RES), | ||
501 | .quirks = KNL_CORE_C6_MSR, | ||
502 | }; | ||
503 | |||
504 | |||
505 | |||
491 | #define X86_CSTATES_MODEL(model, states) \ | 506 | #define X86_CSTATES_MODEL(model, states) \ |
492 | { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long) &(states) } | 507 | { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long) &(states) } |
493 | 508 | ||
@@ -523,6 +538,8 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { | |||
523 | 538 | ||
524 | X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_MOBILE, snb_cstates), | 539 | X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_MOBILE, snb_cstates), |
525 | X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_DESKTOP, snb_cstates), | 540 | X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_DESKTOP, snb_cstates), |
541 | |||
542 | X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNL, knl_cstates), | ||
526 | { }, | 543 | { }, |
527 | }; | 544 | }; |
528 | MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match); | 545 | MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match); |
@@ -558,6 +575,11 @@ static int __init cstate_probe(const struct cstate_model *cm) | |||
558 | if (cm->quirks & SLM_PKG_C6_USE_C7_MSR) | 575 | if (cm->quirks & SLM_PKG_C6_USE_C7_MSR) |
559 | pkg_msr[PERF_CSTATE_PKG_C6_RES].msr = MSR_PKG_C7_RESIDENCY; | 576 | pkg_msr[PERF_CSTATE_PKG_C6_RES].msr = MSR_PKG_C7_RESIDENCY; |
560 | 577 | ||
578 | /* KNL has different MSR for CORE C6 */ | ||
579 | if (cm->quirks & KNL_CORE_C6_MSR) | ||
580 | pkg_msr[PERF_CSTATE_CORE_C6_RES].msr = MSR_KNL_CORE_C6_RESIDENCY; | ||
581 | |||
582 | |||
561 | has_cstate_core = cstate_probe_msr(cm->core_events, | 583 | has_cstate_core = cstate_probe_msr(cm->core_events, |
562 | PERF_CSTATE_CORE_EVENT_MAX, | 584 | PERF_CSTATE_CORE_EVENT_MAX, |
563 | core_msr, core_events_attrs); | 585 | core_msr, core_events_attrs); |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 060d0ede88df..4741ecdb9817 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -1257,6 +1257,7 @@ extern u64 perf_swevent_set_period(struct perf_event *event); | |||
1257 | extern void perf_event_enable(struct perf_event *event); | 1257 | extern void perf_event_enable(struct perf_event *event); |
1258 | extern void perf_event_disable(struct perf_event *event); | 1258 | extern void perf_event_disable(struct perf_event *event); |
1259 | extern void perf_event_disable_local(struct perf_event *event); | 1259 | extern void perf_event_disable_local(struct perf_event *event); |
1260 | extern void perf_event_disable_inatomic(struct perf_event *event); | ||
1260 | extern void perf_event_task_tick(void); | 1261 | extern void perf_event_task_tick(void); |
1261 | #else /* !CONFIG_PERF_EVENTS: */ | 1262 | #else /* !CONFIG_PERF_EVENTS: */ |
1262 | static inline void * | 1263 | static inline void * |
diff --git a/kernel/events/core.c b/kernel/events/core.c index c6e47e97b33f..0e292132efac 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -1960,6 +1960,12 @@ void perf_event_disable(struct perf_event *event) | |||
1960 | } | 1960 | } |
1961 | EXPORT_SYMBOL_GPL(perf_event_disable); | 1961 | EXPORT_SYMBOL_GPL(perf_event_disable); |
1962 | 1962 | ||
1963 | void perf_event_disable_inatomic(struct perf_event *event) | ||
1964 | { | ||
1965 | event->pending_disable = 1; | ||
1966 | irq_work_queue(&event->pending); | ||
1967 | } | ||
1968 | |||
1963 | static void perf_set_shadow_time(struct perf_event *event, | 1969 | static void perf_set_shadow_time(struct perf_event *event, |
1964 | struct perf_event_context *ctx, | 1970 | struct perf_event_context *ctx, |
1965 | u64 tstamp) | 1971 | u64 tstamp) |
@@ -7075,8 +7081,8 @@ static int __perf_event_overflow(struct perf_event *event, | |||
7075 | if (events && atomic_dec_and_test(&event->event_limit)) { | 7081 | if (events && atomic_dec_and_test(&event->event_limit)) { |
7076 | ret = 1; | 7082 | ret = 1; |
7077 | event->pending_kill = POLL_HUP; | 7083 | event->pending_kill = POLL_HUP; |
7078 | event->pending_disable = 1; | 7084 | |
7079 | irq_work_queue(&event->pending); | 7085 | perf_event_disable_inatomic(event); |
7080 | } | 7086 | } |
7081 | 7087 | ||
7082 | READ_ONCE(event->overflow_handler)(event, data, regs); | 7088 | READ_ONCE(event->overflow_handler)(event, data, regs); |
@@ -8855,7 +8861,10 @@ EXPORT_SYMBOL_GPL(perf_pmu_register); | |||
8855 | 8861 | ||
8856 | void perf_pmu_unregister(struct pmu *pmu) | 8862 | void perf_pmu_unregister(struct pmu *pmu) |
8857 | { | 8863 | { |
8864 | int remove_device; | ||
8865 | |||
8858 | mutex_lock(&pmus_lock); | 8866 | mutex_lock(&pmus_lock); |
8867 | remove_device = pmu_bus_running; | ||
8859 | list_del_rcu(&pmu->entry); | 8868 | list_del_rcu(&pmu->entry); |
8860 | mutex_unlock(&pmus_lock); | 8869 | mutex_unlock(&pmus_lock); |
8861 | 8870 | ||
@@ -8869,10 +8878,12 @@ void perf_pmu_unregister(struct pmu *pmu) | |||
8869 | free_percpu(pmu->pmu_disable_count); | 8878 | free_percpu(pmu->pmu_disable_count); |
8870 | if (pmu->type >= PERF_TYPE_MAX) | 8879 | if (pmu->type >= PERF_TYPE_MAX) |
8871 | idr_remove(&pmu_idr, pmu->type); | 8880 | idr_remove(&pmu_idr, pmu->type); |
8872 | if (pmu->nr_addr_filters) | 8881 | if (remove_device) { |
8873 | device_remove_file(pmu->dev, &dev_attr_nr_addr_filters); | 8882 | if (pmu->nr_addr_filters) |
8874 | device_del(pmu->dev); | 8883 | device_remove_file(pmu->dev, &dev_attr_nr_addr_filters); |
8875 | put_device(pmu->dev); | 8884 | device_del(pmu->dev); |
8885 | put_device(pmu->dev); | ||
8886 | } | ||
8876 | free_pmu_context(pmu); | 8887 | free_pmu_context(pmu); |
8877 | } | 8888 | } |
8878 | EXPORT_SYMBOL_GPL(perf_pmu_unregister); | 8889 | EXPORT_SYMBOL_GPL(perf_pmu_unregister); |