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

x86/resctrl: Allow per-rmid arch private storage to be reset

To abstract the rmid counters into a helper that returns the number
of bytes counted, architecture specific per-rmid state is needed.

It needs to be possible to reset this hidden state, as the values
may outlive the life of an rmid, or the mount time of the filesystem.

mon_event_read() is called with first = true when an rmid is first
allocated in mkdir_mondata_subdir(). Add resctrl_arch_reset_rmid()
and call it from __mon_event_count()'s rr->first check.
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-15-james.morse@arm.com
parent 48dbe31a
...@@ -22,14 +22,6 @@ ...@@ -22,14 +22,6 @@
#define L2_QOS_CDP_ENABLE 0x01ULL #define L2_QOS_CDP_ENABLE 0x01ULL
/*
* Event IDs are used to program IA32_QM_EVTSEL before reading event
* counter from IA32_QM_CTR
*/
#define QOS_L3_OCCUP_EVENT_ID 0x01
#define QOS_L3_MBM_TOTAL_EVENT_ID 0x02
#define QOS_L3_MBM_LOCAL_EVENT_ID 0x03
#define CQM_LIMBOCHECK_INTERVAL 1000 #define CQM_LIMBOCHECK_INTERVAL 1000
#define MBM_CNTR_WIDTH_BASE 24 #define MBM_CNTR_WIDTH_BASE 24
...@@ -73,7 +65,7 @@ DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key); ...@@ -73,7 +65,7 @@ DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key);
* @list: entry in &rdt_resource->evt_list * @list: entry in &rdt_resource->evt_list
*/ */
struct mon_evt { struct mon_evt {
u32 evtid; enum resctrl_event_id evtid;
char *name; char *name;
struct list_head list; struct list_head list;
}; };
...@@ -90,9 +82,9 @@ struct mon_evt { ...@@ -90,9 +82,9 @@ struct mon_evt {
union mon_data_bits { union mon_data_bits {
void *priv; void *priv;
struct { struct {
unsigned int rid : 10; unsigned int rid : 10;
unsigned int evtid : 8; enum resctrl_event_id evtid : 8;
unsigned int domid : 14; unsigned int domid : 14;
} u; } u;
}; };
...@@ -100,7 +92,7 @@ struct rmid_read { ...@@ -100,7 +92,7 @@ struct rmid_read {
struct rdtgroup *rgrp; struct rdtgroup *rgrp;
struct rdt_resource *r; struct rdt_resource *r;
struct rdt_domain *d; struct rdt_domain *d;
int evtid; enum resctrl_event_id evtid;
bool first; bool first;
u64 val; u64 val;
}; };
......
...@@ -137,7 +137,37 @@ static inline struct rmid_entry *__rmid_entry(u32 rmid) ...@@ -137,7 +137,37 @@ static inline struct rmid_entry *__rmid_entry(u32 rmid)
return entry; return entry;
} }
static u64 __rmid_read(u32 rmid, u32 eventid) static struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_domain *hw_dom,
u32 rmid,
enum resctrl_event_id eventid)
{
switch (eventid) {
case QOS_L3_OCCUP_EVENT_ID:
return NULL;
case QOS_L3_MBM_TOTAL_EVENT_ID:
return &hw_dom->arch_mbm_total[rmid];
case QOS_L3_MBM_LOCAL_EVENT_ID:
return &hw_dom->arch_mbm_local[rmid];
}
/* Never expect to get here */
WARN_ON_ONCE(1);
return NULL;
}
void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d,
u32 rmid, enum resctrl_event_id eventid)
{
struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
struct arch_mbm_state *am;
am = get_arch_mbm_state(hw_dom, rmid, eventid);
if (am)
memset(am, 0, sizeof(*am));
}
static u64 __rmid_read(u32 rmid, enum resctrl_event_id eventid)
{ {
u64 val; u64 val;
...@@ -291,6 +321,9 @@ static u64 __mon_event_count(u32 rmid, struct rmid_read *rr) ...@@ -291,6 +321,9 @@ static u64 __mon_event_count(u32 rmid, struct rmid_read *rr)
struct mbm_state *m; struct mbm_state *m;
u64 chunks, tval; u64 chunks, tval;
if (rr->first)
resctrl_arch_reset_rmid(rr->r, rr->d, rmid, rr->evtid);
tval = __rmid_read(rmid, rr->evtid); tval = __rmid_read(rmid, rr->evtid);
if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) { if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) {
return tval; return tval;
......
...@@ -32,6 +32,16 @@ enum resctrl_conf_type { ...@@ -32,6 +32,16 @@ enum resctrl_conf_type {
#define CDP_NUM_TYPES (CDP_DATA + 1) #define CDP_NUM_TYPES (CDP_DATA + 1)
/*
* Event IDs, the values match those used to program IA32_QM_EVTSEL before
* reading IA32_QM_CTR on RDT systems.
*/
enum resctrl_event_id {
QOS_L3_OCCUP_EVENT_ID = 0x01,
QOS_L3_MBM_TOTAL_EVENT_ID = 0x02,
QOS_L3_MBM_LOCAL_EVENT_ID = 0x03,
};
/** /**
* struct resctrl_staged_config - parsed configuration to be applied * struct resctrl_staged_config - parsed configuration to be applied
* @new_ctrl: new ctrl value to be loaded * @new_ctrl: new ctrl value to be loaded
...@@ -210,4 +220,17 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d, ...@@ -210,4 +220,17 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d,
int resctrl_online_domain(struct rdt_resource *r, struct rdt_domain *d); int resctrl_online_domain(struct rdt_resource *r, struct rdt_domain *d);
void resctrl_offline_domain(struct rdt_resource *r, struct rdt_domain *d); void resctrl_offline_domain(struct rdt_resource *r, struct rdt_domain *d);
/**
* resctrl_arch_reset_rmid() - Reset any private state associated with rmid
* and eventid.
* @r: The domain's resource.
* @d: The rmid's domain.
* @rmid: The rmid whose counter values should be reset.
* @eventid: The eventid whose counter values should be reset.
*
* This can be called from any CPU.
*/
void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d,
u32 rmid, enum resctrl_event_id eventid);
#endif /* _RESCTRL_H */ #endif /* _RESCTRL_H */
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