[PATCH v4 21/24] x86/sched/ipcc: Implement model-specific checks for task classification

From: Ricardo Neri
Date: Tue Jun 13 2023 - 00:25:58 EST


In Alder Lake and Raptor Lake, the result of thread classification is more
accurate when only one SMT sibling is busy. Classification results for
class 2 and 3 are always reliable.

Changing the classification of a task too frequently may lead to
unnecessary migrations.

Only update the class of a task if it is considered accurate and has been
constant during four consecutive user ticks.

Cc: Ben Segall <bsegall@xxxxxxxxxx>
Cc: Daniel Bristot de Oliveira <bristot@xxxxxxxxxx>
Cc: Dietmar Eggemann <dietmar.eggemann@xxxxxxx>
Cc: Ionela Voinescu <ionela.voinescu@xxxxxxx>
Cc: Joel Fernandes (Google) <joel@xxxxxxxxxxxxxxxxx>
Cc: Len Brown <len.brown@xxxxxxxxx>
Cc: Lukasz Luba <lukasz.luba@xxxxxxx>
Cc: Mel Gorman <mgorman@xxxxxxx>
Cc: Perry Yuan <Perry.Yuan@xxxxxxx>
Cc: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
Cc: Srinivas Pandruvada <srinivas.pandruvada@xxxxxxxxxxxxxxx>
Cc: Steven Rostedt <rostedt@xxxxxxxxxxx>
Cc: Tim C. Chen <tim.c.chen@xxxxxxxxx>
Cc: Valentin Schneider <vschneid@xxxxxxxxxx>
Cc: Zhao Liu <zhao1.liu@xxxxxxxxxxxxxxx>
Cc: x86@xxxxxxxxxx
Cc: linux-pm@xxxxxxxxxxxxxxx
Cc: linux-kernel@xxxxxxxxxxxxxxx
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@xxxxxxxxxxxxxxx>
---
Changes since v3:
* Relocated this code to arch/x86/kernel/sched_ipcc.c (Rafael)

Changes since v2:
* None

Changes since v1:
* Adjusted the result the classification of Intel Thread Director to start
at class 1. Class 0 for the scheduler means that the task is
unclassified.
* Used the new names of the IPC classes members in task_struct.
* Reworked helper functions to use sched_smt_siblings_idle() to query
the idle state of the SMT siblings of a CPU.
---
arch/x86/kernel/sched_ipcc.c | 60 +++++++++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/sched_ipcc.c b/arch/x86/kernel/sched_ipcc.c
index 685e7b3b5375..dd73fc8be49b 100644
--- a/arch/x86/kernel/sched_ipcc.c
+++ b/arch/x86/kernel/sched_ipcc.c
@@ -18,11 +18,67 @@

#include <linux/sched.h>

+#include <asm/intel-family.h>
#include <asm/topology.h>

+#define CLASS_DEBOUNCER_SKIPS 4
+
+/**
+ * debounce_and_update_class() - Process and update a task's classification
+ *
+ * @p: The task of which the classification will be updated
+ * @new_ipcc: The new IPC classification
+ *
+ * Update the classification of @p with the new value that hardware provides.
+ * Only update the classification of @p if it has been the same during
+ * CLASS_DEBOUNCER_SKIPS consecutive ticks.
+ */
+static void debounce_and_update_class(struct task_struct *p, u8 new_ipcc)
+{
+ u16 debounce_skip;
+
+ /* The class of @p changed. Only restart the debounce counter. */
+ if (p->ipcc_tmp != new_ipcc) {
+ p->ipcc_cntr = 1;
+ goto out;
+ }
+
+ /*
+ * The class of @p did not change. Update it if it has been the same
+ * for CLASS_DEBOUNCER_SKIPS user ticks.
+ */
+ debounce_skip = p->ipcc_cntr + 1;
+ if (debounce_skip < CLASS_DEBOUNCER_SKIPS)
+ p->ipcc_cntr++;
+ else
+ p->ipcc = new_ipcc;
+
+out:
+ p->ipcc_tmp = new_ipcc;
+}
+
+static bool classification_is_accurate(u8 hfi_class, bool smt_siblings_idle)
+{
+ switch (boot_cpu_data.x86_model) {
+ case INTEL_FAM6_ALDERLAKE:
+ case INTEL_FAM6_ALDERLAKE_L:
+ case INTEL_FAM6_RAPTORLAKE:
+ case INTEL_FAM6_RAPTORLAKE_P:
+ case INTEL_FAM6_RAPTORLAKE_S:
+ if (hfi_class == 3 || hfi_class == 2 || smt_siblings_idle)
+ return true;
+
+ return false;
+
+ default:
+ return false;
+ }
+}
+
void intel_update_ipcc(struct task_struct *curr)
{
u8 hfi_class;
+ bool idle;

if (intel_hfi_read_classid(&hfi_class))
return;
@@ -31,5 +87,7 @@ void intel_update_ipcc(struct task_struct *curr)
* 0 is a valid classification for Intel Thread Director. A scheduler
* IPCC class of 0 means that the task is unclassified. Adjust.
*/
- curr->ipcc = hfi_class + 1;
+ idle = sched_smt_siblings_idle(task_cpu(curr));
+ if (classification_is_accurate(hfi_class, idle))
+ debounce_and_update_class(curr, hfi_class + 1);
}
--
2.25.1