aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/events/intel/ds.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/events/intel/ds.c')
-rw-r--r--arch/x86/events/intel/ds.c108
1 files changed, 73 insertions, 35 deletions
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 9b983a474253..0319311dbdbb 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -806,9 +806,65 @@ struct event_constraint *intel_pebs_constraints(struct perf_event *event)
806 return &emptyconstraint; 806 return &emptyconstraint;
807} 807}
808 808
809static inline bool pebs_is_enabled(struct cpu_hw_events *cpuc) 809/*
810 * We need the sched_task callback even for per-cpu events when we use
811 * the large interrupt threshold, such that we can provide PID and TID
812 * to PEBS samples.
813 */
814static inline bool pebs_needs_sched_cb(struct cpu_hw_events *cpuc)
815{
816 return cpuc->n_pebs && (cpuc->n_pebs == cpuc->n_large_pebs);
817}
818
819static inline void pebs_update_threshold(struct cpu_hw_events *cpuc)
820{
821 struct debug_store *ds = cpuc->ds;
822 u64 threshold;
823
824 if (cpuc->n_pebs == cpuc->n_large_pebs) {
825 threshold = ds->pebs_absolute_maximum -
826 x86_pmu.max_pebs_events * x86_pmu.pebs_record_size;
827 } else {
828 threshold = ds->pebs_buffer_base + x86_pmu.pebs_record_size;
829 }
830
831 ds->pebs_interrupt_threshold = threshold;
832}
833
834static void
835pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc, struct pmu *pmu)
836{
837 /*
838 * Make sure we get updated with the first PEBS
839 * event. It will trigger also during removal, but
840 * that does not hurt:
841 */
842 bool update = cpuc->n_pebs == 1;
843
844 if (needed_cb != pebs_needs_sched_cb(cpuc)) {
845 if (!needed_cb)
846 perf_sched_cb_inc(pmu);
847 else
848 perf_sched_cb_dec(pmu);
849
850 update = true;
851 }
852
853 if (update)
854 pebs_update_threshold(cpuc);
855}
856
857void intel_pmu_pebs_add(struct perf_event *event)
810{ 858{
811 return (cpuc->pebs_enabled & ((1ULL << MAX_PEBS_EVENTS) - 1)); 859 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
860 struct hw_perf_event *hwc = &event->hw;
861 bool needed_cb = pebs_needs_sched_cb(cpuc);
862
863 cpuc->n_pebs++;
864 if (hwc->flags & PERF_X86_EVENT_FREERUNNING)
865 cpuc->n_large_pebs++;
866
867 pebs_update_state(needed_cb, cpuc, event->ctx->pmu);
812} 868}
813 869
814void intel_pmu_pebs_enable(struct perf_event *event) 870void intel_pmu_pebs_enable(struct perf_event *event)
@@ -816,12 +872,9 @@ void intel_pmu_pebs_enable(struct perf_event *event)
816 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); 872 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
817 struct hw_perf_event *hwc = &event->hw; 873 struct hw_perf_event *hwc = &event->hw;
818 struct debug_store *ds = cpuc->ds; 874 struct debug_store *ds = cpuc->ds;
819 bool first_pebs;
820 u64 threshold;
821 875
822 hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT; 876 hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
823 877
824 first_pebs = !pebs_is_enabled(cpuc);
825 cpuc->pebs_enabled |= 1ULL << hwc->idx; 878 cpuc->pebs_enabled |= 1ULL << hwc->idx;
826 879
827 if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT) 880 if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
@@ -830,46 +883,34 @@ void intel_pmu_pebs_enable(struct perf_event *event)
830 cpuc->pebs_enabled |= 1ULL << 63; 883 cpuc->pebs_enabled |= 1ULL << 63;
831 884
832 /* 885 /*
833 * When the event is constrained enough we can use a larger 886 * Use auto-reload if possible to save a MSR write in the PMI.
834 * threshold and run the event with less frequent PMI. 887 * This must be done in pmu::start(), because PERF_EVENT_IOC_PERIOD.
835 */ 888 */
836 if (hwc->flags & PERF_X86_EVENT_FREERUNNING) {
837 threshold = ds->pebs_absolute_maximum -
838 x86_pmu.max_pebs_events * x86_pmu.pebs_record_size;
839
840 if (first_pebs)
841 perf_sched_cb_inc(event->ctx->pmu);
842 } else {
843 threshold = ds->pebs_buffer_base + x86_pmu.pebs_record_size;
844
845 /*
846 * If not all events can use larger buffer,
847 * roll back to threshold = 1
848 */
849 if (!first_pebs &&
850 (ds->pebs_interrupt_threshold > threshold))
851 perf_sched_cb_dec(event->ctx->pmu);
852 }
853
854 /* Use auto-reload if possible to save a MSR write in the PMI */
855 if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) { 889 if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) {
856 ds->pebs_event_reset[hwc->idx] = 890 ds->pebs_event_reset[hwc->idx] =
857 (u64)(-hwc->sample_period) & x86_pmu.cntval_mask; 891 (u64)(-hwc->sample_period) & x86_pmu.cntval_mask;
858 } 892 }
893}
894
895void intel_pmu_pebs_del(struct perf_event *event)
896{
897 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
898 struct hw_perf_event *hwc = &event->hw;
899 bool needed_cb = pebs_needs_sched_cb(cpuc);
859 900
860 if (first_pebs || ds->pebs_interrupt_threshold > threshold) 901 cpuc->n_pebs--;
861 ds->pebs_interrupt_threshold = threshold; 902 if (hwc->flags & PERF_X86_EVENT_FREERUNNING)
903 cpuc->n_large_pebs--;
904
905 pebs_update_state(needed_cb, cpuc, event->ctx->pmu);
862} 906}
863 907
864void intel_pmu_pebs_disable(struct perf_event *event) 908void intel_pmu_pebs_disable(struct perf_event *event)
865{ 909{
866 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); 910 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
867 struct hw_perf_event *hwc = &event->hw; 911 struct hw_perf_event *hwc = &event->hw;
868 struct debug_store *ds = cpuc->ds;
869 bool large_pebs = ds->pebs_interrupt_threshold >
870 ds->pebs_buffer_base + x86_pmu.pebs_record_size;
871 912
872 if (large_pebs) 913 if (cpuc->n_pebs == cpuc->n_large_pebs)
873 intel_pmu_drain_pebs_buffer(); 914 intel_pmu_drain_pebs_buffer();
874 915
875 cpuc->pebs_enabled &= ~(1ULL << hwc->idx); 916 cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
@@ -879,9 +920,6 @@ void intel_pmu_pebs_disable(struct perf_event *event)
879 else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST) 920 else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
880 cpuc->pebs_enabled &= ~(1ULL << 63); 921 cpuc->pebs_enabled &= ~(1ULL << 63);
881 922
882 if (large_pebs && !pebs_is_enabled(cpuc))
883 perf_sched_cb_dec(event->ctx->pmu);
884
885 if (cpuc->enabled) 923 if (cpuc->enabled)
886 wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled); 924 wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
887 925