diff options
Diffstat (limited to 'arch/x86/kernel/cpu/resctrl/ctrlmondata.c')
| -rw-r--r-- | arch/x86/kernel/cpu/resctrl/ctrlmondata.c | 89 | 
1 files changed, 57 insertions, 32 deletions
diff --git a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c index b7291f60399c..50fa1fe9a073 100644 --- a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c +++ b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c @@ -60,7 +60,7 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r)  }  int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s, -	     struct rdt_domain *d) +	     struct rdt_ctrl_domain *d)  {  	struct resctrl_staged_config *cfg;  	u32 closid = data->rdtgrp->closid; @@ -69,7 +69,7 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,  	cfg = &d->staged_config[s->conf_type];  	if (cfg->have_new_ctrl) { -		rdt_last_cmd_printf("Duplicate domain %d\n", d->id); +		rdt_last_cmd_printf("Duplicate domain %d\n", d->hdr.id);  		return -EINVAL;  	} @@ -139,7 +139,7 @@ static bool cbm_validate(char *buf, u32 *data, struct rdt_resource *r)   * resource type.   */  int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s, -	      struct rdt_domain *d) +	      struct rdt_ctrl_domain *d)  {  	struct rdtgroup *rdtgrp = data->rdtgrp;  	struct resctrl_staged_config *cfg; @@ -148,7 +148,7 @@ int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s,  	cfg = &d->staged_config[s->conf_type];  	if (cfg->have_new_ctrl) { -		rdt_last_cmd_printf("Duplicate domain %d\n", d->id); +		rdt_last_cmd_printf("Duplicate domain %d\n", d->hdr.id);  		return -EINVAL;  	} @@ -208,8 +208,8 @@ static int parse_line(char *line, struct resctrl_schema *s,  	struct resctrl_staged_config *cfg;  	struct rdt_resource *r = s->res;  	struct rdt_parse_data data; +	struct rdt_ctrl_domain *d;  	char *dom = NULL, *id; -	struct rdt_domain *d;  	unsigned long dom_id;  	/* Walking r->domains, ensure it can't race with cpuhp */ @@ -231,8 +231,8 @@ next:  		return -EINVAL;  	}  	dom = strim(dom); -	list_for_each_entry(d, &r->domains, list) { -		if (d->id == dom_id) { +	list_for_each_entry(d, &r->ctrl_domains, hdr.list) { +		if (d->hdr.id == dom_id) {  			data.buf = dom;  			data.rdtgrp = rdtgrp;  			if (r->parse_ctrlval(&data, s, d)) @@ -272,15 +272,15 @@ static u32 get_config_index(u32 closid, enum resctrl_conf_type type)  	}  } -int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, +int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_ctrl_domain *d,  			    u32 closid, enum resctrl_conf_type t, u32 cfg_val)  { +	struct rdt_hw_ctrl_domain *hw_dom = resctrl_to_arch_ctrl_dom(d);  	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); -	struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);  	u32 idx = get_config_index(closid, t);  	struct msr_param msr_param; -	if (!cpumask_test_cpu(smp_processor_id(), &d->cpu_mask)) +	if (!cpumask_test_cpu(smp_processor_id(), &d->hdr.cpu_mask))  		return -EINVAL;  	hw_dom->ctrl_val[idx] = cfg_val; @@ -297,17 +297,17 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d,  int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)  {  	struct resctrl_staged_config *cfg; -	struct rdt_hw_domain *hw_dom; +	struct rdt_hw_ctrl_domain *hw_dom;  	struct msr_param msr_param; +	struct rdt_ctrl_domain *d;  	enum resctrl_conf_type t; -	struct rdt_domain *d;  	u32 idx;  	/* Walking r->domains, ensure it can't race with cpuhp */  	lockdep_assert_cpus_held(); -	list_for_each_entry(d, &r->domains, list) { -		hw_dom = resctrl_to_arch_dom(d); +	list_for_each_entry(d, &r->ctrl_domains, hdr.list) { +		hw_dom = resctrl_to_arch_ctrl_dom(d);  		msr_param.res = NULL;  		for (t = 0; t < CDP_NUM_TYPES; t++) {  			cfg = &hw_dom->d_resctrl.staged_config[t]; @@ -330,7 +330,7 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)  			}  		}  		if (msr_param.res) -			smp_call_function_any(&d->cpu_mask, rdt_ctrl_update, &msr_param, 1); +			smp_call_function_any(&d->hdr.cpu_mask, rdt_ctrl_update, &msr_param, 1);  	}  	return 0; @@ -430,10 +430,10 @@ out:  	return ret ?: nbytes;  } -u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d, +u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_ctrl_domain *d,  			    u32 closid, enum resctrl_conf_type type)  { -	struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d); +	struct rdt_hw_ctrl_domain *hw_dom = resctrl_to_arch_ctrl_dom(d);  	u32 idx = get_config_index(closid, type);  	return hw_dom->ctrl_val[idx]; @@ -442,7 +442,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d,  static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int closid)  {  	struct rdt_resource *r = schema->res; -	struct rdt_domain *dom; +	struct rdt_ctrl_domain *dom;  	bool sep = false;  	u32 ctrl_val; @@ -450,7 +450,7 @@ static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int clo  	lockdep_assert_cpus_held();  	seq_printf(s, "%*s:", max_name_width, schema->name); -	list_for_each_entry(dom, &r->domains, list) { +	list_for_each_entry(dom, &r->ctrl_domains, hdr.list) {  		if (sep)  			seq_puts(s, ";"); @@ -460,7 +460,7 @@ static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int clo  			ctrl_val = resctrl_arch_get_config(r, dom, closid,  							   schema->conf_type); -		seq_printf(s, r->format_str, dom->id, max_data_width, +		seq_printf(s, r->format_str, dom->hdr.id, max_data_width,  			   ctrl_val);  		sep = true;  	} @@ -489,7 +489,7 @@ int rdtgroup_schemata_show(struct kernfs_open_file *of,  			} else {  				seq_printf(s, "%s:%d=%x\n",  					   rdtgrp->plr->s->res->name, -					   rdtgrp->plr->d->id, +					   rdtgrp->plr->d->hdr.id,  					   rdtgrp->plr->cbm);  			}  		} else { @@ -514,8 +514,8 @@ static int smp_mon_event_count(void *arg)  }  void mon_event_read(struct rmid_read *rr, struct rdt_resource *r, -		    struct rdt_domain *d, struct rdtgroup *rdtgrp, -		    int evtid, int first) +		    struct rdt_mon_domain *d, struct rdtgroup *rdtgrp, +		    cpumask_t *cpumask, int evtid, int first)  {  	int cpu; @@ -529,7 +529,6 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,  	rr->evtid = evtid;  	rr->r = r;  	rr->d = d; -	rr->val = 0;  	rr->first = first;  	rr->arch_mon_ctx = resctrl_arch_mon_ctx_alloc(r, evtid);  	if (IS_ERR(rr->arch_mon_ctx)) { @@ -537,7 +536,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,  		return;  	} -	cpu = cpumask_any_housekeeping(&d->cpu_mask, RESCTRL_PICK_ANY_CPU); +	cpu = cpumask_any_housekeeping(cpumask, RESCTRL_PICK_ANY_CPU);  	/*  	 * cpumask_any_housekeeping() prefers housekeeping CPUs, but @@ -546,7 +545,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,  	 * counters on some platforms if its called in IRQ context.  	 */  	if (tick_nohz_full_cpu(cpu)) -		smp_call_function_any(&d->cpu_mask, mon_event_count, rr, 1); +		smp_call_function_any(cpumask, mon_event_count, rr, 1);  	else  		smp_call_on_cpu(cpu, smp_mon_event_count, rr, false); @@ -556,12 +555,13 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,  int rdtgroup_mondata_show(struct seq_file *m, void *arg)  {  	struct kernfs_open_file *of = m->private; +	struct rdt_domain_hdr *hdr; +	struct rmid_read rr = {0}; +	struct rdt_mon_domain *d;  	u32 resid, evtid, domid;  	struct rdtgroup *rdtgrp;  	struct rdt_resource *r;  	union mon_data_bits md; -	struct rdt_domain *d; -	struct rmid_read rr;  	int ret = 0;  	rdtgrp = rdtgroup_kn_lock_live(of->kn); @@ -574,15 +574,40 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg)  	resid = md.u.rid;  	domid = md.u.domid;  	evtid = md.u.evtid; -  	r = &rdt_resources_all[resid].r_resctrl; -	d = rdt_find_domain(r, domid, NULL); -	if (IS_ERR_OR_NULL(d)) { + +	if (md.u.sum) { +		/* +		 * This file requires summing across all domains that share +		 * the L3 cache id that was provided in the "domid" field of the +		 * mon_data_bits union. Search all domains in the resource for +		 * one that matches this cache id. +		 */ +		list_for_each_entry(d, &r->mon_domains, hdr.list) { +			if (d->ci->id == domid) { +				rr.ci = d->ci; +				mon_event_read(&rr, r, NULL, rdtgrp, +					       &d->ci->shared_cpu_map, evtid, false); +				goto checkresult; +			} +		}  		ret = -ENOENT;  		goto out; +	} else { +		/* +		 * This file provides data from a single domain. Search +		 * the resource to find the domain with "domid". +		 */ +		hdr = rdt_find_domain(&r->mon_domains, domid, NULL); +		if (!hdr || WARN_ON_ONCE(hdr->type != RESCTRL_MON_DOMAIN)) { +			ret = -ENOENT; +			goto out; +		} +		d = container_of(hdr, struct rdt_mon_domain, hdr); +		mon_event_read(&rr, r, d, rdtgrp, &d->hdr.cpu_mask, evtid, false);  	} -	mon_event_read(&rr, r, d, rdtgrp, evtid, false); +checkresult:  	if (rr.err == -EIO)  		seq_puts(m, "Error\n");  |