[PATCH 3/6] x86/intel_rdt/mba_sc: Add initialization support

2018-04-20 Thread Vikas Shivappa
When MBA software controller is enabled, we need a per domain storage
for user specified bandwidth in "MBps" and the "percentage" values which
are programmed into the IA32_MBA_THRTL_MSR. Add support for these data
structures and initialization.

The MBA percentage values have a default max value of 100 but however
the max value in MBps is not available from the hardware and we keep it
just at U32_MAX. This simply says that user can use all bandwidth by
default but does not say what is the actual max bandwidth available. The
actual bandwidth that is available may depend on lot of factors like QPI
link, number of memory channels, memory channel frequency, its width and
memory speed, how many channels are configured and also if memory
interleaving is enabled.

Signed-off-by: Vikas Shivappa 
---
 arch/x86/kernel/cpu/intel_rdt.c  | 37 +++-
 arch/x86/kernel/cpu/intel_rdt.h  |  3 +++
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c |  3 +++
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c
index 2a0931f..07f6b3b 100644
--- a/arch/x86/kernel/cpu/intel_rdt.c
+++ b/arch/x86/kernel/cpu/intel_rdt.c
@@ -35,6 +35,7 @@
 
 #define MAX_MBA_BW 100u
 #define MBA_IS_LINEAR  0x4
+#define MBA_MAX_MBPS   U32_MAX
 
 /* Mutex to protect rdtgroup access. */
 DEFINE_MUTEX(rdtgroup_mutex);
@@ -439,25 +440,40 @@ struct rdt_domain *rdt_find_domain(struct rdt_resource 
*r, int id,
return NULL;
 }
 
+void setup_default_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm)
+{
+   int i;
+
+   /*
+* Initialize the Control MSRs to having no control.
+* For Cache Allocation: Set all bits in cbm
+* For Memory Allocation: Set b/w requested to 100%
+* and the bandwidth in MBps to U32_MAX
+*/
+   for (i = 0; i < r->num_closid; i++, dc++, dm++) {
+   *dc = r->default_ctrl;
+   *dm = MBA_MAX_MBPS;
+   }
+}
+
 static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d)
 {
struct msr_param m;
-   u32 *dc;
-   int i;
+   u32 *dc, *dm;
 
dc = kmalloc_array(r->num_closid, sizeof(*d->ctrl_val), GFP_KERNEL);
if (!dc)
return -ENOMEM;
 
-   d->ctrl_val = dc;
+   dm = kmalloc_array(r->num_closid, sizeof(*d->mbps_val), GFP_KERNEL);
+   if (!dm) {
+   kfree(dc);
+   return -ENOMEM;
+   }
 
-   /*
-* Initialize the Control MSRs to having no control.
-* For Cache Allocation: Set all bits in cbm
-* For Memory Allocation: Set b/w requested to 100
-*/
-   for (i = 0; i < r->num_closid; i++, dc++)
-   *dc = r->default_ctrl;
+   d->ctrl_val = dc;
+   d->mbps_val = dm;
+   setup_default_ctrlval(r, dc, dm);
 
m.low = 0;
m.high = r->num_closid;
@@ -596,6 +612,7 @@ static void domain_remove_cpu(int cpu, struct rdt_resource 
*r)
}
 
kfree(d->ctrl_val);
+   kfree(d->mbps_val);
kfree(d->rmid_busy_llc);
kfree(d->mbm_total);
kfree(d->mbm_local);
diff --git a/arch/x86/kernel/cpu/intel_rdt.h b/arch/x86/kernel/cpu/intel_rdt.h
index 74aee0f..91cc310 100644
--- a/arch/x86/kernel/cpu/intel_rdt.h
+++ b/arch/x86/kernel/cpu/intel_rdt.h
@@ -202,6 +202,7 @@ struct mbm_state {
  * @cqm_work_cpu:
  * worker cpu for CQM h/w counters
  * @ctrl_val:  array of cache or mem ctrl values (indexed by CLOSID)
+ * @mbps_val:  When mba_sc is enabled, this holds the bandwidth in MBps
  * @new_ctrl:  new ctrl value to be loaded
  * @have_new_ctrl: did user provide new_ctrl for this domain
  */
@@ -217,6 +218,7 @@ struct rdt_domain {
int mbm_work_cpu;
int cqm_work_cpu;
u32 *ctrl_val;
+   u32 *mbps_val;
u32 new_ctrl;
boolhave_new_ctrl;
 };
@@ -448,6 +450,7 @@ void mbm_setup_overflow_handler(struct rdt_domain *dom,
unsigned long delay_ms);
 void mbm_handle_overflow(struct work_struct *work);
 bool is_mba_sc(struct rdt_resource *r);
+void setup_default_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm);
 void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms);
 void cqm_handle_limbo(struct work_struct *work);
 bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c 
