From: Vikas Shivappa <vikas.shiva...@linux.intel.com>

This patch adds different APIs to manage the L3 cache capacity bitmask.
The capacity bit mask(CBM) needs to have only contiguous bits set. The
current implementation has a global CBM for each class of service id.
There are APIs added to update the CBM via MSR write to IA32_L3_MASK_n
on all packages. Other APIs are to read and write entries to the
clos_cbm_table.

Signed-off-by: Vikas Shivappa <vikas.shiva...@linux.intel.com>
Signed-off-by: Fenghua Yu <fenghua...@intel.com>
Reviewed-by: Tony Luck <tony.l...@intel.com>
---
 arch/x86/include/asm/intel_rdt.h |  4 ++++
 arch/x86/kernel/cpu/intel_rdt.c  | 48 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h
index 68bab26..68c9a79 100644
--- a/arch/x86/include/asm/intel_rdt.h
+++ b/arch/x86/include/asm/intel_rdt.h
@@ -3,6 +3,10 @@
 
 #ifdef CONFIG_INTEL_RDT
 
+#define MAX_CBM_LENGTH                 32
+#define IA32_L3_CBM_BASE               0xc90
+#define CBM_FROM_INDEX(x)              (IA32_L3_CBM_BASE + x)
+
 struct clos_cbm_table {
        unsigned long cbm;
        unsigned int clos_refcnt;
diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c
index b25940a..9cf3a7d 100644
--- a/arch/x86/kernel/cpu/intel_rdt.c
+++ b/arch/x86/kernel/cpu/intel_rdt.c
@@ -31,8 +31,22 @@ static struct clos_cbm_table *cctable;
  * closid availability bit map.
  */
 unsigned long *closmap;
+/*
+ * Mask of CPUs for writing CBM values. We only need one CPU per-socket.
+ */
+static cpumask_t rdt_cpumask;
+/*
+ * Temporary cpumask used during hot cpu notificaiton handling. The usage
+ * is serialized by hot cpu locks.
+ */
+static cpumask_t tmp_cpumask;
 static DEFINE_MUTEX(rdtgroup_mutex);
 
+struct rdt_remote_data {
+       int msr;
+       u64 val;
+};
+
 static inline void closid_get(u32 closid)
 {
        struct clos_cbm_table *cct = &cctable[closid];
@@ -79,11 +93,41 @@ static void closid_put(u32 closid)
                closid_free(closid);
 }
 
+static void msr_cpu_update(void *arg)
+{
+       struct rdt_remote_data *info = arg;
+
+       wrmsrl(info->msr, info->val);
+}
+
+/*
+ * msr_update_all() - Update the msr for all packages.
+ */
+static inline void msr_update_all(int msr, u64 val)
+{
+       struct rdt_remote_data info;
+
+       info.msr = msr;
+       info.val = val;
+       on_each_cpu_mask(&rdt_cpumask, msr_cpu_update, &info, 1);
+}
+
+static inline bool rdt_cpumask_update(int cpu)
+{
+       cpumask_and(&tmp_cpumask, &rdt_cpumask, topology_core_cpumask(cpu));
+       if (cpumask_empty(&tmp_cpumask)) {
+               cpumask_set_cpu(cpu, &rdt_cpumask);
+               return true;
+       }
+
+       return false;
+}
+
 static int __init intel_rdt_late_init(void)
 {
        struct cpuinfo_x86 *c = &boot_cpu_data;
        u32 maxid;
-       int err = 0, size;
+       int err = 0, size, i;
 
        if (!cpu_has(c, X86_FEATURE_CAT_L3))
                return -ENODEV;
@@ -105,6 +149,8 @@ static int __init intel_rdt_late_init(void)
                goto out_err;
        }
 
+       for_each_online_cpu(i)
+               rdt_cpumask_update(i);
        pr_info("Intel cache allocation enabled\n");
 out_err:
 
-- 
2.5.0

Reply via email to