]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86,fs/resctrl: Handle events that can be read from any CPU
authorTony Luck <tony.luck@intel.com>
Wed, 17 Dec 2025 17:20:58 +0000 (09:20 -0800)
committerBorislav Petkov (AMD) <bp@alien8.de>
Mon, 5 Jan 2026 14:38:07 +0000 (15:38 +0100)
resctrl assumes that monitor events can only be read from a CPU in the
cpumask_t set of each domain.  This is true for x86 events accessed with an
MSR interface, but may not be true for other access methods such as MMIO.

Introduce and use flag mon_evt::any_cpu, settable by architecture, that
indicates there are no restrictions on which CPU can read that event.  This
flag is not supported by the L3 event reading that requires to be run on a CPU
that belongs to the L3 domain of the event being read.

Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Link: https://lore.kernel.org/20251217172121.12030-1-tony.luck@intel.com
arch/x86/kernel/cpu/resctrl/core.c
fs/resctrl/ctrlmondata.c
fs/resctrl/internal.h
fs/resctrl/monitor.c
include/linux/resctrl.h

index b3a2dc56155d7f1efe5b2a1a65e243407a7f68c0..bd4a981061530ca786b34e58856a8f9a5969d032 100644 (file)
@@ -902,15 +902,15 @@ static __init bool get_rdt_mon_resources(void)
        bool ret = false;
 
        if (rdt_cpu_has(X86_FEATURE_CQM_OCCUP_LLC)) {
-               resctrl_enable_mon_event(QOS_L3_OCCUP_EVENT_ID);
+               resctrl_enable_mon_event(QOS_L3_OCCUP_EVENT_ID, false);
                ret = true;
        }
        if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) {
-               resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID);
+               resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID, false);
                ret = true;
        }
        if (rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL)) {
-               resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID);
+               resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID, false);
                ret = true;
        }
        if (rdt_cpu_has(X86_FEATURE_ABMC))
index 7f9b2fed117a66aaca943309a02f1e2069a09a9c..2c69fcd70eeb97fc950b528599fe5fca88b5acb0 100644 (file)
@@ -578,6 +578,11 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
                }
        }
 
+       if (evt->any_cpu) {
+               mon_event_count(rr);
+               goto out_ctx_free;
+       }
+
        cpu = cpumask_any_housekeeping(cpumask, RESCTRL_PICK_ANY_CPU);
 
        /*
@@ -591,6 +596,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
        else
                smp_call_on_cpu(cpu, smp_mon_event_count, rr, false);
 
+out_ctx_free:
        if (rr->arch_mon_ctx)
                resctrl_arch_mon_ctx_free(r, evt->evtid, rr->arch_mon_ctx);
 }
index 86cf38ab08a7f4aabb3d116d06a0402a8c36cbc6..fb0b6e40d022b97b92fa9af0f35097ca1a6fba2a 100644 (file)
@@ -61,6 +61,7 @@ static inline struct rdt_fs_context *rdt_fc2context(struct fs_context *fc)
  *                     READS_TO_REMOTE_MEM) being tracked by @evtid.
  *                     Only valid if @evtid is an MBM event.
  * @configurable:      true if the event is configurable
+ * @any_cpu:           true if the event can be read from any CPU
  * @enabled:           true if the event is enabled
  */
 struct mon_evt {
@@ -69,6 +70,7 @@ struct mon_evt {
        char                    *name;
        u32                     evt_cfg;
        bool                    configurable;
+       bool                    any_cpu;
        bool                    enabled;
 };
 
index 340b847ab397293f81838d392f465500f0c71f0f..8c76ac133bca3027ae620956ac9ffc832e521bd6 100644 (file)
@@ -518,6 +518,7 @@ static int __mon_event_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
 {
        switch (rr->r->rid) {
        case RDT_RESOURCE_L3:
+               WARN_ON_ONCE(rr->evt->any_cpu);
                if (rr->hdr)
                        return __l3_mon_event_count(rdtgrp, rr);
                else
@@ -987,7 +988,7 @@ struct mon_evt mon_event_all[QOS_NUM_EVENTS] = {
        },
 };
 
-void resctrl_enable_mon_event(enum resctrl_event_id eventid)
+void resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu)
 {
        if (WARN_ON_ONCE(eventid < QOS_FIRST_EVENT || eventid >= QOS_NUM_EVENTS))
                return;
@@ -996,6 +997,7 @@ void resctrl_enable_mon_event(enum resctrl_event_id eventid)
                return;
        }
 
+       mon_event_all[eventid].any_cpu = any_cpu;
        mon_event_all[eventid].enabled = true;
 }
 
index 79aaaabcdd3f94fd9eeec50fbadde4d44e9f7e29..22c5d07fe9ff56a5b10173bf805c73a71e332a23 100644 (file)
@@ -412,7 +412,7 @@ u32 resctrl_arch_get_num_closid(struct rdt_resource *r);
 u32 resctrl_arch_system_num_rmid_idx(void);
 int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid);
 
-void resctrl_enable_mon_event(enum resctrl_event_id eventid);
+void resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu);
 
 bool resctrl_is_mon_event_enabled(enum resctrl_event_id eventid);