diff options
Diffstat (limited to 'arch/x86/kernel/cpu/resctrl/monitor.c')
-rw-r--r-- | arch/x86/kernel/cpu/resctrl/monitor.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index 27bb4947a176..e91afe99b763 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -17,7 +17,10 @@ #include <linux/module.h> #include <linux/slab.h> + #include <asm/cpu_device_id.h> +#include <asm/resctrl.h> + #include "internal.h" struct rmid_entry { @@ -37,8 +40,8 @@ static LIST_HEAD(rmid_free_lru); * @rmid_limbo_count count of currently unused but (potentially) * dirty RMIDs. * This counts RMIDs that no one is currently using but that - * may have a occupancy value > intel_cqm_threshold. User can change - * the threshold occupancy value. + * may have a occupancy value > resctrl_rmid_realloc_threshold. User can + * change the threshold occupancy value. */ static unsigned int rmid_limbo_count; @@ -59,10 +62,10 @@ bool rdt_mon_capable; unsigned int rdt_mon_features; /* - * This is the threshold cache occupancy at which we will consider an + * This is the threshold cache occupancy in bytes at which we will consider an * RMID available for re-allocation. */ -unsigned int resctrl_cqm_threshold; +unsigned int resctrl_rmid_realloc_threshold; #define CF(cf) ((unsigned long)(1048576 * (cf) + 0.5)) @@ -223,14 +226,13 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d, */ void __check_limbo(struct rdt_domain *d, bool force_free) { + struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl; + struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); struct rmid_entry *entry; - struct rdt_resource *r; u32 crmid = 1, nrmid; bool rmid_dirty; u64 val = 0; - r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl; - /* * Skip RMID 0 and start from RMID 1 and check all the RMIDs that * are marked as busy for occupancy < threshold. If the occupancy @@ -245,10 +247,12 @@ void __check_limbo(struct rdt_domain *d, bool force_free) entry = __rmid_entry(nrmid); if (resctrl_arch_rmid_read(r, d, entry->rmid, - QOS_L3_OCCUP_EVENT_ID, &val)) + QOS_L3_OCCUP_EVENT_ID, &val)) { rmid_dirty = true; - else - rmid_dirty = (val >= resctrl_cqm_threshold); + } else { + val *= hw_res->mon_scale; + rmid_dirty = (val >= resctrl_rmid_realloc_threshold); + } if (force_free || !rmid_dirty) { clear_bit(entry->rmid, d->rmid_busy_llc); @@ -289,13 +293,12 @@ int alloc_rmid(void) static void add_rmid_to_limbo(struct rmid_entry *entry) { - struct rdt_resource *r; + struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl; + struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); struct rdt_domain *d; int cpu, err; u64 val = 0; - r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl; - entry->busy = 0; cpu = get_cpu(); list_for_each_entry(d, &r->domains, list) { @@ -303,7 +306,8 @@ static void add_rmid_to_limbo(struct rmid_entry *entry) err = resctrl_arch_rmid_read(r, d, entry->rmid, QOS_L3_OCCUP_EVENT_ID, &val); - if (err || val <= resctrl_cqm_threshold) + val *= hw_res->mon_scale; + if (err || val <= resctrl_rmid_realloc_threshold) continue; } @@ -744,6 +748,7 @@ int rdt_get_mon_l3_config(struct rdt_resource *r) unsigned int mbm_offset = boot_cpu_data.x86_cache_mbm_width_offset; struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); unsigned int cl_size = boot_cpu_data.x86_cache_size; + unsigned int threshold; int ret; hw_res->mon_scale = boot_cpu_data.x86_cache_occ_scale; @@ -762,10 +767,14 @@ int rdt_get_mon_l3_config(struct rdt_resource *r) * * For a 35MB LLC and 56 RMIDs, this is ~1.8% of the LLC. */ - resctrl_cqm_threshold = cl_size * 1024 / r->num_rmid; + threshold = cl_size * 1024 / r->num_rmid; - /* h/w works in units of "boot_cpu_data.x86_cache_occ_scale" */ - resctrl_cqm_threshold /= hw_res->mon_scale; + /* + * Because num_rmid may not be a power of two, round the value + * to the nearest multiple of hw_res->mon_scale so it matches a + * value the hardware will measure. mon_scale may not be a power of 2. + */ + resctrl_rmid_realloc_threshold = resctrl_arch_round_mon_val(threshold); ret = dom_data_init(r); if (ret) |