Commit b84b3381 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86_cache_for_v6.11_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 resource control updates from Borislav Petkov:

 - Enable Sub-NUMA clustering to work with resource control on Intel by
   teaching resctrl to handle scopes due to the clustering which
   partitions the L3 cache into sets. Modify and extend the subsystem to
   handle such scopes properly

* tag 'x86_cache_for_v6.11_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/resctrl: Update documentation with Sub-NUMA cluster changes
  x86/resctrl: Detect Sub-NUMA Cluster (SNC) mode
  x86/resctrl: Enable shared RMID mode on Sub-NUMA Cluster (SNC) systems
  x86/resctrl: Make __mon_event_count() handle sum domains
  x86/resctrl: Fill out rmid_read structure for smp_call*() to read a counter
  x86/resctrl: Handle removing directories in Sub-NUMA Cluster (SNC) mode
  x86/resctrl: Create Sub-NUMA Cluster (SNC) monitor files
  x86/resctrl: Allocate a new field in union mon_data_bits
  x86/resctrl: Refactor mkdir_mondata_subdir() with a helper function
  x86/resctrl: Initialize on-stack struct rmid_read instances
  x86/resctrl: Add a new field to struct rmid_read for summation of domains
  x86/resctrl: Prepare for new Sub-NUMA Cluster (SNC) monitor files
  x86/resctrl: Block use of mba_MBps mount option on Sub-NUMA Cluster (SNC) systems
  x86/resctrl: Introduce snc_nodes_per_l3_cache
  x86/resctrl: Add node-scope to the options for feature scope
  x86/resctrl: Split the rdt_domain and rdt_hw_domain structures
  x86/resctrl: Prepare for different scope for control/monitor operations
  x86/resctrl: Prepare to split rdt_domain structure
  x86/resctrl: Prepare for new domain scope
