The event configuration is domain specific and initialized during domain initialization. The values are stored in struct rdt_hw_mon_domain. It is not required to read the configuration register every time user asks for it. Use the value stored in struct rdt_hw_mon_domain instead. Introduce resctrl_arch_mon_event_config_get() and resctrl_arch_mon_event_config_set() to get/set architecture domain specific mbm_total_cfg/mbm_local_cfg values. Signed-off-by: Babu Moger <babu.moger@xxxxxxx> --- v12: Removed the un-necessary initialization of mon_config_info structure. Changed wrmsrl instead of wrmsr to address the below comment. https://lore.kernel.org/lkml/0fc8dbd4-07d8-40bd-8eec-402b48762807@xxxxxxxxx/ Fixed a minor typo in comment. Added comments to resctrl_arch_mon_event_config_get() and resctrl_arch_mon_event_config_set() Resolved the conflicts from the recent changes. This patch is for BMEC and there is no dependancy on ABMC feature. Moved it earlier. v11: Moved the mon_config_info structure definition to internal.h. Moved resctrl_arch_mon_event_config_get() and resctrl_arch_mon_event_config_set() to monitor.c file. Renamed local variable from val to config_val. v10: Moved the mon_config_info structure definition to resctrl.h. v9: Removed QOS_L3_OCCUP_EVENT_ID switch case in resctrl_arch_mon_event_config_set. Fixed a unnecessary space. v8: Renamed resctrl_arch_event_config_get() to resctrl_arch_mon_event_config_get(). resctrl_arch_event_config_set() to resctrl_arch_mon_event_config_set(). v7: Removed check if (val == INVALID_CONFIG_VALUE) as resctrl_arch_event_config_get already prints warning. Kept the Event config value definitions as is. v6: Fixed inconstancy with types. Made all the types to u32 for config value. Removed few rdt_last_cmd_puts as it is not necessary. Removed unused config value definitions. Few more updates to commit message. v5: Introduced resctrl_arch_event_config_get and resctrl_arch_event_config_get() based on our discussion. https://lore.kernel.org/lkml/68e861f9-245d-4496-a72e-46fc57d19c62@xxxxxxx/ v4: New patch. --- arch/x86/kernel/cpu/resctrl/monitor.c | 52 +++++++++++++++++++++ arch/x86/kernel/cpu/resctrl/rdtgroup.c | 63 +++++--------------------- include/linux/resctrl.h | 18 +++----- 3 files changed, 71 insertions(+), 62 deletions(-) diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index abd337fbd01d..b84cd48c3d95 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -1330,3 +1330,55 @@ void __init intel_rdt_mbm_apply_quirk(void) mbm_cf_rmidthreshold = mbm_cf_table[cf_index].rmidthreshold; mbm_cf = mbm_cf_table[cf_index].cf; } + +/* + * May run on CPU that does not belong to domain. + */ +u32 resctrl_arch_mon_event_config_get(struct rdt_mon_domain *d, + enum resctrl_event_id eventid) +{ + struct rdt_hw_mon_domain *hw_dom = resctrl_to_arch_mon_dom(d); + + switch (eventid) { + case QOS_L3_OCCUP_EVENT_ID: + break; + case QOS_L3_MBM_TOTAL_EVENT_ID: + return hw_dom->mbm_total_cfg; + case QOS_L3_MBM_LOCAL_EVENT_ID: + return hw_dom->mbm_local_cfg; + } + + /* Never expect to get here */ + WARN_ON_ONCE(1); + + return INVALID_CONFIG_VALUE; +} + +/* + * Runs on CPU that belongs to domain. + */ +void resctrl_arch_mon_event_config_set(void *info) +{ + struct resctrl_mon_config_info *mon_info = info; + struct rdt_hw_mon_domain *hw_dom; + unsigned int index; + + index = mon_event_config_index_get(mon_info->evtid); + if (index == INVALID_CONFIG_INDEX) + return; + + wrmsrl(MSR_IA32_EVT_CFG_BASE + index, mon_info->mon_config); + + hw_dom = resctrl_to_arch_mon_dom(mon_info->d); + + switch (mon_info->evtid) { + case QOS_L3_MBM_TOTAL_EVENT_ID: + hw_dom->mbm_total_cfg = mon_info->mon_config; + break; + case QOS_L3_MBM_LOCAL_EVENT_ID: + hw_dom->mbm_local_cfg = mon_info->mon_config; + break; + default: + break; + } +} diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index bee32eaef8ab..b8100c89f1a6 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -1614,34 +1614,11 @@ unsigned int mon_event_config_index_get(u32 evtid) } } -void resctrl_arch_mon_event_config_read(void *_config_info) -{ - struct resctrl_mon_config_info *config_info = _config_info; - unsigned int index; - u64 msrval; - - index = mon_event_config_index_get(config_info->evtid); - if (index == INVALID_CONFIG_INDEX) { - pr_warn_once("Invalid event id %d\n", config_info->evtid); - return; - } - rdmsrl(MSR_IA32_EVT_CFG_BASE + index, msrval); - - /* Report only the valid event configuration bits */ - config_info->mon_config = msrval & MAX_EVT_CONFIG_BITS; -} - -static void mondata_config_read(struct resctrl_mon_config_info *mon_info) -{ - smp_call_function_any(&mon_info->d->hdr.cpu_mask, - resctrl_arch_mon_event_config_read, mon_info, 1); -} - static int mbm_config_show(struct seq_file *s, struct rdt_resource *r, u32 evtid) { - struct resctrl_mon_config_info mon_info; struct rdt_mon_domain *dom; bool sep = false; + u32 config_val; cpus_read_lock(); mutex_lock(&rdtgroup_mutex); @@ -1650,13 +1627,8 @@ static int mbm_config_show(struct seq_file *s, struct rdt_resource *r, u32 evtid if (sep) seq_puts(s, ";"); - memset(&mon_info, 0, sizeof(struct resctrl_mon_config_info)); - mon_info.r = r; - mon_info.d = dom; - mon_info.evtid = evtid; - mondata_config_read(&mon_info); - - seq_printf(s, "%d=0x%02x", dom->hdr.id, mon_info.mon_config); + config_val = resctrl_arch_mon_event_config_get(dom, evtid); + seq_printf(s, "%d=0x%02x", dom->hdr.id, config_val); sep = true; } seq_puts(s, "\n"); @@ -1687,35 +1659,23 @@ static int mbm_local_bytes_config_show(struct kernfs_open_file *of, return 0; } -void resctrl_arch_mon_event_config_write(void *_config_info) -{ - struct resctrl_mon_config_info *config_info = _config_info; - unsigned int index; - - index = mon_event_config_index_get(config_info->evtid); - if (index == INVALID_CONFIG_INDEX) { - pr_warn_once("Invalid event id %d\n", config_info->evtid); - return; - } - wrmsr(MSR_IA32_EVT_CFG_BASE + index, config_info->mon_config, 0); -} - static void mbm_config_write_domain(struct rdt_resource *r, struct rdt_mon_domain *d, u32 evtid, u32 val) { - struct resctrl_mon_config_info mon_info = {0}; + struct resctrl_mon_config_info mon_info; + u32 config_val; /* - * Read the current config value first. If both are the same then + * Check the current config value first. If both are the same then * no need to write it again. */ + config_val = resctrl_arch_mon_event_config_get(d, evtid); + if (config_val == INVALID_CONFIG_VALUE || config_val == val) + return; + mon_info.r = r; mon_info.d = d; mon_info.evtid = evtid; - mondata_config_read(&mon_info); - if (mon_info.mon_config == val) - return; - mon_info.mon_config = val; /* @@ -1724,7 +1684,8 @@ static void mbm_config_write_domain(struct rdt_resource *r, * are scoped at the domain level. Writing any of these MSRs * on one CPU is observed by all the CPUs in the domain. */ - smp_call_function_any(&d->hdr.cpu_mask, resctrl_arch_mon_event_config_write, + smp_call_function_any(&d->hdr.cpu_mask, + resctrl_arch_mon_event_config_set, &mon_info, 1); /* diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index 880351ca3dfc..afa9aabf014c 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -361,7 +361,7 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid); __init bool resctrl_arch_is_evt_configurable(enum resctrl_event_id evt); /** - * resctrl_arch_mon_event_config_write() - Write the config for an event. + * resctrl_arch_mon_event_config_set() - Write the config for an event. * @config_info: struct resctrl_mon_config_info describing the resource, domain * and event. * @@ -370,19 +370,15 @@ __init bool resctrl_arch_is_evt_configurable(enum resctrl_event_id evt); * * Called via IPI to reach a CPU that is a member of the specified domain. */ -void resctrl_arch_mon_event_config_write(void *config_info); +void resctrl_arch_mon_event_config_set(void *config_info); /** - * resctrl_arch_mon_event_config_read() - Read the config for an event. - * @config_info: struct resctrl_mon_config_info describing the resource, domain - * and event. - * - * Reads resource, domain and eventid from @config_info and reads the - * hardware config value into config_info->mon_config. - * - * Called via IPI to reach a CPU that is a member of the specified domain. + * resctrl_arch_mon_event_config_get() - Get config value from the hardware domain. + * @d: Monitoring domain to read config value + * @eventid: enum resctrl_event_id describing type */ -void resctrl_arch_mon_event_config_read(void *config_info); +u32 resctrl_arch_mon_event_config_get(struct rdt_mon_domain *d, + enum resctrl_event_id eventid); /* For use by arch code to remap resctrl's smaller CDP CLOSID range */ static inline u32 resctrl_get_config_index(u32 closid, -- 2.34.1