From: Vikas Shivappa <vikas.shivappa@linux.intel.com>
To: x86@kernel.org, linux-kernel@vger.kernel.org, tglx@linutronix.de
Cc: hpa@zytor.com, peterz@infradead.org, ravi.v.shankar@intel.com,
vikas.shivappa@intel.com, tony.luck@intel.com,
fenghua.yu@intel.com, andi.kleen@intel.com
Subject: [PATCH 08/21] x86/intel_rdt/cqm: Add RMID(Resource monitoring ID) management
Date: Mon, 26 Jun 2017 11:55:55 -0700 [thread overview]
Message-ID: <1498503368-20173-9-git-send-email-vikas.shivappa@linux.intel.com> (raw)
In-Reply-To: <1498503368-20173-1-git-send-email-vikas.shivappa@linux.intel.com>
Hardware uses RMID(Resource monitoring ID) to keep track of each of the
RDT events associated with tasks. The number of RMIDs is dependent on
the SKU and is enumerated via CPUID. We add support to manage the RMIDs
which include managing the RMID allocation and reading LLC occupancy
for an RMID.
RMID allocation is managed by keeping a free list which is initialized
to all available RMIDs except for RMID 0 which is always reserved for
root group. RMIDs goto a limbo list once they are
freed since the RMIDs are still tagged to cache lines of the tasks which
were using them - thereby still having some occupancy. They continue to
be in limbo list until the occupancy < threshold_occupancy. The
threshold_occupancy is a user configurable value.
OS uses IA32_QM_CTR MSR to read the occupancy associated with an RMID
after programming the IA32_EVENTSEL MSR with the RMID.
Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
---
arch/x86/kernel/cpu/intel_rdt.h | 2 +
arch/x86/kernel/cpu/intel_rdt_monitor.c | 121 ++++++++++++++++++++++++++++++++
2 files changed, 123 insertions(+)
diff --git a/arch/x86/kernel/cpu/intel_rdt.h b/arch/x86/kernel/cpu/intel_rdt.h
index 285f106..cf25b6c 100644
--- a/arch/x86/kernel/cpu/intel_rdt.h
+++ b/arch/x86/kernel/cpu/intel_rdt.h
@@ -20,6 +20,8 @@
#define QOS_L3_MBM_TOTAL_EVENT_ID 0x02
#define QOS_L3_MBM_LOCAL_EVENT_ID 0x03
+#define RMID_VAL_ERROR (1ULL << 63)
+#define RMID_VAL_UNAVAIL (1ULL << 62)
/**
* struct mon_evt - Entry in the event list of a resource
* @evtid: event id
diff --git a/arch/x86/kernel/cpu/intel_rdt_monitor.c b/arch/x86/kernel/cpu/intel_rdt_monitor.c
index a418854..4f4221a 100644
--- a/arch/x86/kernel/cpu/intel_rdt_monitor.c
+++ b/arch/x86/kernel/cpu/intel_rdt_monitor.c
@@ -28,6 +28,9 @@
#include <asm/cpu_device_id.h>
#include "intel_rdt.h"
+#define MSR_IA32_QM_CTR 0x0c8e
+#define MSR_IA32_QM_EVTSEL 0x0c8d
+
enum rmid_recycle_state {
RMID_CHECK = 0,
RMID_DIRTY,
@@ -82,6 +85,124 @@ static inline struct rmid_entry *__rmid_entry(u32 rmid)
return entry;
}
+static u64 __rmid_read(u32 rmid, u32 eventid)
+{
+ u64 val;
+
+ wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid);
+ rdmsrl(MSR_IA32_QM_CTR, val);
+
+ /*
+ * Aside from the ERROR and UNAVAIL bits, the return value is the
+ * count for this @eventid tagged with @rmid.
+ */
+ return val;
+}
+
+/*
+ * Test whether an RMID is dirty(occupancy > threshold_occupancy)
+ */
+static void intel_cqm_stable(void *arg)
+{
+ struct rmid_entry *entry;
+ u64 val;
+
+ /*
+ * Since we are in the IPI already lets mark all the RMIDs
+ * that are dirty
+ */
+ list_for_each_entry(entry, &rmid_limbo_lru, list) {
+ val = __rmid_read(entry->rmid, QOS_L3_OCCUP_EVENT_ID);
+ if (val > intel_cqm_threshold)
+ entry->state = RMID_DIRTY;
+ }
+}
+
+/*
+ * Scan the limbo list and move all entries that are below the
+ * intel_cqm_threshold to the free list.
+ * Return "true" if the limbo list is empty, "false" if there are
+ * still some RMIDs there.
+ */
+static bool try_freeing_limbo_rmid(void)
+{
+ struct rmid_entry *entry, *tmp;
+ struct rdt_resource *r;
+ cpumask_var_t cpu_mask;
+ struct rdt_domain *d;
+ bool ret = true;
+
+ if (list_empty(&rmid_limbo_lru))
+ return ret;
+
+ if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL))
+ return false;
+
+ r = &rdt_resources_all[RDT_RESOURCE_L3];
+
+ list_for_each_entry(d, &r->domains, list)
+ cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask);
+
+ /*
+ * Test whether an RMID is free for each package.
+ */
+ on_each_cpu_mask(cpu_mask, intel_cqm_stable, NULL, true);
+
+ list_for_each_entry_safe(entry, tmp, &rmid_limbo_lru, list) {
+ /*
+ * Ignore the RMIDs that are marked dirty and reset the
+ * state to check for being dirty again later.
+ */
+ if (entry->state == RMID_DIRTY) {
+ entry->state = RMID_CHECK;
+ ret = false;
+ continue;
+ }
+ list_del(&entry->list);
+ list_add_tail(&entry->list, &rmid_free_lru);
+ }
+
+ free_cpumask_var(cpu_mask);
+ return ret;
+}
+
+int alloc_rmid(void)
+{
+ struct rmid_entry *entry;
+ bool ret;
+
+ lockdep_assert_held(&rdtgroup_mutex);
+
+ if (list_empty(&rmid_free_lru)) {
+ ret = try_freeing_limbo_rmid();
+ if (list_empty(&rmid_free_lru))
+ return ret ? -ENOSPC : -EBUSY;
+ }
+
+ entry = list_first_entry(&rmid_free_lru,
+ struct rmid_entry, list);
+ list_del(&entry->list);
+
+ return entry->rmid;
+}
+
+void free_rmid(u32 rmid)
+{
+ struct rmid_entry *entry;
+
+ lockdep_assert_held(&rdtgroup_mutex);
+
+ WARN_ON(!rmid);
+ entry = __rmid_entry(rmid);
+
+ entry->state = RMID_CHECK;
+
+ if (rdt_mon_features & (1 << QOS_L3_OCCUP_EVENT_ID))
+ list_add_tail(&entry->list, &rmid_limbo_lru);
+ else
+ list_add_tail(&entry->list, &rmid_free_lru);
+}
+
static int dom_data_init(struct rdt_resource *r)
{
struct rmid_entry *entry = NULL;
--
1.9.1
next prev parent reply other threads:[~2017-06-26 18:58 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-26 18:55 [PATCH V1 00/21] x86/cqm3: Resctrl based cqm Vikas Shivappa
2017-06-26 18:55 ` [PATCH 01/21] x86/perf/cqm: Wipe out perf " Vikas Shivappa
2017-06-26 18:55 ` [PATCH 02/21] x86/intel_rdt: Fix memory leak during mount Vikas Shivappa
2017-06-30 19:24 ` [tip:x86/urgent] x86/intel_rdt: Fix memory leak on mount failure tip-bot for Vikas Shivappa
2017-06-26 18:55 ` [PATCH 03/21] x86/intel_rdt/cqm: Documentation for resctrl based RDT Monitoring Vikas Shivappa
2017-06-26 18:55 ` [PATCH 04/21] x86/intel_rdt: Introduce a common compile option for RDT Vikas Shivappa
2017-06-26 18:55 ` [PATCH 05/21] x86/intel_rdt: Change file names to accommodate RDT monitor code Vikas Shivappa
2017-06-26 18:55 ` [PATCH 06/21] x86/intel_rdt: Cleanup namespace to support RDT monitoring Vikas Shivappa
2017-06-26 18:55 ` [PATCH 07/21] x86/intel_rdt/cqm: Add RDT monitoring initialization Vikas Shivappa
2017-07-02 9:14 ` Thomas Gleixner
2017-07-06 21:07 ` Shivappa Vikas
2017-06-26 18:55 ` Vikas Shivappa [this message]
2017-07-02 10:05 ` [PATCH 08/21] x86/intel_rdt/cqm: Add RMID(Resource monitoring ID) management Thomas Gleixner
2017-07-03 9:55 ` Thomas Gleixner
2017-07-05 15:34 ` Peter Zijlstra
2017-07-05 17:25 ` Thomas Gleixner
2017-07-11 23:54 ` Shivappa Vikas
2017-07-12 20:14 ` Thomas Gleixner
2017-07-05 17:59 ` Tony Luck
2017-07-06 6:51 ` Thomas Gleixner
2017-06-26 18:55 ` [PATCH 09/21] x86/intel_rdt: Simplify info and base file lists Vikas Shivappa
2017-07-02 10:09 ` Thomas Gleixner
2017-07-06 21:09 ` Shivappa Vikas
2017-06-26 18:55 ` [PATCH 10/21] x86/intel_rdt/cqm: Add info files for RDT monitoring Vikas Shivappa
2017-06-26 18:55 ` [PATCH 11/21] x86/intel_rdt/cqm: Add mkdir support " Vikas Shivappa
2017-07-02 10:58 ` Thomas Gleixner
2017-07-06 21:23 ` Shivappa Vikas
2017-06-26 18:55 ` [PATCH 12/21] x86/intel_rdt/cqm: Add tasks file support Vikas Shivappa
2017-07-02 11:01 ` Thomas Gleixner
2017-07-06 21:25 ` Shivappa Vikas
2017-06-26 18:56 ` [PATCH 13/21] x86/intel_rdt/cqm: Add cpus " Vikas Shivappa
2017-07-02 11:11 ` Thomas Gleixner
2017-07-06 21:26 ` Shivappa Vikas
2017-07-02 12:29 ` Thomas Gleixner
2017-07-06 21:42 ` Shivappa Vikas
2017-07-07 6:44 ` Thomas Gleixner
2017-07-13 18:37 ` Shivappa Vikas
2017-07-13 22:09 ` Shivappa Vikas
2017-06-26 18:56 ` [PATCH 14/21] x86/intel_rdt/cqm: Add mon_data Vikas Shivappa
2017-07-02 12:43 ` Thomas Gleixner
2017-07-06 21:48 ` Shivappa Vikas
2017-07-07 6:22 ` Thomas Gleixner
2017-07-11 21:17 ` Shivappa Vikas
2017-07-11 21:37 ` Luck, Tony
2017-06-26 18:56 ` [PATCH 15/21] x86/intel_rdt/cqm: Add rmdir support Vikas Shivappa
2017-07-02 13:16 ` Thomas Gleixner
2017-07-06 21:49 ` Shivappa Vikas
2017-06-26 18:56 ` [PATCH 16/21] x86/intel_rdt/cqm: Add mount,umount support Vikas Shivappa
2017-07-02 13:22 ` Thomas Gleixner
2017-07-06 21:58 ` Shivappa Vikas
2017-06-26 18:56 ` [PATCH 17/21] x86/intel_rdt/cqm: Add sched_in support Vikas Shivappa
2017-07-02 13:37 ` Thomas Gleixner
2017-07-06 23:35 ` Shivappa Vikas
2017-06-26 18:56 ` [PATCH 18/21] x86/intel_rdt/cqm: Add hotcpu support Vikas Shivappa
2017-06-26 18:56 ` [PATCH 19/21] x86/intel_rdt/mbm: Basic counting of MBM events (total and local) Vikas Shivappa
2017-07-02 13:46 ` Thomas Gleixner
2017-07-06 23:39 ` Shivappa Vikas
2017-07-07 6:47 ` Thomas Gleixner
2017-06-26 18:56 ` [PATCH 20/21] x86/intel_rdt/mbm: Add mbm counter initialization Vikas Shivappa
2017-06-26 18:56 ` [PATCH 21/21] x86/intel_rdt/mbm: Handle counter overflow Vikas Shivappa
2017-07-02 13:57 ` Thomas Gleixner
2017-07-06 23:53 ` Shivappa Vikas
2017-07-07 6:50 ` Thomas Gleixner
2017-07-10 17:54 ` Luck, Tony
2017-07-11 15:22 ` Thomas Gleixner
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=1498503368-20173-9-git-send-email-vikas.shivappa@linux.intel.com \
--to=vikas.shivappa@linux.intel.com \
--cc=andi.kleen@intel.com \
--cc=fenghua.yu@intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=peterz@infradead.org \
--cc=ravi.v.shankar@intel.com \
--cc=tglx@linutronix.de \
--cc=tony.luck@intel.com \
--cc=vikas.shivappa@intel.com \
--cc=x86@kernel.org \
/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