b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
index b9ceb13..bfd707d 100644
--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
+++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
@@ -1055,12 +1055,15 @@ static int set_cache_qos_cfg(int level, bool enable)
 static int set_mba_sc(bool mba_sc)
 {
struct rdt_resource *r = 

[PATCH 3/6] x86/intel_rdt/mba_sc: Add initialization support

2018-04-20 Thread Vikas Shivappa
When MBA software controller is enabled, we need a per domain storage
for user specified bandwidth in "MBps" and the "percentage" values which
are programmed into the IA32_MBA_THRTL_MSR. Add support for these data
structures and initialization.

The MBA percentage values have a default max value of 100 but however
the max value in MBps is not available from the hardware and we keep it
just at U32_MAX. This simply says that user can use all bandwidth by
default but does not say what is the actual max bandwidth available. The
actual bandwidth that is available may depend on lot of factors like QPI
link, number of memory channels, memory channel frequency, its width and
memory speed, how many channels are configured and also if memory
interleaving is enabled.

Signed-off-by: Vikas Shivappa 
---
 arch/x86/kernel/cpu/intel_rdt.c  | 37 +++-
 arch/x86/kernel/cpu/intel_rdt.h  |  3 +++
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c |  3 +++
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c
index 2a0931f..07f6b3b 100644
--- a/arch/x86/kernel/cpu/intel_rdt.c
+++ b/arch/x86/kernel/cpu/intel_rdt.c
@@ -35,6 +35,7 @@
 
 #define MAX_MBA_BW 100u
 #define MBA_IS_LINEAR  0x4
+#define MBA_MAX_MBPS   U32_MAX
 
 /* Mutex to protect rdtgroup access. */
 DEFINE_MUTEX(rdtgroup_mutex);
@@ -439,25 +440,40 @@ struct rdt_domain *rdt_find_domain(struct rdt_resource 
*r, int id,
return NULL;
 }
 
+void setup_default_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm)
+{
+   int i;
+
+   /*
+* Initialize the Control MSRs to having no control.
+* For Cache Allocation: Set all bits in cbm
+* For Memory Allocation: Set b/w requested to 100%
+* and the bandwidth in MBps to U32_MAX
+*/
+   for (i = 0; i < r->num_closid; i++, dc++, dm++) {
+   *dc = r->default_ctrl;
+   *dm = MBA_MAX_MBPS;
+   }
+}
+
 static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d)
 {
struct msr_param m;
-   u32 *dc;
-   int i;
+   u32 *dc, *dm;
 
dc = kmalloc_array(r->num_closid, sizeof(*d->ctrl_val), GFP_KERNEL);
if (!dc)
return -ENOMEM;
 
-   d->ctrl_val = dc;
+   dm = kmalloc_array(r->num_closid, sizeof(*d->mbps_val), GFP_KERNEL);
+   if (!dm) {
+   kfree(dc);
+   return -ENOMEM;
+   }
 
-   /*
-* Initialize the Control MSRs to having no control.
-* For Cache Allocation: Set all bits in cbm
-* For Memory Allocation: Set b/w requested to 100
-*/
-   for (i = 0; i < r->num_closid; i++, dc++)
-   *dc = r->default_ctrl;
+   d->ctrl_val = dc;
+   d->mbps_val = dm;
+   setup_default_ctrlval(r, dc, dm);
 
m.low = 0;
m.high = r->num_closid;
@@ -596,6 +612,7 @@ static void domain_remove_cpu(int cpu, struct rdt_resource 
*r)
}
 
