From 4e2047c6adfb0a8d81fc145536453d77ad37eb20 Mon Sep 17 00:00:00 2001 From: Xie XiuQi Date: Tue, 29 Jan 2019 17:38:23 +0800 Subject: [PATCH 2818/2944] openEuler: arm64/mpam: support pmg alloc/free commit 89691ba7d9a777361165dd9950370572da562709 openEuler-1.0 hulk inclusion category: feature bugzilla: 5510 CVE: NA Signed-off-by: Xie XiuQi Reviewed-by: Hanjun Guo Signed-off-by: Yang Yingliang Signed-off-by: Xin Hao Reviewed-by: Baolin Wang --- arch/arm64/include/asm/mpam.h | 1 + arch/arm64/include/asm/mpam_resource.h | 4 +- arch/arm64/include/asm/resctrl.h | 2 + arch/arm64/kernel/mpam.c | 84 +++++++++++++++++++++++++++++++++- arch/arm64/kernel/mpam_ctrlmon.c | 2 +- arch/arm64/kernel/mpam_mon.c | 36 +++++++++++++-- 6 files changed, 123 insertions(+), 6 deletions(-) diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h index 90d50a4..4f09280 100644 --- a/arch/arm64/include/asm/mpam.h +++ b/arch/arm64/include/asm/mpam.h @@ -321,6 +321,7 @@ struct raw_resctrl_resource { int num_partid; u32 default_ctrl; void (*msr_update) (struct rdt_domain *d, int partid); + u64 (*msr_read) (struct rdt_domain *d, int partid); int data_width; const char *format_str; int (*parse_ctrlval) (char *buf, struct raw_resctrl_resource *r, diff --git a/arch/arm64/include/asm/mpam_resource.h b/arch/arm64/include/asm/mpam_resource.h index 4ec2d860..cd83322 100644 --- a/arch/arm64/include/asm/mpam_resource.h +++ b/arch/arm64/include/asm/mpam_resource.h @@ -57,8 +57,10 @@ #define BWA_WD 6 /* hard code for P680 */ #define MBW_MAX_MASK 0xFC00 #define MBW_MAX_HARDLIM BIT(31) -#define MBW_MAX_SET(v) (MBW_MAX_HARDLIM|((v) << (15 - BWA_WD))) /* [FIXME] hard code for hardlim */ +/* [FIXME] hard code for hardlim */ +#define MBW_MAX_SET(v) (MBW_MAX_HARDLIM|((v) << (15 - BWA_WD))) +#define MBW_MAX_GET(v) (((v) & MBW_MAX_MASK) >> (15 - BWA_WD)) /* * emulate the mpam nodes * These should be reported by ACPI MPAM Table. diff --git a/arch/arm64/include/asm/resctrl.h b/arch/arm64/include/asm/resctrl.h index b8c983f..cb02aae 100644 --- a/arch/arm64/include/asm/resctrl.h +++ b/arch/arm64/include/asm/resctrl.h @@ -19,9 +19,11 @@ static inline void free_mon_id(u32 id) free_rmid(id); } +void pmg_init(void); static inline void resctrl_id_init(void) { closid_init(); + pmg_init(); } static inline int resctrl_id_alloc(void) diff --git a/arch/arm64/kernel/mpam.c b/arch/arm64/kernel/mpam.c index 02aa427..5618895 100644 --- a/arch/arm64/kernel/mpam.c +++ b/arch/arm64/kernel/mpam.c @@ -162,21 +162,27 @@ void mpam_nodes_show(void) static void bw_wrmsr(struct rdt_domain *d, int partid); +u64 cat_rdmsr(struct rdt_domain *d, int partid); +u64 bw_rdmsr(struct rdt_domain *d, int partid); + #define domain_init(id) LIST_HEAD_INIT(resctrl_resources_all[id].domains) struct raw_resctrl_resource raw_resctrl_resources_all[] = { [MPAM_RESOURCE_SMMU] = { .msr_update = cat_wrmsr, + .msr_read = cat_rdmsr, .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", }, [MPAM_RESOURCE_CACHE] = { .msr_update = cat_wrmsr, + .msr_read = cat_rdmsr, .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", }, [MPAM_RESOURCE_MC] = { .msr_update = bw_wrmsr, + .msr_read = bw_rdmsr, .parse_ctrlval = parse_cbm, /* [FIXME] add parse_bw() helper */ .format_str = "%d=%0*x", }, @@ -225,6 +231,22 @@ struct resctrl_resource resctrl_resources_all[] = { mpam_writel(val, d->base + MPAMCFG_MBW_MAX); } +u64 cat_rdmsr(struct rdt_domain *d, int partid) +{ + mpam_writel(partid, d->base + MPAMCFG_PART_SEL); + return mpam_readl(d->base + MPAMCFG_CPBM); +} + +u64 bw_rdmsr(struct rdt_domain *d, int partid) +{ + u64 max; + + mpam_writel(partid, d->base + MPAMCFG_PART_SEL); + max = mpam_readl(d->base + MPAMCFG_MBW_MAX); + + return MBW_MAX_GET(max); +} + /* * Trivial allocator for CLOSIDs. Since h/w only supports a small number, * we can keep a bitmap of free CLOSIDs in a single integer. @@ -271,10 +293,11 @@ void closid_free(int closid) static int mpam_online_cpu(unsigned int cpu) { - pr_info("CPU %2d: online cpu and enable mpam\n", cpu); + cpumask_set_cpu(cpu, &resctrl_group_default.cpu_mask); return 0; } +/* [FIXME] remove related resource when cpu offline */ static int mpam_offline_cpu(unsigned int cpu) { pr_info("offline cpu\n"); @@ -540,9 +563,68 @@ static int resctrl_group_cpus_show(struct kernfs_open_file *of, return ret; } +static void cpumask_rdtgrp_clear(struct rdtgroup *r, struct cpumask *m) +{ + struct rdtgroup *crgrp; + + cpumask_andnot(&r->cpu_mask, &r->cpu_mask, m); + /* update the child mon group masks as well*/ + list_for_each_entry(crgrp, &r->mon.crdtgrp_list, mon.crdtgrp_list) + cpumask_and(&crgrp->cpu_mask, &r->cpu_mask, &crgrp->cpu_mask); +} + int cpus_ctrl_write(struct rdtgroup *rdtgrp, cpumask_var_t newmask, cpumask_var_t tmpmask, cpumask_var_t tmpmask1) { + struct rdtgroup *r, *crgrp; + struct list_head *head; + + /* Check whether cpus are dropped from this group */ + cpumask_andnot(tmpmask, &rdtgrp->cpu_mask, newmask); + if (cpumask_weight(tmpmask)) { + /* Can't drop from default group */ + if (rdtgrp == &resctrl_group_default) { + rdt_last_cmd_puts("Can't drop CPUs from default group\n"); + return -EINVAL; + } + + /* Give any dropped cpus to rdtgroup_default */ + cpumask_or(&resctrl_group_default.cpu_mask, + &resctrl_group_default.cpu_mask, tmpmask); + update_closid_rmid(tmpmask, &resctrl_group_default); + } + + /* + * If we added cpus, remove them from previous group and + * the prev group's child groups that owned them + * and update per-cpu closid/rmid. + */ + cpumask_andnot(tmpmask, newmask, &rdtgrp->cpu_mask); + if (cpumask_weight(tmpmask)) { + list_for_each_entry(r, &resctrl_all_groups, resctrl_group_list) { + if (r == rdtgrp) + continue; + cpumask_and(tmpmask1, &r->cpu_mask, tmpmask); + if (cpumask_weight(tmpmask1)) + cpumask_rdtgrp_clear(r, tmpmask1); + } + update_closid_rmid(tmpmask, rdtgrp); + } + + /* Done pushing/pulling - update this group with new mask */ + cpumask_copy(&rdtgrp->cpu_mask, newmask); + + /* + * Clear child mon group masks since there is a new parent mask + * now and update the rmid for the cpus the child lost. + */ + head = &rdtgrp->mon.crdtgrp_list; + list_for_each_entry(crgrp, head, mon.crdtgrp_list) { + cpumask_and(tmpmask, &rdtgrp->cpu_mask, &crgrp->cpu_mask); + update_closid_rmid(tmpmask, rdtgrp); + cpumask_clear(&crgrp->cpu_mask); + } + return 0; } diff --git a/arch/arm64/kernel/mpam_ctrlmon.c b/arch/arm64/kernel/mpam_ctrlmon.c index c8653ba..b7af781 100644 --- a/arch/arm64/kernel/mpam_ctrlmon.c +++ b/arch/arm64/kernel/mpam_ctrlmon.c @@ -217,7 +217,7 @@ static void show_doms(struct seq_file *s, struct resctrl_resource *r, int partid if (sep) seq_puts(s, ";"); seq_printf(s, rr->format_str, dom->id, max_data_width, - dom->ctrl_val[partid]); + rr->msr_read(dom, partid)); sep = true; } seq_puts(s, "\n"); diff --git a/arch/arm64/kernel/mpam_mon.c b/arch/arm64/kernel/mpam_mon.c index f4eacf1..ebf8980 100644 --- a/arch/arm64/kernel/mpam_mon.c +++ b/arch/arm64/kernel/mpam_mon.c @@ -35,6 +35,36 @@ */ bool rdt_mon_capable; +static int pmg_free_map; + +void pmg_init(void) +{ + int pmg_max = 16; + + pmg_free_map = BIT_MASK(pmg_max) - 1; + + /* pmg 0 is always reserved for the default group */ + pmg_free_map &= ~1; +} + +int alloc_pmg(void) +{ + u32 pmg = ffs(pmg_free_map); + + if (pmg == 0) + return -ENOSPC; + pmg--; + pmg_free_map &= ~(1 << pmg); + + return pmg; +} + +void free_pmg(u32 pmg) +{ + pmg_free_map |= 1 << pmg; +} + + /* * As of now the RMIDs allocation is global. * However we keep track of which packages the RMIDs @@ -42,10 +72,10 @@ */ int alloc_rmid(void) { - return 0; + return alloc_pmg(); } -void free_rmid(u32 rmid) +void free_rmid(u32 pmg) { + free_pmg(pmg); } - -- 1.8.3.1