Commit ff6357bb authored by James Morse's avatar James Morse Committed by Borislav Petkov

x86/resctrl: Allow update_mba_bw() to update controls directly

update_mba_bw() calculates a new control value for the MBA resource
based on the user provided mbps_val and the current measured
bandwidth. Some control values need remapping by delay_bw_map().

It does this by calling wrmsrl() directly. This needs splitting
up to be done by an architecture specific helper, so that the
remainder can eventually be moved to /fs/.

Add resctrl_arch_update_one() to apply one configuration value
to the provided resource and domain. This avoids the staging
and cross-calling that is only needed with changes made by
user-space. delay_bw_map() moves to be part of the arch code,
to maintain the 'percentage control' view of MBA resources
in resctrl.
Signed-off-by: default avatarJames Morse <james.morse@arm.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarJamie Iles <quic_jiles@quicinc.com>
Reviewed-by: default avatarShaopeng Tan <tan.shaopeng@fujitsu.com>
Reviewed-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Tested-by: default avatarXin Hao <xhao@linux.alibaba.com>
Tested-by: default avatarShaopeng Tan <tan.shaopeng@fujitsu.com>
Tested-by: default avatarCristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20220902154829.30399-12-james.morse@arm.com
parent b58d4eb1
...@@ -296,7 +296,7 @@ mba_wrmsr_amd(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r) ...@@ -296,7 +296,7 @@ mba_wrmsr_amd(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r)
* that can be written to QOS_MSRs. * that can be written to QOS_MSRs.
* There are currently no SKUs which support non linear delay values. * There are currently no SKUs which support non linear delay values.
*/ */
u32 delay_bw_map(unsigned long bw, struct rdt_resource *r) static u32 delay_bw_map(unsigned long bw, struct rdt_resource *r)
{ {
if (r->membw.delay_linear) if (r->membw.delay_linear)
return MAX_MBA_BW - bw; return MAX_MBA_BW - bw;
......
...@@ -282,6 +282,27 @@ static bool apply_config(struct rdt_hw_domain *hw_dom, ...@@ -282,6 +282,27 @@ static bool apply_config(struct rdt_hw_domain *hw_dom,
return false; return false;
} }
int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d,
u32 closid, enum resctrl_conf_type t, u32 cfg_val)
{
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))
return -EINVAL;
hw_dom->ctrl_val[idx] = cfg_val;
msr_param.res = r;
msr_param.low = idx;
msr_param.high = idx + 1;
hw_res->msr_update(d, &msr_param, r);
return 0;
}
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;
......
...@@ -527,7 +527,6 @@ void mbm_setup_overflow_handler(struct rdt_domain *dom, ...@@ -527,7 +527,6 @@ void mbm_setup_overflow_handler(struct rdt_domain *dom,
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);
u32 delay_bw_map(unsigned long bw, struct rdt_resource *r);
void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms); void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms);
void cqm_handle_limbo(struct work_struct *work); void cqm_handle_limbo(struct work_struct *work);
bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d); bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
......
...@@ -420,10 +420,8 @@ void mon_event_count(void *info) ...@@ -420,10 +420,8 @@ void mon_event_count(void *info)
*/ */
static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
{ {
u32 closid, rmid, cur_msr, cur_msr_val, new_msr_val; u32 closid, rmid, cur_msr_val, new_msr_val;
struct mbm_state *pmbm_data, *cmbm_data; struct mbm_state *pmbm_data, *cmbm_data;
struct rdt_hw_resource *hw_r_mba;
struct rdt_hw_domain *hw_dom_mba;
u32 cur_bw, delta_bw, user_bw; u32 cur_bw, delta_bw, user_bw;
struct rdt_resource *r_mba; struct rdt_resource *r_mba;
struct rdt_domain *dom_mba; struct rdt_domain *dom_mba;
...@@ -433,8 +431,8 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) ...@@ -433,8 +431,8 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
if (!is_mbm_local_enabled()) if (!is_mbm_local_enabled())
return; return;
hw_r_mba = &rdt_resources_all[RDT_RESOURCE_MBA]; r_mba = &rdt_resources_all[RDT_RESOURCE_MBA].r_resctrl;
r_mba = &hw_r_mba->r_resctrl;
closid = rgrp->closid; closid = rgrp->closid;
rmid = rgrp->mon.rmid; rmid = rgrp->mon.rmid;
pmbm_data = &dom_mbm->mbm_local[rmid]; pmbm_data = &dom_mbm->mbm_local[rmid];
...@@ -444,7 +442,6 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) ...@@ -444,7 +442,6 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
pr_warn_once("Failure to get domain for MBA update\n"); pr_warn_once("Failure to get domain for MBA update\n");
return; return;
} }
hw_dom_mba = resctrl_to_arch_dom(dom_mba);
cur_bw = pmbm_data->prev_bw; cur_bw = pmbm_data->prev_bw;
user_bw = dom_mba->mbps_val[closid]; user_bw = dom_mba->mbps_val[closid];
...@@ -486,9 +483,7 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) ...@@ -486,9 +483,7 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
return; return;
} }
cur_msr = hw_r_mba->msr_base + closid; resctrl_arch_update_one(r_mba, dom_mba, closid, CDP_NONE, new_msr_val);
wrmsrl(cur_msr, delay_bw_map(new_msr_val, r_mba));
hw_dom_mba->ctrl_val[closid] = new_msr_val;
/* /*
* Delta values are updated dynamically package wise for each * Delta values are updated dynamically package wise for each
......
...@@ -197,6 +197,14 @@ struct resctrl_schema { ...@@ -197,6 +197,14 @@ struct resctrl_schema {
/* The number of closid supported by this resource regardless of CDP */ /* The number of closid supported by this resource regardless of CDP */
u32 resctrl_arch_get_num_closid(struct rdt_resource *r); u32 resctrl_arch_get_num_closid(struct rdt_resource *r);
int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid); int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid);
/*
* Update the ctrl_val and apply this config right now.
* Must be called on one of the domain's CPUs.
*/
int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d,
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_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_domain(struct rdt_resource *r, struct rdt_domain *d);
......
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