[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1484076788-25385-4-git-send-email-vikas.shivappa@linux.intel.com>
Date: Tue, 10 Jan 2017 11:33:03 -0800
From: Vikas Shivappa <vikas.shivappa@...ux.intel.com>
To: vikas.shivappa@...el.com, linux-kernel@...r.kernel.org
Cc: x86@...nel.org, hpa@...or.com, tglx@...utronix.de,
mingo@...nel.org, peterz@...radead.org, ravi.v.shankar@...el.com,
tony.luck@...el.com, fenghua.yu@...el.com, h.peter.anvin@...el.com,
vikas.shivappa@...ux.intel.com
Subject: [PATCH 3/8] x86/intel_rdt/mba: Improvements to handle more RDT resources like MBA
This patch does some changes to get ready to handle more resources like
Memory b/w allocation(MBA).
-Update the control registers only when user changes the controls(cbm for
Cache resources and Mem b/w for memory). Hence not sending IPIs on all
domains when user updates the control vals.
-Introduce next_enabled_resource rather than looping through all
resources while parsing each schemata line. The order of resources
should be anyways the same as the root schemata.
-Return error as soon as we detect a resource not entering all domain
values in schemata rather than waiting till we parse all resources.
Signed-off-by: Vikas Shivappa <vikas.shivappa@...ux.intel.com>
---
arch/x86/include/asm/intel_rdt.h | 16 +++++++++++++
arch/x86/kernel/cpu/intel_rdt_schemata.c | 40 +++++++++++++++++---------------
2 files changed, 37 insertions(+), 19 deletions(-)
diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h
index 9f66bf5..e1f8acb 100644
--- a/arch/x86/include/asm/intel_rdt.h
+++ b/arch/x86/include/asm/intel_rdt.h
@@ -156,6 +156,22 @@ enum {
r++) \
if (r->enabled)
+/*
+ * Parameter r must be NULL or pointing to
+ * a valid rdt_resource_all entry.
+ * Points r to the next enabled RDT resource at the end.
+ */
+#define next_enabled_rdt_resource(r) \
+do { \
+ if (!r) \
+ r = rdt_resources_all; \
+ else \
+ r++; \
+ for (; r < rdt_resources_all + RDT_NUM_RESOURCES; r++) \
+ if (r->enabled) \
+ break; \
+} while (0)
+
/* CPUID.(EAX=10H, ECX=ResID=1).EAX */
union cpuid_0x10_1_eax {
struct {
diff --git a/arch/x86/kernel/cpu/intel_rdt_schemata.c b/arch/x86/kernel/cpu/intel_rdt_schemata.c
index c50f742..054d771 100644
--- a/arch/x86/kernel/cpu/intel_rdt_schemata.c
+++ b/arch/x86/kernel/cpu/intel_rdt_schemata.c
@@ -94,6 +94,10 @@ static int parse_line(char *line, struct rdt_resource *r)
return -EINVAL;
}
+ /* Incorrect number of domains in the line */
+ if (r->num_tmp_ctrl != r->num_domains)
+ return -EINVAL;
+
/* Any garbage at the end of the line? */
if (line && line[0])
return -EINVAL;
@@ -114,9 +118,16 @@ static int update_domains(struct rdt_resource *r, int closid)
msr_param.high = msr_param.low + 1;
msr_param.res = r;
+ /*
+ * Only update the domains that user has changed.
+ * There by avoiding unnecessary IPIs.
+ */
list_for_each_entry(d, &r->domains, list) {
- cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask);
- d->ctrl_val[msr_param.low] = r->tmp_ctrl[idx++];
+ if (d->ctrl_val[msr_param.low] != r->tmp_ctrl[idx]) {
+ cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask);
+ d->ctrl_val[msr_param.low] = r->tmp_ctrl[idx];
+ }
+ idx++;
}
cpu = get_cpu();
/* Update CBM on this cpu if it's in cpu_mask. */
@@ -164,30 +175,21 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
r->num_tmp_ctrl = 0;
}
+ r = NULL;
while ((tok = strsep(&buf, "\n")) != NULL) {
resname = strsep(&tok, ":");
if (!tok) {
ret = -EINVAL;
goto out;
}
- for_each_enabled_rdt_resource(r) {
- if (!strcmp(resname, r->name) &&
- closid < r->num_closid) {
- ret = parse_line(tok, r);
- if (ret)
- goto out;
- break;
- }
- }
- if (!r->name) {
- ret = -EINVAL;
- goto out;
- }
- }
- /* Did the parser find all the masks we need? */
- for_each_enabled_rdt_resource(r) {
- if (r->num_tmp_ctrl != r->num_domains) {
+ next_enabled_rdt_resource(r);
+
+ if (!strcmp(resname, r->name)) {
+ ret = parse_line(tok, r);
+ if (ret)
+ goto out;
+ } else {
ret = -EINVAL;
goto out;
}
--
1.9.1
Powered by blists - more mailing lists