提交 88371f8b 编写于 作者: W Wang ShaoBo 提交者: Yang Yingliang

arm64/mpam: resctrl: Handle cpuhp and resctrl_dom allocation

hulk inclusion
category: feature
bugzilla: 34278
CVE: NA

-------------------------------------------------

We implement the cpuhp hooks that allocated and free the resctrl
domain structures, meanwhile, ctrl_val array in resctrl_resource
structure are created and destroyed synchronously, so it continuously
maintains the operations below when cpu online or offline, for
mpam resctrl, only the cpu mask is needed to know.

Most of this code are borrowed from James's(76814660 "arm_mpam: resctrl:
Add boilerplate cpuhp and domain allocation").

Link: http://www.linux-arm.org/git?p=linux-jm.git;a=patch;h=768146605a808b379ae3861103f30a792af33ea2Signed-off-by: NWang ShaoBo <bobo.shaobowang@huawei.com>
Reviewed-by: NXiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: NCheng Jian <cj.chengjian@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NCheng Jian <cj.chengjian@huawei.com>
上级 2ab89c89
......@@ -132,4 +132,7 @@ mpam_get_raw_resctrl_resource(u32 level);
int __init mpam_resctrl_init(void);
int mpam_resctrl_set_default_cpu(unsigned int cpu);
void mpam_resctrl_clear_default_cpu(unsigned int cpu);
#endif
......@@ -82,6 +82,19 @@ bool rdt_alloc_capable;
* AFF2: MPIDR.AFF2
*/
int mpam_resctrl_set_default_cpu(unsigned int cpu)
{
/* The cpu is set in default rdtgroup after online. */
cpumask_set_cpu(cpu, &resctrl_group_default.cpu_mask);
return 0;
}
void mpam_resctrl_clear_default_cpu(unsigned int cpu)
{
/* The cpu is set in default rdtgroup after online. */
cpumask_clear_cpu(cpu, &resctrl_group_default.cpu_mask);
}
static inline void mpam_node_assign_val(struct mpam_node *n,
char *name,
u8 type,
......@@ -529,13 +542,14 @@ void closid_free(int closid)
static int mpam_online_cpu(unsigned int cpu)
{
cpumask_set_cpu(cpu, &resctrl_group_default.cpu_mask);
return 0;
return mpam_resctrl_set_default_cpu(cpu);
}
/* remove related resource when cpu offline */
static int mpam_offline_cpu(unsigned int cpu)
{
mpam_resctrl_clear_default_cpu(cpu);
return 0;
}
......
......@@ -41,16 +41,133 @@
struct mpam_resctrl_res mpam_resctrl_exports[RDT_NUM_RESOURCES];
struct mpam_resctrl_res mpam_resctrl_events[RESCTRL_NUM_EVENT_IDS];
int mpam_resctrl_cpu_online(unsigned int cpu)
/* Like resctrl_get_domain_from_cpu(), but for offline CPUs */
static struct mpam_resctrl_dom *
mpam_get_domain_from_cpu(int cpu, struct mpam_resctrl_res *res)
{
struct rdt_domain *d;
struct mpam_resctrl_dom *dom;
list_for_each_entry(d, &res->resctrl_res.domains, list) {
dom = container_of(d, struct mpam_resctrl_dom, resctrl_dom);
if (cpumask_test_cpu(cpu, &dom->comp->fw_affinity))
return dom;
}
return NULL;
}
static int mpam_resctrl_setup_domain(unsigned int cpu,
struct mpam_resctrl_res *res)
{
struct mpam_resctrl_dom *dom;
struct mpam_class *class = res->class;
struct mpam_component *comp_iter, *comp;
u32 num_partid;
u32 **ctrlval_ptr;
num_partid = mpam_sysprops_num_partid();
comp = NULL;
list_for_each_entry(comp_iter, &class->components, class_list) {
if (cpumask_test_cpu(cpu, &comp_iter->fw_affinity)) {
comp = comp_iter;
break;
}
}
/* cpu with unknown exported component? */
if (WARN_ON_ONCE(!comp))
return 0;
dom = kzalloc_node(sizeof(*dom), GFP_KERNEL, cpu_to_node(cpu));
if (!dom)
return -ENOMEM;
dom->comp = comp;
INIT_LIST_HEAD(&dom->resctrl_dom.list);
dom->resctrl_dom.id = comp->comp_id;
cpumask_set_cpu(cpu, &dom->resctrl_dom.cpu_mask);
ctrlval_ptr = &dom->resctrl_dom.ctrl_val;
*ctrlval_ptr = kmalloc_array(num_partid,
sizeof(**ctrlval_ptr), GFP_KERNEL);
if (!*ctrlval_ptr) {
kfree(dom);
return -ENOMEM;
}
/* TODO: this list should be sorted */
list_add_tail(&dom->resctrl_dom.list, &res->resctrl_res.domains);
res->resctrl_res.dom_num++;
return 0;
}
int mpam_resctrl_cpu_online(unsigned int cpu)
{
int ret;
struct mpam_resctrl_dom *dom;
struct mpam_resctrl_res *res;
for_each_supported_resctrl_exports(res) {
dom = mpam_get_domain_from_cpu(cpu, res);
if (dom) {
cpumask_set_cpu(cpu, &dom->resctrl_dom.cpu_mask);
} else {
ret = mpam_resctrl_setup_domain(cpu, res);
if (ret)
return ret;
}
}
return mpam_resctrl_set_default_cpu(cpu);
}
static inline struct rdt_domain *
resctrl_get_domain_from_cpu(int cpu, struct resctrl_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;
}
int mpam_resctrl_cpu_offline(unsigned int cpu)
{
struct rdt_domain *d;
struct mpam_resctrl_res *res;
struct mpam_resctrl_dom *dom;
for_each_supported_resctrl_exports(res) {
d = resctrl_get_domain_from_cpu(cpu, &res->resctrl_res);
/* cpu with unknown exported component? */
if (WARN_ON_ONCE(!d))
continue;
cpumask_clear_cpu(cpu, &d->cpu_mask);
if (!cpumask_empty(&d->cpu_mask))
continue;
list_del(&d->list);
dom = container_of(d, struct mpam_resctrl_dom, resctrl_dom);
kfree(dom);
}
mpam_resctrl_clear_default_cpu(cpu);
return 0;
}
/* Test whether we can export MPAM_CLASS_CACHE:{2,3}? */
static void mpam_resctrl_pick_caches(void)
{
......
......@@ -47,6 +47,7 @@ struct resctrl_resource {
bool mon_capable;
char *name;
struct list_head domains;
u32 dom_num;
struct list_head evt_list;
unsigned long fflags;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册