parents d6797831 ea34999f
...@@ -375,6 +375,10 @@ When monitoring is enabled all MON groups will also contain: ...@@ -375,6 +375,10 @@ When monitoring is enabled all MON groups will also contain:
all tasks in the group. In CTRL_MON groups these files provide all tasks in the group. In CTRL_MON groups these files provide
the sum for all tasks in the CTRL_MON group and all tasks in the sum for all tasks in the CTRL_MON group and all tasks in
MON groups. Please see example section for more details on usage. MON groups. Please see example section for more details on usage.
On systems with Sub-NUMA Cluster (SNC) enabled there are extra
directories for each node (located within the "mon_L3_XX" directory
for the L3 cache they occupy). These are named "mon_sub_L3_YY"
where "YY" is the node number.
"mon_hw_id": "mon_hw_id":
Available only with debug option. The identifier used by hardware Available only with debug option. The identifier used by hardware
...@@ -484,6 +488,29 @@ if non-contiguous 1s value is supported. On a system with a 20-bit mask ...@@ -484,6 +488,29 @@ if non-contiguous 1s value is supported. On a system with a 20-bit mask
each bit represents 5% of the capacity of the cache. You could partition each bit represents 5% of the capacity of the cache. You could partition
the cache into four equal parts with masks: 0x1f, 0x3e0, 0x7c00, 0xf8000. the cache into four equal parts with masks: 0x1f, 0x3e0, 0x7c00, 0xf8000.
Notes on Sub-NUMA Cluster mode
==============================
When SNC mode is enabled, Linux may load balance tasks between Sub-NUMA
nodes much more readily than between regular NUMA nodes since the CPUs
on Sub-NUMA nodes share the same L3 cache and the system may report
the NUMA distance between Sub-NUMA nodes with a lower value than used
for regular NUMA nodes.
The top-level monitoring files in each "mon_L3_XX" directory provide
the sum of data across all SNC nodes sharing an L3 cache instance.
Users who bind tasks to the CPUs of a specific Sub-NUMA node can read
the "llc_occupancy", "mbm_total_bytes", and "mbm_local_bytes" in the
"mon_sub_L3_YY" directories to get node local data.
Memory bandwidth allocation is still performed at the L3 cache
level. I.e. throttling controls are applied to all SNC nodes.
L3 cache allocation bitmaps also apply to all SNC nodes. But note that
the amount of L3 cache represented by each bit is divided by the number
of SNC nodes per L3 cache. E.g. with a 100MB cache on a system with 10-bit
allocation masks each bit normally represents 10MB. With SNC mode enabled
with two SNC nodes per L3 cache, each bit only represents 5MB.
Memory bandwidth Allocation and monitoring Memory bandwidth Allocation and monitoring
========================================== ==========================================
......
...@@ -1164,6 +1164,7 @@ ...@@ -1164,6 +1164,7 @@
#define MSR_IA32_QM_CTR 0xc8e #define MSR_IA32_QM_CTR 0xc8e
#define MSR_IA32_PQR_ASSOC 0xc8f #define MSR_IA32_PQR_ASSOC 0xc8f
#define MSR_IA32_L3_CBM_BASE 0xc90 #define MSR_IA32_L3_CBM_BASE 0xc90
#define MSR_RMID_SNC_CONFIG 0xca0
#define MSR_IA32_L2_CBM_BASE 0xd10 #define MSR_IA32_L2_CBM_BASE 0xd10
#define MSR_IA32_MBA_THRTL_BASE 0xd50 #define MSR_IA32_MBA_THRTL_BASE 0xd50
......
This diff is collapsed.
...@@ -60,7 +60,7 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) ...@@ -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, 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; struct resctrl_staged_config *cfg;
u32 closid = data->rdtgrp->closid; u32 closid = data->rdtgrp->closid;
...@@ -69,7 +69,7 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s, ...@@ -69,7 +69,7 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
cfg = &d->staged_config[s->conf_type]; cfg = &d->staged_config[s->conf_type];
if (cfg->have_new_ctrl) { 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; return -EINVAL;
} }
...@@ -139,7 +139,7 @@ static bool cbm_validate(char *buf, u32 *data, struct rdt_resource *r) ...@@ -139,7 +139,7 @@ static bool cbm_validate(char *buf, u32 *data, struct rdt_resource *r)
* resource type. * resource type.
*/ */
int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s, 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 rdtgroup *rdtgrp = data->rdtgrp;
struct resctrl_staged_config *cfg; struct resctrl_staged_config *cfg;
...@@ -148,7 +148,7 @@ int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s, ...@@ -148,7 +148,7 @@ int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s,
cfg = &d->staged_config[s->conf_type]; cfg = &d->staged_config[s->conf_type];
if (cfg->have_new_ctrl) { 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; return -EINVAL;
} }
...@@ -208,8 +208,8 @@ static int parse_line(char *line, struct resctrl_schema *s, ...@@ -208,8 +208,8 @@ static int parse_line(char *line, struct resctrl_schema *s,
struct resctrl_staged_config *cfg; struct resctrl_staged_config *cfg;
struct rdt_resource *r = s->res; struct rdt_resource *r = s->res;
struct rdt_parse_data data; struct rdt_parse_data data;
struct rdt_ctrl_domain *d;
char *dom = NULL, *id; char *dom = NULL, *id;
struct rdt_domain *d;
unsigned long dom_id; unsigned long dom_id;
/* Walking r->domains, ensure it can't race with cpuhp */ /* Walking r->domains, ensure it can't race with cpuhp */
...@@ -231,8 +231,8 @@ static int parse_line(char *line, struct resctrl_schema *s, ...@@ -231,8 +231,8 @@ static int parse_line(char *line, struct resctrl_schema *s,
return -EINVAL; return -EINVAL;
} }
dom = strim(dom); dom = strim(dom);
list_for_each_entry(d, &r->domains, list) { list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
if (d->id == dom_id) { if (d->hdr.id == dom_id) {
data.buf = dom; data.buf = dom;
data.rdtgrp = rdtgrp; data.rdtgrp = rdtgrp;
if (r->parse_ctrlval(&data, s, d)) if (r->parse_ctrlval(&data, s, d))
...@@ -272,15 +272,15 @@ static u32 get_config_index(u32 closid, enum resctrl_conf_type type) ...@@ -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) 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_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); u32 idx = get_config_index(closid, t);
struct msr_param msr_param; 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; return -EINVAL;
hw_dom->ctrl_val[idx] = cfg_val; hw_dom->ctrl_val[idx] = cfg_val;
...@@ -297,17 +297,17 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, ...@@ -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) int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
{ {
struct resctrl_staged_config *cfg; struct resctrl_staged_config *cfg;
struct rdt_hw_domain *hw_dom; struct rdt_hw_ctrl_domain *hw_dom;
struct msr_param msr_param; struct msr_param msr_param;
struct rdt_ctrl_domain *d;
enum resctrl_conf_type t; enum resctrl_conf_type t;
struct rdt_domain *d;
u32 idx; u32 idx;
/* Walking r->domains, ensure it can't race with cpuhp */ /* Walking r->domains, ensure it can't race with cpuhp */
lockdep_assert_cpus_held(); lockdep_assert_cpus_held();
list_for_each_entry(d, &r->domains, list) { list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
hw_dom = resctrl_to_arch_dom(d); hw_dom = resctrl_to_arch_ctrl_dom(d);
msr_param.res = NULL; msr_param.res = NULL;
for (t = 0; t < CDP_NUM_TYPES; t++) { for (t = 0; t < CDP_NUM_TYPES; t++) {
cfg = &hw_dom->d_resctrl.staged_config[t]; cfg = &hw_dom->d_resctrl.staged_config[t];
...@@ -330,7 +330,7 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid) ...@@ -330,7 +330,7 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
} }
} }
if (msr_param.res) 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; return 0;
...@@ -430,10 +430,10 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, ...@@ -430,10 +430,10 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
return ret ?: nbytes; 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) 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); u32 idx = get_config_index(closid, type);
return hw_dom->ctrl_val[idx]; return hw_dom->ctrl_val[idx];
...@@ -442,7 +442,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d, ...@@ -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) static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int closid)
{ {
struct rdt_resource *r = schema->res; struct rdt_resource *r = schema->res;
struct rdt_domain *dom; struct rdt_ctrl_domain *dom;
bool sep = false; bool sep = false;
u32 ctrl_val; u32 ctrl_val;
...@@ -450,7 +450,7 @@ static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int clo ...@@ -450,7 +450,7 @@ static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int clo
lockdep_assert_cpus_held(); lockdep_assert_cpus_held();
seq_printf(s, "%*s:", max_name_width, schema->name); 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) if (sep)
seq_puts(s, ";"); seq_puts(s, ";");
...@@ -460,7 +460,7 @@ static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int clo ...@@ -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, ctrl_val = resctrl_arch_get_config(r, dom, closid,
schema->conf_type); 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); ctrl_val);
sep = true; sep = true;
} }
...@@ -489,7 +489,7 @@ int rdtgroup_schemata_show(struct kernfs_open_file *of, ...@@ -489,7 +489,7 @@ int rdtgroup_schemata_show(struct kernfs_open_file *of,
} else { } else {
seq_printf(s, "%s:%d=%x\n", seq_printf(s, "%s:%d=%x\n",
rdtgrp->plr->s->res->name, rdtgrp->plr->s->res->name,
rdtgrp->plr->d->id, rdtgrp->plr->d->hdr.id,
rdtgrp->plr->cbm); rdtgrp->plr->cbm);
} }
} else { } else {
...@@ -514,8 +514,8 @@ static int smp_mon_event_count(void *arg) ...@@ -514,8 +514,8 @@ static int smp_mon_event_count(void *arg)
} }
void mon_event_read(struct rmid_read *rr, struct rdt_resource *r, void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
struct rdt_domain *d, struct rdtgroup *rdtgrp, struct rdt_mon_domain *d, struct rdtgroup *rdtgrp,
int evtid, int first) cpumask_t *cpumask, int evtid, int first)
{ {
int cpu; int cpu;
...@@ -529,7 +529,6 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r, ...@@ -529,7 +529,6 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
rr->evtid = evtid; rr->evtid = evtid;
rr->r = r; rr->r = r;
rr->d = d; rr->d = d;
rr->val = 0;
rr->first = first; rr->first = first;
rr->arch_mon_ctx = resctrl_arch_mon_ctx_alloc(r, evtid); rr->arch_mon_ctx = resctrl_arch_mon_ctx_alloc(r, evtid);
if (IS_ERR(rr->arch_mon_ctx)) { if (IS_ERR(rr->arch_mon_ctx)) {
...@@ -537,7 +536,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r, ...@@ -537,7 +536,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
return; 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 * cpumask_any_housekeeping() prefers housekeeping CPUs, but
...@@ -546,7 +545,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r, ...@@ -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. * counters on some platforms if its called in IRQ context.
*/ */
if (tick_nohz_full_cpu(cpu)) 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 else
smp_call_on_cpu(cpu, smp_mon_event_count, rr, false); 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, ...@@ -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) int rdtgroup_mondata_show(struct seq_file *m, void *arg)
{ {
struct kernfs_open_file *of = m->private; 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; u32 resid, evtid, domid;
struct rdtgroup *rdtgrp; struct rdtgroup *rdtgrp;
struct rdt_resource *r; struct rdt_resource *r;
union mon_data_bits md; union mon_data_bits md;
struct rdt_domain *d;
struct rmid_read rr;
int ret = 0; int ret = 0;
rdtgrp = rdtgroup_kn_lock_live(of->kn); rdtgrp = rdtgroup_kn_lock_live(of->kn);
...@@ -574,15 +574,40 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg) ...@@ -574,15 +574,40 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg)
resid = md.u.rid; resid = md.u.rid;
domid = md.u.domid; domid = md.u.domid;
evtid = md.u.evtid; evtid = md.u.evtid;
r = &rdt_resources_all[resid].r_resctrl; 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; ret = -ENOENT;
goto out; 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) if (rr.err == -EIO)
seq_puts(m, "Error\n"); seq_puts(m, "Error\n");
......
...@@ -127,29 +127,54 @@ struct mon_evt { ...@@ -127,29 +127,54 @@ struct mon_evt {
}; };
/** /**
* union mon_data_bits - Monitoring details for each event file * union mon_data_bits - Monitoring details for each event file.
* @priv: Used to store monitoring event data in @u * @priv: Used to store monitoring event data in @u
* as kernfs private data * as kernfs private data.
* @rid: Resource id associated with the event file * @u.rid: Resource id associated with the event file.
* @evtid: Event id associated with the event file * @u.evtid: Event id associated with the event file.
* @domid: The domain to which the event file belongs * @u.sum: Set when event must be summed across multiple
* @u: Name of the bit fields struct * domains.
* @u.domid: When @u.sum is zero this is the domain to which
* the event file belongs. When @sum is one this
* is the id of the L3 cache that all domains to be
* summed share.
* @u: Name of the bit fields struct.
*/ */
union mon_data_bits { union mon_data_bits {
void *priv; void *priv;
struct { struct {
unsigned int rid : 10; unsigned int rid : 10;
enum resctrl_event_id evtid : 8; enum resctrl_event_id evtid : 7;
unsigned int sum : 1;
unsigned int domid : 14; unsigned int domid : 14;
} u; } u;
}; };
/**
* struct rmid_read - Data passed across smp_call*() to read event count.
* @rgrp: Resource group for which the counter is being read. If it is a parent
* resource group then its event count is summed with the count from all
* its child resource groups.
* @r: Resource describing the properties of the event being read.
* @d: Domain that the counter should be read from. If NULL then sum all
* domains in @r sharing L3 @ci.id
* @evtid: Which monitor event to read.
* @first: Initialize MBM counter when true.
* @ci: Cacheinfo for L3. Only set when @d is NULL. Used when summing domains.
* @err: Error encountered when reading counter.
* @val: Returned value of event counter. If @rgrp is a parent resource group,
* @val includes the sum of event counts from its child resource groups.
* If @d is NULL, @val includes the sum of all domains in @r sharing @ci.id,
* (summed across child resource groups if @rgrp is a parent resource group).
* @arch_mon_ctx: Hardware monitor allocated for this read request (MPAM only).
*/
struct rmid_read { struct rmid_read {
struct rdtgroup *rgrp; struct rdtgroup *rgrp;
struct rdt_resource *r; struct rdt_resource *r;
struct rdt_domain *d; struct rdt_mon_domain *d;
enum resctrl_event_id evtid; enum resctrl_event_id evtid;
bool first; bool first;
struct cacheinfo *ci;
int err; int err;
u64 val; u64 val;
void *arch_mon_ctx; void *arch_mon_ctx;
...@@ -232,7 +257,7 @@ struct mongroup { ...@@ -232,7 +257,7 @@ struct mongroup {
*/ */
struct pseudo_lock_region { struct pseudo_lock_region {
struct resctrl_schema *s; struct resctrl_schema *s;
struct rdt_domain *d; struct rdt_ctrl_domain *d;
u32 cbm; u32 cbm;
wait_queue_head_t lock_thread_wq; wait_queue_head_t lock_thread_wq;
int thread_done; int thread_done;
...@@ -355,25 +380,41 @@ struct arch_mbm_state { ...@@ -355,25 +380,41 @@ struct arch_mbm_state {
}; };
/** /**
* struct rdt_hw_domain - Arch private attributes of a set of CPUs that share * struct rdt_hw_ctrl_domain - Arch private attributes of a set of CPUs that share
* a resource * a resource for a control function
* @d_resctrl: Properties exposed to the resctrl file system * @d_resctrl: Properties exposed to the resctrl file system
* @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID) * @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID)
*
* Members of this structure are accessed via helpers that provide abstraction.
*/
struct rdt_hw_ctrl_domain {
struct rdt_ctrl_domain d_resctrl;
u32 *ctrl_val;
};
/**
* struct rdt_hw_mon_domain - Arch private attributes of a set of CPUs that share
* a resource for a monitor function
* @d_resctrl: Properties exposed to the resctrl file system
* @arch_mbm_total: arch private state for MBM total bandwidth * @arch_mbm_total: arch private state for MBM total bandwidth
* @arch_mbm_local: arch private state for MBM local bandwidth * @arch_mbm_local: arch private state for MBM local bandwidth
* *
* Members of this structure are accessed via helpers that provide abstraction. * Members of this structure are accessed via helpers that provide abstraction.
*/ */
struct rdt_hw_domain { struct rdt_hw_mon_domain {
struct rdt_domain d_resctrl; struct rdt_mon_domain d_resctrl;
u32 *ctrl_val;
struct arch_mbm_state *arch_mbm_total; struct arch_mbm_state *arch_mbm_total;
struct arch_mbm_state *arch_mbm_local; struct arch_mbm_state *arch_mbm_local;
}; };
static inline struct rdt_hw_domain *resctrl_to_arch_dom(struct rdt_domain *r) static inline struct rdt_hw_ctrl_domain *resctrl_to_arch_ctrl_dom(struct rdt_ctrl_domain *r)
{ {
return container_of(r, struct rdt_hw_domain, d_resctrl); return container_of(r, struct rdt_hw_ctrl_domain, d_resctrl);
}
static inline struct rdt_hw_mon_domain *resctrl_to_arch_mon_dom(struct rdt_mon_domain *r)
{
return container_of(r, struct rdt_hw_mon_domain, d_resctrl);
} }
/** /**
...@@ -385,7 +426,7 @@ static inline struct rdt_hw_domain *resctrl_to_arch_dom(struct rdt_domain *r) ...@@ -385,7 +426,7 @@ static inline struct rdt_hw_domain *resctrl_to_arch_dom(struct rdt_domain *r)
*/ */
struct msr_param { struct msr_param {
struct rdt_resource *res; struct rdt_resource *res;
struct rdt_domain *dom; struct rdt_ctrl_domain *dom;
u32 low; u32 low;
u32 high; u32 high;
}; };
...@@ -458,9 +499,9 @@ static inline struct rdt_hw_resource *resctrl_to_arch_res(struct rdt_resource *r ...@@ -458,9 +499,9 @@ static inline struct rdt_hw_resource *resctrl_to_arch_res(struct rdt_resource *r
} }
int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s, int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s,
struct rdt_domain *d); struct rdt_ctrl_domain *d);
int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s, int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
struct rdt_domain *d); struct rdt_ctrl_domain *d);
extern struct mutex rdtgroup_mutex; extern struct mutex rdtgroup_mutex;
...@@ -493,6 +534,8 @@ static inline bool resctrl_arch_get_cdp_enabled(enum resctrl_res_level l) ...@@ -493,6 +534,8 @@ static inline bool resctrl_arch_get_cdp_enabled(enum resctrl_res_level l)
int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable); int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable);
void arch_mon_domain_online(struct rdt_resource *r, struct rdt_mon_domain *d);
/* /*
* To return the common struct rdt_resource, which is contained in struct * To return the common struct rdt_resource, which is contained in struct
* rdt_hw_resource, walk the resctrl member of struct rdt_hw_resource. * rdt_hw_resource, walk the resctrl member of struct rdt_hw_resource.
...@@ -558,27 +601,28 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn); ...@@ -558,27 +601,28 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn);
int rdtgroup_kn_mode_restrict(struct rdtgroup *r, const char *name); int rdtgroup_kn_mode_restrict(struct rdtgroup *r, const char *name);
int rdtgroup_kn_mode_restore(struct rdtgroup *r, const char *name, int rdtgroup_kn_mode_restore(struct rdtgroup *r, const char *name,
umode_t mask); umode_t mask);
struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id, struct rdt_domain_hdr *rdt_find_domain(struct list_head *h, int id,
struct list_head **pos); struct list_head **pos);
ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off); char *buf, size_t nbytes, loff_t off);
int rdtgroup_schemata_show(struct kernfs_open_file *of, int rdtgroup_schemata_show(struct kernfs_open_file *of,
struct seq_file *s, void *v); struct seq_file *s, void *v);
bool rdtgroup_cbm_overlaps(struct resctrl_schema *s, struct rdt_domain *d, bool rdtgroup_cbm_overlaps(struct resctrl_schema *s, struct rdt_ctrl_domain *d,
unsigned long cbm, int closid, bool exclusive); unsigned long cbm, int closid, bool exclusive);
unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r, struct rdt_domain *d, unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r, struct rdt_ctrl_domain *d,
unsigned long cbm); unsigned long cbm);
enum rdtgrp_mode rdtgroup_mode_by_closid(int closid); enum rdtgrp_mode rdtgroup_mode_by_closid(int closid);
int rdtgroup_tasks_assigned(struct rdtgroup *r); int rdtgroup_tasks_assigned(struct rdtgroup *r);
int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp); int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp);
int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp); int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp);
bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_domain *d, unsigned long cbm); bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_ctrl_domain *d, unsigned long cbm);
bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d); bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_ctrl_domain *d);
int rdt_pseudo_lock_init(void); int rdt_pseudo_lock_init(void);
void rdt_pseudo_lock_release(void); void rdt_pseudo_lock_release(void);
int rdtgroup_pseudo_lock_create(struct rdtgroup *rdtgrp); int rdtgroup_pseudo_lock_create(struct rdtgroup *rdtgrp);
void rdtgroup_pseudo_lock_remove(struct rdtgroup *rdtgrp); void rdtgroup_pseudo_lock_remove(struct rdtgroup *rdtgrp);
struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r); struct rdt_ctrl_domain *get_ctrl_domain_from_cpu(int cpu, struct rdt_resource *r);
struct rdt_mon_domain *get_mon_domain_from_cpu(int cpu, struct rdt_resource *r);
int closids_supported(void); int closids_supported(void);
void closid_free(int closid); void closid_free(int closid);
int alloc_rmid(u32 closid); int alloc_rmid(u32 closid);
...@@ -589,19 +633,19 @@ bool __init rdt_cpu_has(int flag); ...@@ -589,19 +633,19 @@ bool __init rdt_cpu_has(int flag);
void mon_event_count(void *info); void mon_event_count(void *info);
int rdtgroup_mondata_show(struct seq_file *m, void *arg); int rdtgroup_mondata_show(struct seq_file *m, void *arg);
void mon_event_read(struct rmid_read *rr, struct rdt_resource *r, void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
struct rdt_domain *d, struct rdtgroup *rdtgrp, struct rdt_mon_domain *d, struct rdtgroup *rdtgrp,
int evtid, int first); cpumask_t *cpumask, int evtid, int first);
void mbm_setup_overflow_handler(struct rdt_domain *dom, void mbm_setup_overflow_handler(struct rdt_mon_domain *dom,
unsigned long delay_ms, unsigned long delay_ms,
int exclude_cpu); int exclude_cpu);
void mbm_handle_overflow(struct work_struct *work); void mbm_handle_overflow(struct work_struct *work);
void __init intel_rdt_mbm_apply_quirk(void); void __init intel_rdt_mbm_apply_quirk(void);
bool is_mba_sc(struct rdt_resource *r); bool is_mba_sc(struct rdt_resource *r);
void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms, void cqm_setup_limbo_handler(struct rdt_mon_domain *dom, unsigned long delay_ms,
int exclude_cpu); int exclude_cpu);
void cqm_handle_limbo(struct work_struct *work); void cqm_handle_limbo(struct work_struct *work);
bool has_busy_rmid(struct rdt_domain *d); bool has_busy_rmid(struct rdt_mon_domain *d);
void __check_limbo(struct rdt_domain *d, bool force_free); void __check_limbo(struct rdt_mon_domain *d, bool force_free);
void rdt_domain_reconfigure_cdp(struct rdt_resource *r); void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
void __init thread_throttle_mode_init(void); void __init thread_throttle_mode_init(void);
void __init mbm_config_rftype_init(const char *config); void __init mbm_config_rftype_init(const char *config);
......
This diff is collapsed.
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/cacheinfo.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
...@@ -221,7 +220,7 @@ static int pseudo_lock_cstates_constrain(struct pseudo_lock_region *plr) ...@@ -221,7 +220,7 @@ static int pseudo_lock_cstates_constrain(struct pseudo_lock_region *plr)
int cpu; int cpu;
int ret; int ret;
for_each_cpu(cpu, &plr->d->cpu_mask) { for_each_cpu(cpu, &plr->d->hdr.cpu_mask) {
pm_req = kzalloc(sizeof(*pm_req), GFP_KERNEL); pm_req = kzalloc(sizeof(*pm_req), GFP_KERNEL);
if (!pm_req) { if (!pm_req) {
rdt_last_cmd_puts("Failure to allocate memory for PM QoS\n"); rdt_last_cmd_puts("Failure to allocate memory for PM QoS\n");
...@@ -292,11 +291,15 @@ static void pseudo_lock_region_clear(struct pseudo_lock_region *plr) ...@@ -292,11 +291,15 @@ static void pseudo_lock_region_clear(struct pseudo_lock_region *plr)
*/ */
static int pseudo_lock_region_init(struct pseudo_lock_region *plr) static int pseudo_lock_region_init(struct pseudo_lock_region *plr)
{ {
enum resctrl_scope scope = plr->s->res->ctrl_scope;
struct cacheinfo *ci; struct cacheinfo *ci;
int ret; int ret;
if (WARN_ON_ONCE(scope != RESCTRL_L2_CACHE && scope != RESCTRL_L3_CACHE))
return -ENODEV;
/* Pick the first cpu we find that is associated with the cache. */ /* Pick the first cpu we find that is associated with the cache. */
plr->cpu = cpumask_first(&plr->d->cpu_mask); plr->cpu = cpumask_first(&plr->d->hdr.cpu_mask);
if (!cpu_online(plr->cpu)) { if (!cpu_online(plr->cpu)) {
rdt_last_cmd_printf("CPU %u associated with cache not online\n", rdt_last_cmd_printf("CPU %u associated with cache not online\n",
...@@ -305,7 +308,7 @@ static int pseudo_lock_region_init(struct pseudo_lock_region *plr) ...@@ -305,7 +308,7 @@ static int pseudo_lock_region_init(struct pseudo_lock_region *plr)
goto out_region; goto out_region;
} }
ci = get_cpu_cacheinfo_level(plr->cpu, plr->s->res->cache_level); ci = get_cpu_cacheinfo_level(plr->cpu, scope);
if (ci) { if (ci) {
plr->line_size = ci->coherency_line_size; plr->line_size = ci->coherency_line_size;
plr->size = rdtgroup_cbm_to_size(plr->s->res, plr->d, plr->cbm); plr->size = rdtgroup_cbm_to_size(plr->s->res, plr->d, plr->cbm);
...@@ -805,7 +808,7 @@ int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp) ...@@ -805,7 +808,7 @@ int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp)
* Return: true if @cbm overlaps with pseudo-locked region on @d, false * Return: true if @cbm overlaps with pseudo-locked region on @d, false
* otherwise. * otherwise.
*/ */
bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_domain *d, unsigned long cbm) bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_ctrl_domain *d, unsigned long cbm)
{ {
unsigned int cbm_len; unsigned int cbm_len;
unsigned long cbm_b; unsigned long cbm_b;
...@@ -832,11 +835,11 @@ bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_domain *d, unsigned long cbm ...@@ -832,11 +835,11 @@ bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_domain *d, unsigned long cbm
* if it is not possible to test due to memory allocation issue, * if it is not possible to test due to memory allocation issue,
* false otherwise. * false otherwise.
*/ */
bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d) bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_ctrl_domain *d)
{ {
struct rdt_ctrl_domain *d_i;
cpumask_var_t cpu_with_psl; cpumask_var_t cpu_with_psl;
struct rdt_resource *r; struct rdt_resource *r;
struct rdt_domain *d_i;
bool ret = false; bool ret = false;
/* Walking r->domains, ensure it can't race with cpuhp */ /* Walking r->domains, ensure it can't race with cpuhp */
...@@ -850,10 +853,10 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d) ...@@ -850,10 +853,10 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d)
* associated with them. * associated with them.
*/ */
for_each_alloc_capable_rdt_resource(r) { for_each_alloc_capable_rdt_resource(r) {
list_for_each_entry(d_i, &r->domains, list) { list_for_each_entry(d_i, &r->ctrl_domains, hdr.list) {
if (d_i->plr) if (d_i->plr)
cpumask_or(cpu_with_psl, cpu_with_psl, cpumask_or(cpu_with_psl, cpu_with_psl,
&d_i->cpu_mask); &d_i->hdr.cpu_mask);
} }
} }
...@@ -861,7 +864,7 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d) ...@@ -861,7 +864,7 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d)
* Next test if new pseudo-locked region would intersect with * Next test if new pseudo-locked region would intersect with
* existing region. * existing region.
*/ */
if (cpumask_intersects(&d->cpu_mask, cpu_with_psl)) if (cpumask_intersects(&d->hdr.cpu_mask, cpu_with_psl))
ret = true; ret = true;
free_cpumask_var(cpu_with_psl); free_cpumask_var(cpu_with_psl);
...@@ -1193,7 +1196,7 @@ static int pseudo_lock_measure_cycles(struct rdtgroup *rdtgrp, int sel) ...@@ -1193,7 +1196,7 @@ static int pseudo_lock_measure_cycles(struct rdtgroup *rdtgrp, int sel)
} }
plr->thread_done = 0; plr->thread_done = 0;
cpu = cpumask_first(&plr->d->cpu_mask); cpu = cpumask_first(&plr->d->hdr.cpu_mask);
if (!cpu_online(cpu)) { if (!cpu_online(cpu)) {
ret = -ENODEV; ret = -ENODEV;
goto out; goto out;
...@@ -1523,7 +1526,7 @@ static int pseudo_lock_dev_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -1523,7 +1526,7 @@ static int pseudo_lock_dev_mmap(struct file *filp, struct vm_area_struct *vma)
* may be scheduled elsewhere and invalidate entries in the * may be scheduled elsewhere and invalidate entries in the
* pseudo-locked region. * pseudo-locked region.
*/ */
if (!cpumask_subset(current->cpus_ptr, &plr->d->cpu_mask)) { if (!cpumask_subset(current->cpus_ptr, &plr->d->hdr.cpu_mask)) {
mutex_unlock(&rdtgroup_mutex); mutex_unlock(&rdtgroup_mutex);
return -EINVAL; return -EINVAL;
} }
......
This diff is collapsed.
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#ifndef _RESCTRL_H #ifndef _RESCTRL_H
#define _RESCTRL_H #define _RESCTRL_H
#include <linux/cacheinfo.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/pid.h> #include <linux/pid.h>
...@@ -58,11 +59,45 @@ struct resctrl_staged_config { ...@@ -58,11 +59,45 @@ struct resctrl_staged_config {
bool have_new_ctrl; bool have_new_ctrl;
}; };
enum resctrl_domain_type {
RESCTRL_CTRL_DOMAIN,
RESCTRL_MON_DOMAIN,
};
/** /**
* struct rdt_domain - group of CPUs sharing a resctrl resource * struct rdt_domain_hdr - common header for different domain types
* @list: all instances of this resource * @list: all instances of this resource
* @id: unique id for this instance * @id: unique id for this instance
* @type: type of this instance
* @cpu_mask: which CPUs share this resource * @cpu_mask: which CPUs share this resource
*/
struct rdt_domain_hdr {
struct list_head list;
int id;
enum resctrl_domain_type type;
struct cpumask cpu_mask;
};
/**
* struct rdt_ctrl_domain - group of CPUs sharing a resctrl control resource
* @hdr: common header for different domain types
* @plr: pseudo-locked region (if any) associated with domain
* @staged_config: parsed configuration to be applied
* @mbps_val: When mba_sc is enabled, this holds the array of user
* specified control values for mba_sc in MBps, indexed
* by closid
*/
struct rdt_ctrl_domain {
struct rdt_domain_hdr hdr;
struct pseudo_lock_region *plr;
struct resctrl_staged_config staged_config[CDP_NUM_TYPES];
u32 *mbps_val;
};
/**
* struct rdt_mon_domain - group of CPUs sharing a resctrl monitor resource
* @hdr: common header for different domain types
* @ci: cache info for this domain
* @rmid_busy_llc: bitmap of which limbo RMIDs are above threshold * @rmid_busy_llc: bitmap of which limbo RMIDs are above threshold
* @mbm_total: saved state for MBM total bandwidth * @mbm_total: saved state for MBM total bandwidth
* @mbm_local: saved state for MBM local bandwidth * @mbm_local: saved state for MBM local bandwidth
...@@ -70,16 +105,10 @@ struct resctrl_staged_config { ...@@ -70,16 +105,10 @@ struct resctrl_staged_config {
* @cqm_limbo: worker to periodically read CQM h/w counters * @cqm_limbo: worker to periodically read CQM h/w counters
* @mbm_work_cpu: worker CPU for MBM h/w counters * @mbm_work_cpu: worker CPU for MBM h/w counters
* @cqm_work_cpu: worker CPU for CQM h/w counters * @cqm_work_cpu: worker CPU for CQM h/w counters
* @plr: pseudo-locked region (if any) associated with domain
* @staged_config: parsed configuration to be applied
* @mbps_val: When mba_sc is enabled, this holds the array of user
* specified control values for mba_sc in MBps, indexed
* by closid
*/ */
struct rdt_domain { struct rdt_mon_domain {
struct list_head list; struct rdt_domain_hdr hdr;
int id; struct cacheinfo *ci;
struct cpumask cpu_mask;
unsigned long *rmid_busy_llc; unsigned long *rmid_busy_llc;
struct mbm_state *mbm_total; struct mbm_state *mbm_total;
struct mbm_state *mbm_local; struct mbm_state *mbm_local;
...@@ -87,9 +116,6 @@ struct rdt_domain { ...@@ -87,9 +116,6 @@ struct rdt_domain {
struct delayed_work cqm_limbo; struct delayed_work cqm_limbo;
int mbm_work_cpu; int mbm_work_cpu;
int cqm_work_cpu; int cqm_work_cpu;
struct pseudo_lock_region *plr;
struct resctrl_staged_config staged_config[CDP_NUM_TYPES];
u32 *mbps_val;
}; };
/** /**
...@@ -150,16 +176,24 @@ struct resctrl_membw { ...@@ -150,16 +176,24 @@ struct resctrl_membw {
struct rdt_parse_data; struct rdt_parse_data;
struct resctrl_schema; struct resctrl_schema;
enum resctrl_scope {
RESCTRL_L2_CACHE = 2,
RESCTRL_L3_CACHE = 3,
RESCTRL_L3_NODE,
};
/** /**
* struct rdt_resource - attributes of a resctrl resource * struct rdt_resource - attributes of a resctrl resource
* @rid: The index of the resource * @rid: The index of the resource
* @alloc_capable: Is allocation available on this machine * @alloc_capable: Is allocation available on this machine
* @mon_capable: Is monitor feature available on this machine * @mon_capable: Is monitor feature available on this machine
* @num_rmid: Number of RMIDs available * @num_rmid: Number of RMIDs available
* @cache_level: Which cache level defines scope of this resource * @ctrl_scope: Scope of this resource for control functions
* @mon_scope: Scope of this resource for monitor functions
* @cache: Cache allocation related data * @cache: Cache allocation related data
* @membw: If the component has bandwidth controls, their properties. * @membw: If the component has bandwidth controls, their properties.
* @domains: RCU list of all domains for this resource * @ctrl_domains: RCU list of all control domains for this resource
* @mon_domains: RCU list of all monitor domains for this resource
* @name: Name to use in "schemata" file. * @name: Name to use in "schemata" file.
* @data_width: Character width of data when displaying * @data_width: Character width of data when displaying
* @default_ctrl: Specifies default cache cbm or memory B/W percent. * @default_ctrl: Specifies default cache cbm or memory B/W percent.
...@@ -174,17 +208,19 @@ struct rdt_resource { ...@@ -174,17 +208,19 @@ struct rdt_resource {
bool alloc_capable; bool alloc_capable;
bool mon_capable; bool mon_capable;
int num_rmid; int num_rmid;
int cache_level; enum resctrl_scope ctrl_scope;
enum resctrl_scope mon_scope;
struct resctrl_cache cache; struct resctrl_cache cache;
struct resctrl_membw membw; struct resctrl_membw membw;
struct list_head domains; struct list_head ctrl_domains;
struct list_head mon_domains;
char *name; char *name;
int data_width; int data_width;
u32 default_ctrl; u32 default_ctrl;
const char *format_str; const char *format_str;
int (*parse_ctrlval)(struct rdt_parse_data *data, int (*parse_ctrlval)(struct rdt_parse_data *data,
struct resctrl_schema *s, struct resctrl_schema *s,
struct rdt_domain *d); struct rdt_ctrl_domain *d);
struct list_head evt_list; struct list_head evt_list;
unsigned long fflags; unsigned long fflags;
bool cdp_capable; bool cdp_capable;
...@@ -218,13 +254,15 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid); ...@@ -218,13 +254,15 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid);
* Update the ctrl_val and apply this config right now. * Update the ctrl_val and apply this config right now.
* Must be called on one of the domain's CPUs. * Must be called on one of the domain's CPUs.
*/ */
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); u32 closid, enum resctrl_conf_type t, u32 cfg_val);
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); u32 closid, enum resctrl_conf_type type);
int resctrl_online_domain(struct rdt_resource *r, struct rdt_domain *d); int resctrl_online_ctrl_domain(struct rdt_resource *r, struct rdt_ctrl_domain *d);
void resctrl_offline_domain(struct rdt_resource *r, struct rdt_domain *d); int resctrl_online_mon_domain(struct rdt_resource *r, struct rdt_mon_domain *d);
void resctrl_offline_ctrl_domain(struct rdt_resource *r, struct rdt_ctrl_domain *d);
void resctrl_offline_mon_domain(struct rdt_resource *r, struct rdt_mon_domain *d);
void resctrl_online_cpu(unsigned int cpu); void resctrl_online_cpu(unsigned int cpu);
void resctrl_offline_cpu(unsigned int cpu); void resctrl_offline_cpu(unsigned int cpu);
...@@ -253,7 +291,7 @@ void resctrl_offline_cpu(unsigned int cpu); ...@@ -253,7 +291,7 @@ void resctrl_offline_cpu(unsigned int cpu);
* Return: * Return:
* 0 on success, or -EIO, -EINVAL etc on error. * 0 on success, or -EIO, -EINVAL etc on error.
*/ */
int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d, int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_mon_domain *d,
u32 closid, u32 rmid, enum resctrl_event_id eventid, u32 closid, u32 rmid, enum resctrl_event_id eventid,
u64 *val, void *arch_mon_ctx); u64 *val, void *arch_mon_ctx);
...@@ -286,7 +324,7 @@ static inline void resctrl_arch_rmid_read_context_check(void) ...@@ -286,7 +324,7 @@ static inline void resctrl_arch_rmid_read_context_check(void)
* *
* This can be called from any CPU. * This can be called from any CPU.
*/ */
void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d, void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_mon_domain *d,
u32 closid, u32 rmid, u32 closid, u32 rmid,
enum resctrl_event_id eventid); enum resctrl_event_id eventid);
...@@ -299,7 +337,7 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d, ...@@ -299,7 +337,7 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d,
* *
* This can be called from any CPU. * This can be called from any CPU.
*/ */
void resctrl_arch_reset_rmid_all(struct rdt_resource *r, struct rdt_domain *d); void resctrl_arch_reset_rmid_all(struct rdt_resource *r, struct rdt_mon_domain *d);
extern unsigned int resctrl_rmid_realloc_threshold; extern unsigned int resctrl_rmid_realloc_threshold;
extern unsigned int resctrl_rmid_realloc_limit; extern unsigned int resctrl_rmid_realloc_limit;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment