mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
To: "Peter Zijlstra (Intel)" <peterz@infradead.org>,
	Juri Lelli <juri.lelli@redhat.com>,
	Vincent Guittot <vincent.guittot@linaro.org>
Cc: Ricardo Neri <ricardo.neri@intel.com>,
	"Ravi V. Shankar" <ravi.v.shankar@intel.com>,
	Ben Segall <bsegall@google.com>,
	Daniel Bristot de Oliveira <bristot@redhat.com>,
	Dietmar Eggemann <dietmar.eggemann@arm.com>,
	Len Brown <len.brown@intel.com>, Mel Gorman <mgorman@suse.de>,
	"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
	Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Tim Chen <tim.c.chen@linux.intel.com>,
	Valentin Schneider <vschneid@redhat.com>,
	Lukasz Luba <lukasz.luba@arm.com>,
	Ionela Voinescu <ionela.voinescu@arm.com>,
	Zhao Liu <zhao1.liu@intel.com>,
	"Yuan, Perry" <Perry.Yuan@amd.com>,
	x86@kernel.org,
	"Joel Fernandes (Google)" <joel@joelfernandes.org>,
	linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
	Ricardo Neri <ricardo.neri-calderon@linux.intel.com>,
	"Tim C . Chen" <tim.c.chen@intel.com>,
	Zhao Liu <zhao1.liu@linux.intel.com>
Subject: [PATCH v4 14/24] thermal: intel: hfi: Store per-CPU IPCC scores
Date: Mon, 12 Jun 2023 21:24:12 -0700	[thread overview]
Message-ID: <20230613042422.5344-15-ricardo.neri-calderon@linux.intel.com> (raw)
In-Reply-To: <20230613042422.5344-1-ricardo.neri-calderon@linux.intel.com>

The scheduler reads the IPCC scores when balancing load. These reads can
occur frequently and originate from many CPUs. Hardware may also
occasionally update the HFI table. Controlling access with locks would
cause contention.

Cache the IPCC scores in separate per-CPU variables that the scheduler can
use. Use a seqcount to synchronize memory accesses to these cached values.
This eliminates the need for locks, as the sequence counter provides the
memory ordering required to prevent the use of stale data.

The HFI delayed workqueue guarantees that only one CPU writes the cached
IPCC scores. The frequency of updates is low (every CONFIG_HZ jiffies or
less), and the number of writes per update is in the order of tens. Writes
should not starve reads.

Only cache IPCC scores in this changeset. A subsequent changeset will
use these scores.

Cc: Ben Segall <bsegall@google.com>
Cc: Daniel Bristot de Oliveira <bristot@redhat.com>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Ionela Voinescu <ionela.voinescu@arm.com>
Cc: Joel Fernandes (Google) <joel@joelfernandes.org>
Cc: Len Brown <len.brown@intel.com>
Cc: Lukasz Luba <lukasz.luba@arm.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Perry Yuan <Perry.Yuan@amd.com>
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: Zhao Liu <zhao1.liu@linux.intel.com>
Cc: x86@kernel.org
Cc: linux-pm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
Changes since v3:
 * As Rafael requested, I reworked the memory ordering of the cached IPCC
   scores. I selected a seqcount as is less expensive than a memory
   barrier, which is not necessary anyways.
 * Made alloc_hfi_ipcc_scores() return -ENOMEM on allocation failure.
   (Rafael)
 * Added a comment to describe hfi_ipcc_scores. (Rafael)

Changes since v2:
 * Only create these per-CPU variables when Intel Thread Director is
   supported.

Changes since v1:
 * Added this patch.
---
 drivers/thermal/intel/intel_hfi.c | 66 +++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/drivers/thermal/intel/intel_hfi.c b/drivers/thermal/intel/intel_hfi.c
index 20ee4264dcd4..d822ed0bb5c1 100644
--- a/drivers/thermal/intel/intel_hfi.c
+++ b/drivers/thermal/intel/intel_hfi.c
@@ -29,9 +29,11 @@
 #include <linux/kernel.h>
 #include <linux/math.h>
 #include <linux/mutex.h>
+#include <linux/percpu.h>
 #include <linux/percpu-defs.h>
 #include <linux/printk.h>
 #include <linux/processor.h>
+#include <linux/seqlock.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
@@ -180,6 +182,62 @@ static struct workqueue_struct *hfi_updates_wq;
 #define HFI_UPDATE_INTERVAL		HZ
 #define HFI_MAX_THERM_NOTIFY_COUNT	16
 
+/* A cache of the HFI perf capabilities for lockless access. */
+static int __percpu *hfi_ipcc_scores;
+/* Sequence counter for hfi_ipcc_scores */
+static seqcount_t hfi_ipcc_seqcount = SEQCNT_ZERO(hfi_ipcc_seqcount);
+
+static int alloc_hfi_ipcc_scores(void)
+{
+	if (!cpu_feature_enabled(X86_FEATURE_ITD))
+		return 0;
+
+	hfi_ipcc_scores = __alloc_percpu(sizeof(*hfi_ipcc_scores) *
+					 hfi_features.nr_classes,
+					 sizeof(*hfi_ipcc_scores));
+
+	return hfi_ipcc_scores ? 0 : -ENOMEM;
+}
+
+static void set_hfi_ipcc_scores(struct hfi_instance *hfi_instance)
+{
+	int cpu;
+
+	if (!cpu_feature_enabled(X86_FEATURE_ITD))
+		return;
+
+	/*
+	 * Serialize with writes to the HFI table. It also protects the write
+	 * loop against seqcount readers running in interrupt context.
+	 */
+	raw_spin_lock_irq(&hfi_instance->table_lock);
+	/*
+	 * The seqcount implies store-release semantics to order stores with
+	 * lockless loads from the seqcount read side. It also implies a
+	 * compiler barrier.
+	 */
+	write_seqcount_begin(&hfi_ipcc_seqcount);
+	for_each_cpu(cpu, hfi_instance->cpus) {
+		int c, *scores;
+		s16 index;
+
+		index = per_cpu(hfi_cpu_info, cpu).index;
+		scores = per_cpu_ptr(hfi_ipcc_scores, cpu);
+
+		for (c = 0;  c < hfi_features.nr_classes; c++) {
+			struct hfi_cpu_data *caps;
+
+			caps = hfi_instance->data +
+			       index * hfi_features.cpu_stride +
+			       c * hfi_features.class_stride;
+			scores[c] = caps->perf_cap;
+		}
+	}
+
+	write_seqcount_end(&hfi_ipcc_seqcount);
+	raw_spin_unlock_irq(&hfi_instance->table_lock);
+}
+
 /**
  * intel_hfi_read_classid() - Read the currrent classid
  * @classid:	Variable to which the classid will be written.
@@ -275,6 +333,8 @@ static void update_capabilities(struct hfi_instance *hfi_instance)
 		thermal_genl_cpu_capability_event(cpu_count, &cpu_caps[i]);
 
 	kfree(cpu_caps);
+
+	set_hfi_ipcc_scores(hfi_instance);
 out:
 	mutex_unlock(&hfi_instance_lock);
 }
@@ -618,8 +678,14 @@ void __init intel_hfi_init(void)
 	if (!hfi_updates_wq)
 		goto err_nomem;
 
+	if (alloc_hfi_ipcc_scores())
+		goto err_ipcc;
+
 	return;
 
+err_ipcc:
+	destroy_workqueue(hfi_updates_wq);
+
 err_nomem:
 	for (j = 0; j < i; ++j) {
 		hfi_instance = &hfi_instances[j];
-- 
2.25.1


  parent reply	other threads:[~2023-06-13  4:23 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-13  4:23 [PATCH v4 00/24] sched: Introduce classes of tasks for load balance Ricardo Neri
2023-06-13  4:23 ` [PATCH v4 01/24] sched/task_struct: Introduce IPC classes of tasks Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 02/24] sched: Add interfaces for IPC classes Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 03/24] sched/core: Initialize the IPC class of a new task Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 04/24] sched/core: Add user_tick as argument to scheduler_tick() Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 05/24] sched/core: Update the IPC class of the current task Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 06/24] sched/fair: Collect load-balancing stats for IPC classes Ricardo Neri
2023-06-14  0:29   ` Ricardo Neri
2023-06-22  9:01   ` Ionela Voinescu
2023-06-24  0:01     ` Ricardo Neri
2023-06-26 19:52       ` Tim Chen
2023-07-06 23:40         ` Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 07/24] sched/fair: Compute IPC class scores for load balancing Ricardo Neri
2023-06-22  9:02   ` Ionela Voinescu
2023-06-25 20:11     ` Ricardo Neri
2023-06-26 21:01       ` Tim Chen
2023-07-06 23:48         ` Ricardo Neri
2023-06-27 15:19       ` Ionela Voinescu
2023-06-13  4:24 ` [PATCH v4 08/24] sched/fair: Use IPCC stats to break ties between asym_packing sched groups Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 09/24] sched/fair: Use IPCC stats to break ties between fully_busy SMT groups Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 10/24] sched/fair: Use IPCC scores to select a busiest runqueue Ricardo Neri
2023-06-22  9:03   ` Ionela Voinescu
2023-06-24  0:25     ` Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 11/24] thermal: intel: hfi: Introduce Intel Thread Director classes Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 12/24] x86/cpufeatures: Add the Intel Thread Director feature definitions Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 13/24] x86/sched: Update the IPC class of the current task Ricardo Neri
2023-06-13  4:24 ` Ricardo Neri [this message]
2023-06-29 18:53   ` [PATCH v4 14/24] thermal: intel: hfi: Store per-CPU IPCC scores Rafael J. Wysocki
2023-07-06 23:23     ` Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 15/24] thermal: intel: hfi: Report the IPC class score of a CPU Ricardo Neri
2023-06-29 18:56   ` Rafael J. Wysocki
2023-07-06 23:10     ` Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 16/24] thermal: intel: hfi: Define a default class for unclassified tasks Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 17/24] thermal: intel: hfi: Enable the Intel Thread Director Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 18/24] sched/task_struct: Add helpers for IPC classification Ricardo Neri
2023-06-22 10:20   ` Ionela Voinescu
2023-06-25 20:23     ` Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 19/24] sched/core: Initialize helpers of task classification Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 20/24] sched/fair: Introduce sched_smt_siblings_idle() Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 21/24] x86/sched/ipcc: Implement model-specific checks for task classification Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 22/24] x86/cpufeatures: Add feature bit for HRESET Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 23/24] x86/hreset: Configure history reset Ricardo Neri
2023-06-13  4:24 ` [PATCH v4 24/24] x86/process: Reset hardware history in context switch Ricardo Neri

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230613042422.5344-15-ricardo.neri-calderon@linux.intel.com \
    --to=ricardo.neri-calderon@linux.intel.com \
    --cc=Perry.Yuan@amd.com \
    --cc=bristot@redhat.com \
    --cc=bsegall@google.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=ionela.voinescu@arm.com \
    --cc=joel@joelfernandes.org \
    --cc=juri.lelli@redhat.com \
    --cc=len.brown@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=lukasz.luba@arm.com \
    --cc=mgorman@suse.de \
    --cc=peterz@infradead.org \
    --cc=rafael.j.wysocki@intel.com \
    --cc=ravi.v.shankar@intel.com \
    --cc=ricardo.neri@intel.com \
    --cc=rostedt@goodmis.org \
    --cc=srinivas.pandruvada@linux.intel.com \
    --cc=tim.c.chen@intel.com \
    --cc=tim.c.chen@linux.intel.com \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    --cc=x86@kernel.org \
    --cc=zhao1.liu@intel.com \
    --cc=zhao1.liu@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®