[PATCH 17/21] x86/intel_rdt/cqm: Add sched_in support

From: Vikas Shivappa
Date: Mon Jun 26 2017 - 14:55:31 EST


OS associates an RMID/CLOSid to a task by writing the per CPU
IA32_PQR_ASSOC MSR when a task is scheduled in.

The sched_in code will stay as no-op unless we are running on Intel SKU
which supports either resource control or monitoring and we also enable
them by mounting the resctrl fs. The per cpu CLOSid/RMID values are
cached and the write is performed only when a task with a different
CLOSid/RMID is scheduled in.

Signed-off-by: Vikas Shivappa <vikas.shivappa@xxxxxxxxxxxxxxx>
---
arch/x86/include/asm/intel_rdt_sched.h | 47 ++++++++++++++++++++++++----------
1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/intel_rdt_sched.h b/arch/x86/include/asm/intel_rdt_sched.h
index 4dee77b..7c823c4 100644
--- a/arch/x86/include/asm/intel_rdt_sched.h
+++ b/arch/x86/include/asm/intel_rdt_sched.h
@@ -27,27 +27,31 @@ struct intel_pqr_state {

DECLARE_PER_CPU(struct intel_pqr_state, pqr_state);
DECLARE_PER_CPU_READ_MOSTLY(int, cpu_closid);
+DECLARE_PER_CPU_READ_MOSTLY(int, cpu_rmid);
DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
+DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key);
+DECLARE_STATIC_KEY_FALSE(rdt_enable_key);

/*
- * intel_rdt_sched_in() - Writes the task's CLOSid to IA32_PQR_MSR
+ * __intel_rdt_sched_in() - Writes the task's CLOSid/RMID to IA32_PQR_MSR
*
* Following considerations are made so that this has minimal impact
* on scheduler hot path:
* - This will stay as no-op unless we are running on an Intel SKU
- * which supports resource control and we enable by mounting the
- * resctrl file system.
- * - Caches the per cpu CLOSid values and does the MSR write only
- * when a task with a different CLOSid is scheduled in.
+ * which supports resource control or monitoring and we enable by
+ * mounting the resctrl file system.
+ * - Caches the per cpu CLOSid/RMID values and does the MSR write only
+ * when a task with a different CLOSid/RMID is scheduled in.
*
* Must be called with preemption disabled.
*/
-static inline void intel_rdt_sched_in(void)
+static void __intel_rdt_sched_in(void)
{
- if (static_branch_likely(&rdt_alloc_enable_key)) {
- struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
- int closid;
+ struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
+ u32 closid = 0;
+ u32 rmid = 0;

+ if (static_branch_likely(&rdt_alloc_enable_key)) {
/*
* If this task has a closid assigned, use it.
* Else use the closid assigned to this cpu.
@@ -55,14 +59,31 @@ static inline void intel_rdt_sched_in(void)
closid = current->closid;
if (closid == 0)
closid = this_cpu_read(cpu_closid);
+ }
+
+ if (static_branch_likely(&rdt_mon_enable_key)) {
+ /*
+ * If this task has a rmid assigned, use it.
+ * Else use the rmid assigned to this cpu.
+ */
+ rmid = current->rmid;
+ if (rmid == 0)
+ rmid = this_cpu_read(cpu_rmid);
+ }

- if (closid != state->closid) {
- state->closid = closid;
- wrmsr(IA32_PQR_ASSOC, state->rmid, closid);
- }
+ if (closid != state->closid || rmid != state->rmid) {
+ state->closid = closid;
+ state->rmid = rmid;
+ wrmsr(IA32_PQR_ASSOC, rmid, closid);
}
}

+static inline void intel_rdt_sched_in(void)
+{
+ if (static_branch_likely(&rdt_enable_key))
+ __intel_rdt_sched_in();
+}
+
#else

static inline void intel_rdt_sched_in(void) {}
--
1.9.1