]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
x86/resctrl: Allow per-rmid arch private storage to be reset
authorJames Morse <james.morse@arm.com>
Fri, 2 Sep 2022 15:48:22 +0000 (15:48 +0000)
committerBorislav Petkov <bp@suse.de>
Fri, 23 Sep 2022 10:49:04 +0000 (12:49 +0200)
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: James Morse <james.morse@arm.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Jamie Iles <quic_jiles@quicinc.com>
Reviewed-by: Shaopeng Tan <tan.shaopeng@fujitsu.com>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Xin Hao <xhao@linux.alibaba.com>
Tested-by: Shaopeng Tan <tan.shaopeng@fujitsu.com>
Tested-by: Cristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20220902154829.30399-15-james.morse@arm.com
arch/x86/kernel/cpu/resctrl/internal.h
arch/x86/kernel/cpu/resctrl/monitor.c
include/linux/resctrl.h

index 4de8e5bb93e1f84135287c02f4ad822237bc731b..b34a1403f033c44b666fcaa97b966a0e8df80bd5 100644 (file)
 
 #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 MBM_CNTR_WIDTH_BASE            24
@@ -73,7 +65,7 @@ DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key);
  * @list:              entry in &rdt_resource->evt_list
  */
 struct mon_evt {
-       u32                     evtid;
+       enum resctrl_event_id   evtid;
        char                    *name;
        struct list_head        list;
 };
@@ -90,9 +82,9 @@ struct mon_evt {
 union mon_data_bits {
        void *priv;
        struct {
-               unsigned int rid        : 10;
-               unsigned int evtid      : 8;
-               unsigned int domid      : 14;
+               unsigned int rid                : 10;
+               enum resctrl_event_id evtid     : 8;
+               unsigned int domid              : 14;
        } u;
 };
 
@@ -100,7 +92,7 @@ struct rmid_read {
        struct rdtgroup         *rgrp;
        struct rdt_resource     *r;
        struct rdt_domain       *d;
-       int                     evtid;
+       enum resctrl_event_id   evtid;
        bool                    first;
        u64                     val;
 };
index 2d81b6cd96320f479853f9fba7700e117833adf5..e9755143492b43a66a50dd8e21df7497a127b97e 100644 (file)
@@ -137,7 +137,37 @@ static inline struct rmid_entry *__rmid_entry(u32 rmid)
        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;
 
@@ -291,6 +321,9 @@ static u64 __mon_event_count(u32 rmid, struct rmid_read *rr)
        struct mbm_state *m;
        u64 chunks, tval;
 
+       if (rr->first)
+               resctrl_arch_reset_rmid(rr->r, rr->d, rmid, rr->evtid);
+
        tval = __rmid_read(rmid, rr->evtid);
        if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) {
                return tval;
index f4c9101df461b7e680cc0e08e8f8c1b9de15dfde..818456770176d30030f245b341e625d52e1199e0 100644 (file)
@@ -32,6 +32,16 @@ enum resctrl_conf_type {
 
 #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
  * @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,
 int resctrl_online_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 */