aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/perf_event_intel_cqm.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2015-05-18 20:00:58 -0400
committerIngo Molnar <mingo@kernel.org>2015-05-27 03:17:41 -0400
commitbf926731e1585ccad029ca2fad1444fee082b78d (patch)
tree3565ea28fe99cc3b1ef04fab5b9069d4f95f5695 /arch/x86/kernel/cpu/perf_event_intel_cqm.c
parent43d0c2f6dcd07ffc0de658a7fbeeb63c806e9caa (diff)
perf/x86/intel/cqm: Add storage for 'closid' and clean up 'struct intel_pqr_state'
'closid' (CLass Of Service ID) is used for the Class based Cache Allocation Technology (CAT). Add explicit storage to the per cpu cache for it, so it can be used later with the CAT support (requires to move the per cpu data). While at it: - Rename the structure to intel_pqr_state which reflects the actual purpose of the struct: cache values which go into the PQR MSR - Rename 'cnt' to rmid_usecnt which reflects the actual purpose of the counter. - Document the structure and the struct members. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Matt Fleming <matt.fleming@intel.com> Cc: Kanaka Juvva <kanaka.d.juvva@intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Vikas Shivappa <vikas.shivappa@linux.intel.com> Cc: Will Auld <will.auld@intel.com> Link: http://lkml.kernel.org/r/20150518235150.240899319@linutronix.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel/cpu/perf_event_intel_cqm.c')
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_cqm.c50
1 files changed, 27 insertions, 23 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_cqm.c b/arch/x86/kernel/cpu/perf_event_intel_cqm.c
index 8241b64d34c4..8233b29bdd35 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_cqm.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_cqm.c
@@ -16,18 +16,32 @@
16static unsigned int cqm_max_rmid = -1; 16static unsigned int cqm_max_rmid = -1;
17static unsigned int cqm_l3_scale; /* supposedly cacheline size */ 17static unsigned int cqm_l3_scale; /* supposedly cacheline size */
18 18
19struct intel_cqm_state { 19/**
20 * struct intel_pqr_state - State cache for the PQR MSR
21 * @rmid: The cached Resource Monitoring ID
22 * @closid: The cached Class Of Service ID
23 * @rmid_usecnt: The usage counter for rmid
24 *
25 * The upper 32 bits of MSR_IA32_PQR_ASSOC contain closid and the
26 * lower 10 bits rmid. The update to MSR_IA32_PQR_ASSOC always
27 * contains both parts, so we need to cache them.
28 *
29 * The cache also helps to avoid pointless updates if the value does
30 * not change.
31 */
32struct intel_pqr_state {
20 u32 rmid; 33 u32 rmid;
21 int cnt; 34 u32 closid;
35 int rmid_usecnt;
22}; 36};
23 37
24/* 38/*
25 * The cached intel_cqm_state is strictly per CPU and can never be 39 * The cached intel_pqr_state is strictly per CPU and can never be
26 * updated from a remote CPU. Both functions which modify the state 40 * updated from a remote CPU. Both functions which modify the state
27 * (intel_cqm_event_start and intel_cqm_event_stop) are called with 41 * (intel_cqm_event_start and intel_cqm_event_stop) are called with
28 * interrupts disabled, which is sufficient for the protection. 42 * interrupts disabled, which is sufficient for the protection.
29 */ 43 */
30static DEFINE_PER_CPU(struct intel_cqm_state, cqm_state); 44static DEFINE_PER_CPU(struct intel_pqr_state, pqr_state);
31 45
32/* 46/*
33 * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru. 47 * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru.
@@ -966,7 +980,7 @@ out:
966 980
967static void intel_cqm_event_start(struct perf_event *event, int mode) 981static void intel_cqm_event_start(struct perf_event *event, int mode)
968{ 982{
969 struct intel_cqm_state *state = this_cpu_ptr(&cqm_state); 983 struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
970 u32 rmid = event->hw.cqm_rmid; 984 u32 rmid = event->hw.cqm_rmid;
971 985
972 if (!(event->hw.cqm_state & PERF_HES_STOPPED)) 986 if (!(event->hw.cqm_state & PERF_HES_STOPPED))
@@ -974,7 +988,7 @@ static void intel_cqm_event_start(struct perf_event *event, int mode)
974 988
975 event->hw.cqm_state &= ~PERF_HES_STOPPED; 989 event->hw.cqm_state &= ~PERF_HES_STOPPED;
976 990
977 if (state->cnt++) { 991 if (state->rmid_usecnt++) {
978 if (!WARN_ON_ONCE(state->rmid != rmid)) 992 if (!WARN_ON_ONCE(state->rmid != rmid))
979 return; 993 return;
980 } else { 994 } else {
@@ -982,17 +996,12 @@ static void intel_cqm_event_start(struct perf_event *event, int mode)
982 } 996 }
983 997
984 state->rmid = rmid; 998 state->rmid = rmid;
985 /* 999 wrmsr(MSR_IA32_PQR_ASSOC, rmid, state->closid);
986 * This is actually wrong, as the upper 32 bit MSR contain the
987 * closid which is used for configuring the Cache Allocation
988 * Technology component.
989 */
990 wrmsr(MSR_IA32_PQR_ASSOC, rmid, 0);
991} 1000}
992 1001
993static void intel_cqm_event_stop(struct perf_event *event, int mode) 1002static void intel_cqm_event_stop(struct perf_event *event, int mode)
994{ 1003{
995 struct intel_cqm_state *state = this_cpu_ptr(&cqm_state); 1004 struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
996 1005
997 if (event->hw.cqm_state & PERF_HES_STOPPED) 1006 if (event->hw.cqm_state & PERF_HES_STOPPED)
998 return; 1007 return;
@@ -1001,15 +1010,9 @@ static void intel_cqm_event_stop(struct perf_event *event, int mode)
1001 1010
1002 intel_cqm_event_read(event); 1011 intel_cqm_event_read(event);
1003 1012
1004 if (!--state->cnt) { 1013 if (!--state->rmid_usecnt) {
1005 state->rmid = 0; 1014 state->rmid = 0;
1006 /* 1015 wrmsr(MSR_IA32_PQR_ASSOC, 0, state->closid);
1007 * This is actually wrong, as the upper 32 bit of the
1008 * MSR contain the closid which is used for
1009 * configuring the Cache Allocation Technology
1010 * component.
1011 */
1012 wrmsr(MSR_IA32_PQR_ASSOC, 0, 0);
1013 } else { 1016 } else {
1014 WARN_ON_ONCE(!state->rmid); 1017 WARN_ON_ONCE(!state->rmid);
1015 } 1018 }
@@ -1247,11 +1250,12 @@ static inline void cqm_pick_event_reader(int cpu)
1247 1250
1248static void intel_cqm_cpu_prepare(unsigned int cpu) 1251static void intel_cqm_cpu_prepare(unsigned int cpu)
1249{ 1252{
1250 struct intel_cqm_state *state = &per_cpu(cqm_state, cpu); 1253 struct intel_pqr_state *state = &per_cpu(pqr_state, cpu);
1251 struct cpuinfo_x86 *c = &cpu_data(cpu); 1254 struct cpuinfo_x86 *c = &cpu_data(cpu);
1252 1255
1253 state->rmid = 0; 1256 state->rmid = 0;
1254 state->cnt = 0; 1257 state->closid = 0;
1258 state->rmid_usecnt = 0;
1255 1259
1256 WARN_ON(c->x86_cache_max_rmid != cqm_max_rmid); 1260 WARN_ON(c->x86_cache_max_rmid != cqm_max_rmid);
1257 WARN_ON(c->x86_cache_occ_scale != cqm_l3_scale); 1261 WARN_ON(c->x86_cache_occ_scale != cqm_l3_scale);