kfree(d->ctrl_val);
+   kfree(d->mbps_val);
kfree(d->rmid_busy_llc);
kfree(d->mbm_total);
kfree(d->mbm_local);
diff --git a/arch/x86/kernel/cpu/intel_rdt.h b/arch/x86/kernel/cpu/intel_rdt.h
index 74aee0f..91cc310 100644
--- a/arch/x86/kernel/cpu/intel_rdt.h
+++ b/arch/x86/kernel/cpu/intel_rdt.h
@@ -202,6 +202,7 @@ struct mbm_state {
  * @cqm_work_cpu:
  * worker cpu for CQM h/w counters
  * @ctrl_val:  array of cache or mem ctrl values (indexed by CLOSID)
+ * @mbps_val:  When mba_sc is enabled, this holds the bandwidth in MBps
  * @new_ctrl:  new ctrl value to be loaded
  * @have_new_ctrl: did user provide new_ctrl for this domain
  */
@@ -217,6 +218,7 @@ struct rdt_domain {
int mbm_work_cpu;
int cqm_work_cpu;
u32 *ctrl_val;
+   u32 *mbps_val;
u32 new_ctrl;
boolhave_new_ctrl;
 };
@@ -448,6 +450,7 @@ void mbm_setup_overflow_handler(struct rdt_domain *dom,
unsigned long delay_ms);
 void mbm_handle_overflow(struct work_struct *work);
 bool is_mba_sc(struct rdt_resource *r);
+void setup_default_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm);
 void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms);
 void cqm_handle_limbo(struct work_struct *work);
 bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c 
