aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/events/core.c3
-rw-r--r--arch/x86/events/intel/core.c14
-rw-r--r--arch/x86/events/intel/ds.c6
-rw-r--r--arch/x86/events/intel/uncore_snbep.c32
-rw-r--r--arch/x86/events/perf_event.h6
-rw-r--r--kernel/events/core.c21
6 files changed, 49 insertions, 33 deletions
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 140d33288e78..88797c80b3e0 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2118,7 +2118,8 @@ static int x86_pmu_event_init(struct perf_event *event)
2118 event->destroy(event); 2118 event->destroy(event);
2119 } 2119 }
2120 2120
2121 if (READ_ONCE(x86_pmu.attr_rdpmc)) 2121 if (READ_ONCE(x86_pmu.attr_rdpmc) &&
2122 !(event->hw.flags & PERF_X86_EVENT_LARGE_PEBS))
2122 event->hw.flags |= PERF_X86_EVENT_RDPMC_ALLOWED; 2123 event->hw.flags |= PERF_X86_EVENT_RDPMC_ALLOWED;
2123 2124
2124 return err; 2125 return err;
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 56457cb73448..1e41d7508d99 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2952,9 +2952,9 @@ static void intel_pebs_aliases_skl(struct perf_event *event)
2952 return intel_pebs_aliases_precdist(event); 2952 return intel_pebs_aliases_precdist(event);
2953} 2953}
2954 2954
2955static unsigned long intel_pmu_free_running_flags(struct perf_event *event) 2955static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event)
2956{ 2956{
2957 unsigned long flags = x86_pmu.free_running_flags; 2957 unsigned long flags = x86_pmu.large_pebs_flags;
2958 2958
2959 if (event->attr.use_clockid) 2959 if (event->attr.use_clockid)
2960 flags &= ~PERF_SAMPLE_TIME; 2960 flags &= ~PERF_SAMPLE_TIME;
@@ -2976,8 +2976,8 @@ static int intel_pmu_hw_config(struct perf_event *event)
2976 if (!event->attr.freq) { 2976 if (!event->attr.freq) {
2977 event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD; 2977 event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
2978 if (!(event->attr.sample_type & 2978 if (!(event->attr.sample_type &
2979 ~intel_pmu_free_running_flags(event))) 2979 ~intel_pmu_large_pebs_flags(event)))
2980 event->hw.flags |= PERF_X86_EVENT_FREERUNNING; 2980 event->hw.flags |= PERF_X86_EVENT_LARGE_PEBS;
2981 } 2981 }
2982 if (x86_pmu.pebs_aliases) 2982 if (x86_pmu.pebs_aliases)
2983 x86_pmu.pebs_aliases(event); 2983 x86_pmu.pebs_aliases(event);
@@ -3194,7 +3194,7 @@ static unsigned bdw_limit_period(struct perf_event *event, unsigned left)
3194 X86_CONFIG(.event=0xc0, .umask=0x01)) { 3194 X86_CONFIG(.event=0xc0, .umask=0x01)) {
3195 if (left < 128) 3195 if (left < 128)
3196 left = 128; 3196 left = 128;
3197 left &= ~0x3fu; 3197 left &= ~0x3fULL;
3198 } 3198 }
3199 return left; 3199 return left;
3200} 3200}
@@ -3460,7 +3460,7 @@ static __initconst const struct x86_pmu core_pmu = {
3460 .event_map = intel_pmu_event_map, 3460 .event_map = intel_pmu_event_map,
3461 .max_events = ARRAY_SIZE(intel_perfmon_event_map), 3461 .max_events = ARRAY_SIZE(intel_perfmon_event_map),
3462 .apic = 1, 3462 .apic = 1,
3463 .free_running_flags = PEBS_FREERUNNING_FLAGS, 3463 .large_pebs_flags = LARGE_PEBS_FLAGS,
3464 3464
3465 /* 3465 /*
3466 * Intel PMCs cannot be accessed sanely above 32-bit width, 3466 * Intel PMCs cannot be accessed sanely above 32-bit width,
@@ -3502,7 +3502,7 @@ static __initconst const struct x86_pmu intel_pmu = {
3502 .event_map = intel_pmu_event_map, 3502 .event_map = intel_pmu_event_map,
3503 .max_events = ARRAY_SIZE(intel_perfmon_event_map), 3503 .max_events = ARRAY_SIZE(intel_perfmon_event_map),
3504 .apic = 1, 3504 .apic = 1,
3505 .free_running_flags = PEBS_FREERUNNING_FLAGS, 3505 .large_pebs_flags = LARGE_PEBS_FLAGS,
3506 /* 3506 /*
3507 * Intel PMCs cannot be accessed sanely above 32 bit width, 3507 * Intel PMCs cannot be accessed sanely above 32 bit width,
3508 * so we install an artificial 1<<31 period regardless of 3508 * so we install an artificial 1<<31 period regardless of
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 18c25ab28557..d8015235ba76 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -935,7 +935,7 @@ void intel_pmu_pebs_add(struct perf_event *event)
935 bool needed_cb = pebs_needs_sched_cb(cpuc); 935 bool needed_cb = pebs_needs_sched_cb(cpuc);
936 936
937 cpuc->n_pebs++; 937 cpuc->n_pebs++;
938 if (hwc->flags & PERF_X86_EVENT_FREERUNNING) 938 if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS)
939 cpuc->n_large_pebs++; 939 cpuc->n_large_pebs++;
940 940
941 pebs_update_state(needed_cb, cpuc, event->ctx->pmu); 941 pebs_update_state(needed_cb, cpuc, event->ctx->pmu);
@@ -975,7 +975,7 @@ void intel_pmu_pebs_del(struct perf_event *event)
975 bool needed_cb = pebs_needs_sched_cb(cpuc); 975 bool needed_cb = pebs_needs_sched_cb(cpuc);
976 976
977 cpuc->n_pebs--; 977 cpuc->n_pebs--;
978 if (hwc->flags & PERF_X86_EVENT_FREERUNNING) 978 if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS)
979 cpuc->n_large_pebs--; 979 cpuc->n_large_pebs--;
980 980
981 pebs_update_state(needed_cb, cpuc, event->ctx->pmu); 981 pebs_update_state(needed_cb, cpuc, event->ctx->pmu);
@@ -1530,7 +1530,7 @@ void __init intel_ds_init(void)
1530 x86_pmu.pebs_record_size = 1530 x86_pmu.pebs_record_size =
1531 sizeof(struct pebs_record_skl); 1531 sizeof(struct pebs_record_skl);
1532 x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; 1532 x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
1533 x86_pmu.free_running_flags |= PERF_SAMPLE_TIME; 1533 x86_pmu.large_pebs_flags |= PERF_SAMPLE_TIME;
1534 break; 1534 break;
1535 1535
1536 default: 1536 default:
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 22ec65bc033a..c98b943e58b4 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -3343,6 +3343,7 @@ static struct extra_reg skx_uncore_cha_extra_regs[] = {
3343 SNBEP_CBO_EVENT_EXTRA_REG(0x9134, 0xffff, 0x4), 3343 SNBEP_CBO_EVENT_EXTRA_REG(0x9134, 0xffff, 0x4),
3344 SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x8), 3344 SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x8),
3345 SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x8), 3345 SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x8),
3346 SNBEP_CBO_EVENT_EXTRA_REG(0x38, 0xff, 0x3),
3346 EVENT_EXTRA_END 3347 EVENT_EXTRA_END
3347}; 3348};
3348 3349
@@ -3562,24 +3563,27 @@ static struct intel_uncore_type *skx_msr_uncores[] = {
3562 NULL, 3563 NULL,
3563}; 3564};
3564 3565
3566/*
3567 * To determine the number of CHAs, it should read bits 27:0 in the CAPID6
3568 * register which located at Device 30, Function 3, Offset 0x9C. PCI ID 0x2083.
3569 */
3570#define SKX_CAPID6 0x9c
3571#define SKX_CHA_BIT_MASK GENMASK(27, 0)
3572
3565static int skx_count_chabox(void) 3573static int skx_count_chabox(void)
3566{ 3574{
3567 struct pci_dev *chabox_dev = NULL; 3575 struct pci_dev *dev = NULL;
3568 int bus, count = 0; 3576 u32 val = 0;
3569 3577
3570 while (1) { 3578 dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x2083, dev);
3571 chabox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x208d, chabox_dev); 3579 if (!dev)
3572 if (!chabox_dev) 3580 goto out;
3573 break;
3574 if (count == 0)
3575 bus = chabox_dev->bus->number;
3576 if (bus != chabox_dev->bus->number)
3577 break;
3578 count++;
3579 }
3580 3581
3581 pci_dev_put(chabox_dev); 3582 pci_read_config_dword(dev, SKX_CAPID6, &val);
3582 return count; 3583 val &= SKX_CHA_BIT_MASK;
3584out:
3585 pci_dev_put(dev);
3586 return hweight32(val);
3583} 3587}
3584 3588
3585void skx_uncore_cpu_init(void) 3589void skx_uncore_cpu_init(void)
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 78f91ec1056e..39cd0615f04f 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -69,7 +69,7 @@ struct event_constraint {
69#define PERF_X86_EVENT_RDPMC_ALLOWED 0x0100 /* grant rdpmc permission */ 69#define PERF_X86_EVENT_RDPMC_ALLOWED 0x0100 /* grant rdpmc permission */
70#define PERF_X86_EVENT_EXCL_ACCT 0x0200 /* accounted EXCL event */ 70#define PERF_X86_EVENT_EXCL_ACCT 0x0200 /* accounted EXCL event */
71#define PERF_X86_EVENT_AUTO_RELOAD 0x0400 /* use PEBS auto-reload */ 71#define PERF_X86_EVENT_AUTO_RELOAD 0x0400 /* use PEBS auto-reload */
72#define PERF_X86_EVENT_FREERUNNING 0x0800 /* use freerunning PEBS */ 72#define PERF_X86_EVENT_LARGE_PEBS 0x0800 /* use large PEBS */
73 73
74 74
75struct amd_nb { 75struct amd_nb {
@@ -88,7 +88,7 @@ struct amd_nb {
88 * REGS_USER can be handled for events limited to ring 3. 88 * REGS_USER can be handled for events limited to ring 3.
89 * 89 *
90 */ 90 */
91#define PEBS_FREERUNNING_FLAGS \ 91#define LARGE_PEBS_FLAGS \
92 (PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \ 92 (PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \
93 PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \ 93 PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \
94 PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \ 94 PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \
@@ -608,7 +608,7 @@ struct x86_pmu {
608 struct event_constraint *pebs_constraints; 608 struct event_constraint *pebs_constraints;
609 void (*pebs_aliases)(struct perf_event *event); 609 void (*pebs_aliases)(struct perf_event *event);
610 int max_pebs_events; 610 int max_pebs_events;
611 unsigned long free_running_flags; 611 unsigned long large_pebs_flags;
612 612
613 /* 613 /*
614 * Intel LBR 614 * Intel LBR
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 4b838470fac4..709a55b9ad97 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -724,9 +724,15 @@ static inline void __update_cgrp_time(struct perf_cgroup *cgrp)
724 724
725static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx) 725static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx)
726{ 726{
727 struct perf_cgroup *cgrp_out = cpuctx->cgrp; 727 struct perf_cgroup *cgrp = cpuctx->cgrp;
728 if (cgrp_out) 728 struct cgroup_subsys_state *css;
729 __update_cgrp_time(cgrp_out); 729
730 if (cgrp) {
731 for (css = &cgrp->css; css; css = css->parent) {
732 cgrp = container_of(css, struct perf_cgroup, css);
733 __update_cgrp_time(cgrp);
734 }
735 }
730} 736}
731 737
732static inline void update_cgrp_time_from_event(struct perf_event *event) 738static inline void update_cgrp_time_from_event(struct perf_event *event)
@@ -754,6 +760,7 @@ perf_cgroup_set_timestamp(struct task_struct *task,
754{ 760{
755 struct perf_cgroup *cgrp; 761 struct perf_cgroup *cgrp;
756 struct perf_cgroup_info *info; 762 struct perf_cgroup_info *info;
763 struct cgroup_subsys_state *css;
757 764
758 /* 765 /*
759 * ctx->lock held by caller 766 * ctx->lock held by caller
@@ -764,8 +771,12 @@ perf_cgroup_set_timestamp(struct task_struct *task,
764 return; 771 return;
765 772
766 cgrp = perf_cgroup_from_task(task, ctx); 773 cgrp = perf_cgroup_from_task(task, ctx);
767 info = this_cpu_ptr(cgrp->info); 774
768 info->timestamp = ctx->timestamp; 775 for (css = &cgrp->css; css; css = css->parent) {
776 cgrp = container_of(css, struct perf_cgroup, css);
777 info = this_cpu_ptr(cgrp->info);
778 info->timestamp = ctx->timestamp;
779 }
769} 780}
770 781
771static DEFINE_PER_CPU(struct list_head, cgrp_cpuctx_list); 782static DEFINE_PER_CPU(struct list_head, cgrp_cpuctx_list);