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.shiva...@linux.intel.com>
---
 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

Reply via email to