[v1,4/9] x86/resctrl: Flush MBM event counts on soft RMID change

Message ID 20230421141723.2405942-5-peternewman@google.com
State New
Headers
Series x86/resctrl: Use soft RMIDs for reliable MBM on AMD |

Commit Message

Peter Newman April 21, 2023, 2:17 p.m. UTC
  To implement soft RMIDs, context switch must detect when the current
soft RMID is changing and if so, flush the CPU's MBM event counts to the
outgoing soft RMID.

To avoid impacting context switch performance in the non-soft RMID case,
protect the new logic with a static branch.

Co-developed-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Newman <peternewman@google.com>
---
 arch/x86/include/asm/resctrl.h         | 27 +++++++++++++++++++++++++-
 arch/x86/kernel/cpu/resctrl/rdtgroup.c |  1 +
 2 files changed, 27 insertions(+), 1 deletion(-)
  

Comments

Reinette Chatre May 11, 2023, 9:37 p.m. UTC | #1
Hi Peter,

On 4/21/2023 7:17 AM, Peter Newman wrote:
> To implement soft RMIDs, context switch must detect when the current
> soft RMID is changing and if so, flush the CPU's MBM event counts to the
> outgoing soft RMID.
> 
> To avoid impacting context switch performance in the non-soft RMID case,
> protect the new logic with a static branch.
> 
> Co-developed-by: Stephane Eranian <eranian@google.com>
> Signed-off-by: Stephane Eranian <eranian@google.com>
> Signed-off-by: Peter Newman <peternewman@google.com>
> ---
>  arch/x86/include/asm/resctrl.h         | 27 +++++++++++++++++++++++++-
>  arch/x86/kernel/cpu/resctrl/rdtgroup.c |  1 +
>  2 files changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h
> index e7acf118d770..50d05e883dbb 100644
> --- a/arch/x86/include/asm/resctrl.h
> +++ b/arch/x86/include/asm/resctrl.h
> @@ -36,6 +36,9 @@ DECLARE_PER_CPU(struct resctrl_pqr_state, pqr_state);
>  DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
>  DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
>  DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key);
> +DECLARE_STATIC_KEY_FALSE(rdt_soft_rmid_enable_key);
> +
> +void resctrl_mbm_flush_cpu(void);
>  
>  /*
>   * __resctrl_sched_in() - Writes the task's CLOSid/RMID to IA32_PQR_MSR
> @@ -75,9 +78,31 @@ static inline void __resctrl_sched_in(struct task_struct *tsk)
>  	}
>  
>  	if (closid != state->cur_closid || rmid != state->cur_rmid) {
> +		if (static_branch_likely(&rdt_soft_rmid_enable_key)) {

Could you please elaborate on the choice of static_branch_likely() (as opposed
to static_branch_unlikely())?

Reinette
  

Patch

diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h
index e7acf118d770..50d05e883dbb 100644
--- a/arch/x86/include/asm/resctrl.h
+++ b/arch/x86/include/asm/resctrl.h
@@ -36,6 +36,9 @@  DECLARE_PER_CPU(struct resctrl_pqr_state, pqr_state);
 DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
 DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
 DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key);
+DECLARE_STATIC_KEY_FALSE(rdt_soft_rmid_enable_key);
+
+void resctrl_mbm_flush_cpu(void);
 
 /*
  * __resctrl_sched_in() - Writes the task's CLOSid/RMID to IA32_PQR_MSR
@@ -75,9 +78,31 @@  static inline void __resctrl_sched_in(struct task_struct *tsk)
 	}
 
 	if (closid != state->cur_closid || rmid != state->cur_rmid) {
+		if (static_branch_likely(&rdt_soft_rmid_enable_key)) {
+			/*
+			 * Flush current event counts to outgoing soft rmid
+			 * when it changes.
+			 */
+			if (rmid != state->cur_rmid)
+				resctrl_mbm_flush_cpu();
+
+			/*
+			 * rmid never changes in this mode, so skip wrmsr if the
+			 * closid is not changing.
+			 */
+			if (closid != state->cur_closid)
+				wrmsr(MSR_IA32_PQR_ASSOC, state->hw_rmid,
+				      closid);
+		} else {
+			wrmsr(MSR_IA32_PQR_ASSOC, rmid, closid);
+		}
+
+		/*
+		 * Record new closid/rmid last so soft rmid case can detect
+		 * changes.
+		 */
 		state->cur_closid = closid;
 		state->cur_rmid = rmid;
-		wrmsr(MSR_IA32_PQR_ASSOC, rmid, closid);
 	}
 }
 
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index 6ad33f355861..c10f4798156a 100644
--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -35,6 +35,7 @@ 
 DEFINE_STATIC_KEY_FALSE(rdt_enable_key);
 DEFINE_STATIC_KEY_FALSE(rdt_mon_enable_key);
 DEFINE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
+DEFINE_STATIC_KEY_FALSE(rdt_soft_rmid_enable_key);
 static struct kernfs_root *rdt_root;
 struct rdtgroup rdtgroup_default;
 LIST_HEAD(rdt_all_groups);