b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
index b9ceb13..bfd707d 100644
--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
+++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
@@ -1055,12 +1055,15 @@ static int set_cache_qos_cfg(int level, bool enable)
 static int set_mba_sc(bool mba_sc)
 {
struct rdt_resource *r = _resources_all[RDT_RESOURCE_MBA];
+   struct rdt_domain 

Re: [PATCH 3/6] x86/intel_rdt/mba_sc: Add initialization support

2018-04-03 Thread Shivappa Vikas



On Tue, 3 Apr 2018, Thomas Gleixner wrote:


On Thu, 29 Mar 2018, Vikas Shivappa wrote:

+void setup_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm)
+{
+   int i;
+
+   /*
+* Initialize the Control MSRs to having no control.
+* For Cache Allocation: Set all bits in cbm
+* For Memory Allocation: Set b/w requested to 100%
+* and the b/w in MB to U32_MAX
+*/
+   for (i = 0; i < r->num_closid; i++, dc++, dm++) {
+   *dc = r->membw.bw_byte ? MBA_BW_MAX_MB : r->default_ctrl;
+   *dm = r->default_ctrl;


No! Please stop duct taping your stuff into the existing code. So far the
ctrl value was the same as the value which was actually written into the
MSR. With your new mode you have to split that up into the user supplied
value and the value which gets written into the MSR.

So the right thing to do is to separate the user value and the MSR value
first and independent of the mode. Then the new mode falls into place
naturally because r->default_ctrl and r->default_msrval are set up at mount
time with the values which correspond to the mount mode.


will fix. I tried both and this implementation assumes what user modifies is 
the control values (because then schemata read and write is easy as user does it 
directly) but agree we can change that.


Thanks,
Vikas



Thanks,

tglx



Re: [PATCH 3/6] x86/intel_rdt/mba_sc: Add initialization support

2018-04-03 Thread Shivappa Vikas



On Tue, 3 Apr 2018, Thomas Gleixner wrote:


On Thu, 29 Mar 2018, Vikas Shivappa wrote:

+void setup_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm)
+{
+   int i;
+
+   /*
+* Initialize the Control MSRs to having no control.
+* For Cache Allocation: Set all bits in cbm
+* For Memory Allocation: Set b/w requested to 100%
+* and the b/w in MB to U32_MAX
+*/
+   for (i = 0; i < r->num_closid; i++, dc++, dm++) {
+   *dc = r->membw.bw_byte ? MBA_BW_MAX_MB : r->default_ctrl;
+   *dm = r->default_ctrl;


No! Please stop duct taping your stuff into the existing code. So far the
ctrl value was the same as the value which was actually written into the
MSR. With your new mode you have to split that up into the user supplied
value and the value which gets written into the MSR.

So the right thing to do is to separate the user value and the MSR value
first and independent of the mode. Then the new mode falls into place
naturally because r->default_ctrl and r->default_msrval are set up at mount
time with the values which correspond to the mount mode.


will fix. I tried both and this implementation assumes what user modifies is 
the control values (because then schemata read and write is easy as user does it 
directly) but agree we can change that.


Thanks,
Vikas



Thanks,

tglx



Re: [PATCH 3/6] x86/intel_rdt/mba_sc: Add initialization support

2018-04-03 Thread Thomas Gleixner
On Thu, 29 Mar 2018, Vikas Shivappa wrote:
> +void setup_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm)
> +{
> + int i;
> +
> + /*
> +  * Initialize the Control MSRs to having no control.
> +  * For Cache Allocation: Set all bits in cbm
> +  * For Memory Allocation: Set b/w requested to 100%
> +  * and the b/w in MB to U32_MAX
> +  */
> + for (i = 0; i < r->num_closid; i++, dc++, dm++) {
> + *dc = r->membw.bw_byte ? MBA_BW_MAX_MB : r->default_ctrl;
> + *dm = r->default_ctrl;

No! Please stop duct taping your stuff into the existing code. So far the
ctrl value was the same as the value which was actually written into the
MSR. With your new mode you have to split that up into the user supplied
value and the value which gets written into the MSR.

So the right thing to do is to separate the user value and the MSR value
first and independent of the mode. Then the new mode falls into place
naturally because r->default_ctrl and r->default_msrval are set up at mount
time with the values which correspond to the mount mode. 

Thanks,

tglx


Re: [PATCH 3/6] x86/intel_rdt/mba_sc: Add initialization support

2018-04-03 Thread Thomas Gleixner
On Thu, 29 Mar 2018, Vikas Shivappa wrote:
> +void setup_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm)
> +{
> + int i;
> +
> + /*
> +  * Initialize the Control MSRs to having no control.
> +  * For Cache Allocation: Set all bits in cbm
> +  * For Memory Allocation: Set b/w requested to 100%
> +  * and the b/w in MB to U32_MAX
> +  */
> + for (i = 0; i < r->num_closid; i++, dc++, dm++) {
> + *dc = r->membw.bw_byte ? MBA_BW_MAX_MB : r->default_ctrl;
> + *dm = r->default_ctrl;

No! Please stop duct taping your stuff into the existing code. So far the
ctrl value was the same as the value which was actually written into the
MSR. With your new mode you have to split that up into the user supplied
value and the value which gets written into the MSR.

So the right thing to do is to separate the user value and the MSR value
first and independent of the mode. Then the new mode falls into place
naturally because r->default_ctrl and r->default_msrval are set up at mount
time with the values which correspond to the mount mode. 

Thanks,

tglx


[PATCH 3/6] x86/intel_rdt/mba_sc: Add initialization support

2018-03-29 Thread Vikas Shivappa
When MBA software controller is enabled, we need a per domain storage
for user specified bandwidth in MB and the raw b/w percentage values
which are programmed into the MSR. Add support for these data structures
and initialization.

Signed-off-by: Vikas Shivappa 
---
 arch/x86/kernel/cpu/intel_rdt.c  | 37 +++-
 arch/x86/kernel/cpu/intel_rdt.h  |  4 
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c |  3 +++
 3 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c
index 2b65601..8a32561 100644
--- a/arch/x86/kernel/cpu/intel_rdt.c
+++ b/arch/x86/kernel/cpu/intel_rdt.c
@@ -35,6 +35,7 @@
 
 #define MAX_MBA_BW 100u
 #define MBA_IS_LINEAR  0x4
+#define MBA_BW_MAX_MB  U32_MAX
 
 /* Mutex to protect rdtgroup access. */
 DEFINE_MUTEX(rdtgroup_mutex);
@@ -431,25 +432,40 @@ struct rdt_domain *rdt_find_domain(struct rdt_resource 
*r, int id,
return NULL;
 }
 
+void setup_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm)
+{
+   int i;
+
+   /*
+* Initialize the Control MSRs to having no control.
+* For Cache Allocation: Set all bits in cbm
+* For Memory Allocation: Set b/w requested to 100%
+* and the b/w in MB to U32_MAX
+*/
+   for (i = 0; i < r->num_closid; i++, dc++, dm++) {
+   *dc = r->membw.bw_byte ? MBA_BW_MAX_MB : r->default_ctrl;
+   *dm = r->default_ctrl;
+   }
+}
+
 static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d)
 {
struct msr_param m;
-   u32 *dc;
-   int i;
+   u32 *dc, *dm;
 
dc = kmalloc_array(r->num_closid, sizeof(*d->ctrl_val), GFP_KERNEL);
if (!dc)
return -ENOMEM;
 
-   d->ctrl_val = dc;
+   dm = kmalloc_array(r->num_closid, sizeof(*d->msr_val), GFP_KERNEL);
+   if (!dm) {
+   kfree (dc);
+   return -ENOMEM;
+   }
 
-   /*
-* Initialize the Control MSRs to having no control.
-* For Cache Allocation: Set all bits in cbm
-* For Memory Allocation: Set b/w requested to 100
-*/
-   for (i = 0; i < r->num_closid; i++, dc++)
-   *dc = r->default_ctrl;
+   d->ctrl_val = dc;
+   d->msr_val = dm;
+   setup_ctrlval(r, dc, dm);
 
m.low = 0;
m.high = r->num_closid;
@@ -588,6 +604,7 @@ static void domain_remove_cpu(int cpu, struct rdt_resource 
*r)
}
 
kfree(d->ctrl_val);
+   kfree(d->msr_val);
kfree(d->rmid_busy_llc);
kfree(d->mbm_total);
kfree(d->mbm_local);
diff --git a/arch/x86/kernel/cpu/intel_rdt.h b/arch/x86/kernel/cpu/intel_rdt.h
index 3e9bc3f..68c7da0 100644
--- a/arch/x86/kernel/cpu/intel_rdt.h
+++ b/arch/x86/kernel/cpu/intel_rdt.h
@@ -202,6 +202,8 @@ struct mbm_state {
  * @cqm_work_cpu:
  * worker cpu for CQM h/w counters
  * @ctrl_val:  array of cache or mem ctrl values (indexed by CLOSID)
+ * When MBA is expressed in MB, this holds number of MegaBytes
+ * @msr_val:   When MBA is expressed in MB, this holds the control MSR value
  * @new_ctrl:  new ctrl value to be loaded
  * @have_new_ctrl: did user provide new_ctrl for this domain
  */
@@ -217,6 +219,7 @@ struct rdt_domain {
int mbm_work_cpu;
int cqm_work_cpu;
u32 *ctrl_val;
+   u32 *msr_val;
u32 new_ctrl;
boolhave_new_ctrl;
 };
@@ -450,6 +453,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_domain 
*d,
 void mbm_setup_overflow_handler(struct rdt_domain *dom,
unsigned long delay_ms);
 void mbm_handle_overflow(struct work_struct *work);
+void setup_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm);
 void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms);
 void cqm_handle_limbo(struct work_struct *work);
 bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c 
b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
index 0707191..d4e8412 100644
--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
+++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
@@ -1044,8 +1044,11 @@ static int set_cache_qos_cfg(int level, bool enable)
 static void __set_mba_byte_ctrl(bool byte_ctrl)
 {
struct rdt_resource *r = _resources_all[RDT_RESOURCE_MBA];
+   struct rdt_domain *d;
 
r->membw.bw_byte = byte_ctrl;
+   list_for_each_entry(d, >domains, list)
+   setup_ctrlval(r, d->ctrl_val, d->msr_val);
 }
 
 /*
-- 
1.9.1



[PATCH 3/6] x86/intel_rdt/mba_sc: Add initialization support

2018-03-29 Thread Vikas Shivappa
When MBA software controller is enabled, we need a per domain storage
for user specified bandwidth in MB and the raw b/w percentage values
which are programmed into the MSR. Add support for these data structures
and initialization.

Signed-off-by: Vikas Shivappa 
---
 arch/x86/kernel/cpu/intel_rdt.c  | 37 +++-
 arch/x86/kernel/cpu/intel_rdt.h  |  4 
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c |  3 +++
 3 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c
index 2b65601..8a32561 100644
--- a/arch/x86/kernel/cpu/intel_rdt.c
+++ b/arch/x86/kernel/cpu/intel_rdt.c
@@ -35,6 +35,7 @@
 
 #define MAX_MBA_BW 100u
 #define MBA_IS_LINEAR  0x4
+#define MBA_BW_MAX_MB  U32_MAX
 
 /* Mutex to protect rdtgroup access. */
 DEFINE_MUTEX(rdtgroup_mutex);
@@ -431,25 +432,40 @@ struct rdt_domain *rdt_find_domain(struct rdt_resource 
*r, int id,
return NULL;
 }
 
+void setup_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm)
+{
+   int i;
+
+   /*
+* Initialize the Control MSRs to having no control.
+* For Cache Allocation: Set all bits in cbm
+* For Memory Allocation: Set b/w requested to 100%
+* and the b/w in MB to U32_MAX
+*/
+   for (i = 0; i < r->num_closid; i++, dc++, dm++) {
+   *dc = r->membw.bw_byte ? MBA_BW_MAX_MB : r->default_ctrl;
+   *dm = r->default_ctrl;
+   }
+}
+
 static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d)
 {
struct msr_param m;
-   u32 *dc;
-   int i;
+   u32 *dc, *dm;
 
dc = kmalloc_array(r->num_closid, sizeof(*d->ctrl_val), GFP_KERNEL);
if (!dc)
return -ENOMEM;
 
-   d->ctrl_val = dc;
+   dm = kmalloc_array(r->num_closid, sizeof(*d->msr_val), GFP_KERNEL);
+   if (!dm) {
+   kfree (dc);
+   return -ENOMEM;
+   }
 
-   /*
-* Initialize the Control MSRs to having no control.
-* For Cache Allocation: Set all bits in cbm
-* For Memory Allocation: Set b/w requested to 100
-*/
-   for (i = 0; i < r->num_closid; i++, dc++)
-   *dc = r->default_ctrl;
+   d->ctrl_val = dc;
+   d->msr_val = dm;
+   setup_ctrlval(r, dc, dm);
 
m.low = 0;
m.high = r->num_closid;
@@ -588,6 +604,7 @@ static void domain_remove_cpu(int cpu, struct rdt_resource 
*r)
}
 
