diff options
author | Vikas Shivappa <vikas.shivappa@linux.intel.com> | 2017-07-25 14:14:28 -0700 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-08-01 22:41:21 +0200 |
commit | edf6fa1c4a951b3a03e94b63e6483c5d9da3ab11 (patch) | |
tree | e154789f372b5026d8bf9fec0bf7a2c39ad12082 /arch/x86/kernel/cpu/intel_rdt.c | |
parent | 6a445edce657810992594c7b9e679219aaf78ad9 (diff) | |
download | linux-edf6fa1c4a951b3a03e94b63e6483c5d9da3ab11.tar.gz linux-edf6fa1c4a951b3a03e94b63e6483c5d9da3ab11.tar.bz2 linux-edf6fa1c4a951b3a03e94b63e6483c5d9da3ab11.zip |
x86/intel_rdt/cqm: Add RMID (Resource monitoring ID) management
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.
[Tony: Improved limbo search]
Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: ravi.v.shankar@intel.com
Cc: tony.luck@intel.com
Cc: fenghua.yu@intel.com
Cc: peterz@infradead.org
Cc: eranian@google.com
Cc: vikas.shivappa@intel.com
Cc: ak@linux.intel.com
Cc: davidcc@google.com
Cc: reinette.chatre@intel.com
Link: http://lkml.kernel.org/r/1501017287-28083-10-git-send-email-vikas.shivappa@linux.intel.com
Diffstat (limited to 'arch/x86/kernel/cpu/intel_rdt.c')
-rw-r--r-- | arch/x86/kernel/cpu/intel_rdt.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c index cb520dd73bc8..d30830a8eafd 100644 --- a/arch/x86/kernel/cpu/intel_rdt.c +++ b/arch/x86/kernel/cpu/intel_rdt.c @@ -320,6 +320,19 @@ cat_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r) wrmsrl(r->msr_base + cbm_idx(r, i), d->ctrl_val[i]); } +struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r) +{ + struct rdt_domain *d; + + list_for_each_entry(d, &r->domains, list) { + /* Find the domain that contains this CPU */ + if (cpumask_test_cpu(cpu, &d->cpu_mask)) + return d; + } + + return NULL; +} + void rdt_ctrl_update(void *arg) { struct msr_param *m = arg; @@ -397,6 +410,19 @@ static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d) return 0; } +static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d) +{ + if (is_llc_occupancy_enabled()) { + d->rmid_busy_llc = kcalloc(BITS_TO_LONGS(r->num_rmid), + sizeof(unsigned long), + GFP_KERNEL); + if (!d->rmid_busy_llc) + return -ENOMEM; + } + + return 0; +} + /* * domain_add_cpu - Add a cpu to a resource's domain list. * @@ -438,6 +464,11 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r) return; } + if (r->mon_capable && domain_setup_mon_state(r, d)) { + kfree(d); + return; + } + cpumask_set_cpu(cpu, &d->cpu_mask); list_add_tail(&d->list, add_pos); } @@ -456,6 +487,7 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r) cpumask_clear_cpu(cpu, &d->cpu_mask); if (cpumask_empty(&d->cpu_mask)) { kfree(d->ctrl_val); + kfree(d->rmid_busy_llc); list_del(&d->list); kfree(d); } |