Hi Babu, On 9/27/24 9:22 AM, Moger, Babu wrote: > Hi Reinitte, > > On 9/19/2024 12:45 PM, Reinette Chatre wrote: >> On 9/4/24 3:21 PM, Babu Moger wrote: ... >>> +} >>> + >>> static int rdtgroup_mbm_assign_mode_show(struct kernfs_open_file *of, >>> struct seq_file *s, void *v) >>> { >>> @@ -1793,12 +1802,48 @@ static int mbm_local_bytes_config_show(struct kernfs_open_file *of, >>> return 0; >>> } >>> +static int resctrl_mbm_event_update_assign(struct rdt_resource *r, >>> + struct rdt_mon_domain *d, u32 evtid) >>> +{ >>> + struct rdt_mon_domain *dom; >>> + struct rdtgroup *rdtg; >>> + int ret = 0; >>> + >>> + if (!resctrl_arch_mbm_cntr_assign_enabled(r)) >>> + return ret; >>> + >>> + list_for_each_entry(rdtg, &rdt_all_groups, rdtgroup_list) { >>> + struct rdtgroup *crg; >>> + >>> + list_for_each_entry(dom, &r->mon_domains, hdr.list) { >>> + if (d == dom && resctrl_mbm_event_assigned(rdtg, dom, evtid)) { >>> + ret = rdtgroup_assign_cntr(r, rdtg, dom, evtid); >>> + if (ret) >>> + goto out_done; >>> + } >>> + } >>> + >>> + list_for_each_entry(crg, &rdtg->mon.crdtgrp_list, mon.crdtgrp_list) { >>> + list_for_each_entry(dom, &r->mon_domains, hdr.list) { >>> + if (d == dom && resctrl_mbm_event_assigned(crg, dom, evtid)) { >>> + ret = rdtgroup_assign_cntr(r, crg, dom, evtid); >>> + if (ret) >>> + goto out_done; >>> + } >>> + } >>> + } >>> + } >>> + >>> +out_done: >>> + return ret; >>> +} >>> static void mbm_config_write_domain(struct rdt_resource *r, >>> struct rdt_mon_domain *d, u32 evtid, u32 val) >>> { >>> struct mon_config_info mon_info = {0}; >>> u32 config_val; >>> + int ret; >>> /* >>> * Check the current config value first. If both are the same then >>> @@ -1822,6 +1867,14 @@ static void mbm_config_write_domain(struct rdt_resource *r, >>> resctrl_arch_event_config_set, >>> &mon_info, 1); >>> + /* >>> + * Counter assignments needs to be updated to match the event >>> + * configuration. >>> + */ >>> + ret = resctrl_mbm_event_update_assign(r, d, evtid); >>> + if (ret) >>> + rdt_last_cmd_puts("Assign failed, event will be Unavailable\n"); >>> + >> >> This does not look right. This function _just_ returned from an IPI on appropriate CPU and then >> starts flow to do _another_ IPI to run code that could have just been run during previous IPI. >> The whole flow to call rdgroup_assign_cntr() also seems like an obfuscated way to call resctrl_arch_assign_cntr() >> to just reconfigure the counter (not actually assign it). >> Could it perhaps call some resctrl fs code via single IPI that in turn calls the appropriate arch code to set the new >> mon event config and re-configures the counter? >> > > I think we can simplify this. We dont have to go thru all the rdtgroups to figure out if the counter is assigned or not. > > I can move the code inside mon_config_write() after the call mbm_config_write_domain(). mbm_config_write_domain() already does an IPI so if I understand correctly this will still result in a second IPI that seems unnecessary to me. Why can the reconfigure not be done with a single IPI? > > Using the domain bitmap we can figure out which of the counters are assigned in the domain. I can use the hardware help to update the assignment for each counter. This has to be done via IPI. > Something like this. > > static void rdtgroup_abmc_dom_cfg(void *info) > { > union l3_qos_abmc_cfg *abmc_cfg = info; > u32 val = abmc_cfg->bw_type; > > /* Get the counter configuration */ > wrmsrl(MSR_IA32_L3_QOS_ABMC_CFG, *abmc_cfg); > rdmsrl(MGR_IA32_L3_QOS_ABMC_DSC, *abmc_cfg); > This is not clear to me. I expected MSR_IA32_L3_QOS_ABMC_DSC to return the bw_type that was just written to MSR_IA32_L3_QOS_ABMC_CFG. It is also not clear to me how these registers can be used without a valid counter ID. I seem to miss the context of this call. > /* update the counter configuration */ > if (abmc_cfg->bw_type != val) { > abmc_cfg->bw_type = val; > abmc_cfg.split.cfg_en = 1; > wrmsrl(MSR_IA32_L3_QOS_ABMC_CFG, *abmc_cfg); > } > } > > Reinette