kfree(d->ctrl_val);
+   kfree(d->msr_val);
kfree(d->rmid_busy_llc);
kfree(d->mbm_total);
kfree(d->mbm_local);
diff --git a/arch/x86/kernel/cpu/intel_rdt.h b/arch/x86/kernel/cpu/intel_rdt.h
index 3e9bc3f..68c7da0 100644
--- a/arch/x86/kernel/cpu/intel_rdt.h
+++ b/arch/x86/kernel/cpu/intel_rdt.h
@@ -202,6 +202,8 @@ struct mbm_state {
  * @cqm_work_cpu:
  * worker cpu for CQM h/w counters
  * @ctrl_val:  array of cache or mem ctrl values (indexed by CLOSID)
+ * When MBA is expressed in MB, this holds number of MegaBytes
+ * @msr_val:   When MBA is expressed in MB, this holds the control MSR value
  * @new_ctrl:  new ctrl value to be loaded
  * @have_new_ctrl: did user provide new_ctrl for this domain
  */
@@ -217,6 +219,7 @@ struct rdt_domain {
int mbm_work_cpu;
int cqm_work_cpu;
u32 *ctrl_val;
+   u32 *msr_val;
u32 new_ctrl;
boolhave_new_ctrl;
 };
@@ -450,6 +453,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_domain 
*d,
 void mbm_setup_overflow_handler(struct rdt_domain *dom,
unsigned long delay_ms);
 void mbm_handle_overflow(struct work_struct *work);
+void setup_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm);
 void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms);
 void cqm_handle_limbo(struct work_struct *work);
 bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c 
b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
index 0707191..d4e8412 100644
--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
+++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
@@ -1044,8 +1044,11 @@ static int set_cache_qos_cfg(int level, bool enable)
 static void __set_mba_byte_ctrl(bool byte_ctrl)
 {
struct rdt_resource *r = _resources_all[RDT_RESOURCE_MBA];
+   struct rdt_domain *d;
 
r->membw.bw_byte = byte_ctrl;
+   list_for_each_entry(d, >domains, list)
+   setup_ctrlval(r, d->ctrl_val, d->msr_val);
 }
 
 /*
-- 
1.9.1