[RFC PATCH 15/23] thermal: intel: hfi: Report per-cpu class-specific performance scores

Ricardo Neri
2022-09-09T23:07:26Z

Support the arch_get_task_class_score() interface of the scheduler. Use the
data that Intel Thread Director provides to inform the scheduler the
performance of a class of tasks when placed on a given CPU.

Cc: Ben Segall <bsegall@google.com>
Cc: Daniel Bristot de Oliveira <bristot@redhat.com>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Len Brown <len.brown@intel.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Tim C. Chen <tim.c.chen@intel.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: x86@kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
arch/x86/include/asm/topology.h | 2 ++
drivers/thermal/intel/intel_hfi.c | 40 +++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+)

diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 9c6df4fd9414..2ed234104ef4 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -230,9 +230,11 @@ void init_freq_invariance_cppc(void);
#ifdef CONFIG_INTEL_THREAD_DIRECTOR
int intel_hfi_has_task_classes(void);
void intel_hfi_update_task_class(struct task_struct *curr, bool smt_siblings_idle);
+int intel_hfi_get_task_class_score(int class, int cpu);

#define arch_has_task_classes intel_hfi_has_task_classes
#define arch_update_task_class intel_hfi_update_task_class
+#define arch_get_task_class_score intel_hfi_get_task_class_score
#endif

#endif /* _ASM_X86_TOPOLOGY_H */
diff --git a/drivers/thermal/intel/intel_hfi.c b/drivers/thermal/intel/intel_hfi.c
index f46d9331f912..1b6072c828ff 100644
--- a/drivers/thermal/intel/intel_hfi.c
+++ b/drivers/thermal/intel/intel_hfi.c
@@ -205,6 +205,46 @@ void intel_hfi_update_task_class(struct task_struct *curr, bool smt_siblings_idl

curr->class = msr.split.classid;
}
+
+static void get_one_hfi_cap(struct hfi_instance *hfi_instance, s16 index,
+ struct hfi_cpu_data *hfi_caps, int class)
+{
+ struct hfi_cpu_data *caps;
+
+ /* Find the capabilities of @cpu */
+ caps = hfi_instance->data + index * hfi_features.cpu_stride +
+ class * hfi_features.class_stride;
+ memcpy(hfi_caps, caps, sizeof(*hfi_caps));
+}
+
+int intel_hfi_get_task_class_score(int class, int cpu)
+{
+ struct hfi_cpu_info *info = &per_cpu(hfi_cpu_info, cpu);
+ struct hfi_instance *instance;
+ struct hfi_cpu_data caps;
+ unsigned long flags;
+ int cap;
+
+ if (cpu < 0 || cpu >= nr_cpu_ids)
+ return -EINVAL;
+
+ if (class == TASK_CLASS_UNCLASSIFIED)
+ return -EINVAL;
+
+ if (class >= (int)hfi_features.nr_classes)
+ return -EINVAL;
+
+ instance = info->hfi_instance;
+ if (!instance)
+ return -ENOENT;
+
+ raw_spin_lock_irqsave(&instance->table_lock, flags);
+ get_one_hfi_cap(instance, info->index, &caps, class);
+ cap = caps.perf_cap;
+ raw_spin_unlock_irqrestore(&instance->table_lock, flags);
+
+ return cap;
+}
#endif /* CONFIG_INTEL_THREAD_DIRECTOR */

static void get_hfi_caps(struct hfi_instance *hfi_instance,
--
2.25.1