]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86,fs/resctrl: Detect Assignable Bandwidth Monitoring feature details
authorBabu Moger <babu.moger@amd.com>
Fri, 5 Sep 2025 21:34:07 +0000 (16:34 -0500)
committerBorislav Petkov (AMD) <bp@alien8.de>
Mon, 15 Sep 2025 10:08:01 +0000 (12:08 +0200)
ABMC feature details are reported via CPUID Fn8000_0020_EBX_x5.
Bits Description
15:0 MAX_ABMC Maximum Supported Assignable Bandwidth
     Monitoring Counter ID + 1

The ABMC feature details are documented in APM [1] available from [2].

  [1] AMD64 Architecture Programmer's Manual Volume 2: System Programming
  Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth
  Monitoring (ABMC).

Detect the feature and number of assignable counters supported. For backward
compatibility, upon detecting the assignable counter feature, enable the
mbm_total_bytes and mbm_local_bytes events that users are familiar with as
part of original L3 MBM support.

Signed-off-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Link: https://lore.kernel.org/cover.1757108044.git.babu.moger@amd.com
Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537
arch/x86/kernel/cpu/resctrl/core.c
arch/x86/kernel/cpu/resctrl/monitor.c
fs/resctrl/monitor.c
include/linux/resctrl.h

index 267e9206a999268293c1e42aa9f5149b4e0ce061..2e68aa02ad3f4c5000cf139872c1e348b103be26 100644 (file)
@@ -883,6 +883,8 @@ static __init bool get_rdt_mon_resources(void)
                resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID);
                ret = true;
        }
+       if (rdt_cpu_has(X86_FEATURE_ABMC))
+               ret = true;
 
        if (!ret)
                return false;
@@ -978,7 +980,7 @@ static enum cpuhp_state rdt_online;
 /* Runs once on the BSP during boot. */
 void resctrl_cpu_detect(struct cpuinfo_x86 *c)
 {
-       if (!cpu_has(c, X86_FEATURE_CQM_LLC)) {
+       if (!cpu_has(c, X86_FEATURE_CQM_LLC) && !cpu_has(c, X86_FEATURE_ABMC)) {
                c->x86_cache_max_rmid  = -1;
                c->x86_cache_occ_scale = -1;
                c->x86_cache_mbm_width_offset = -1;
@@ -990,7 +992,8 @@ void resctrl_cpu_detect(struct cpuinfo_x86 *c)
 
        if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC) ||
            cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL) ||
-           cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)) {
+           cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL) ||
+           cpu_has(c, X86_FEATURE_ABMC)) {
                u32 eax, ebx, ecx, edx;
 
                /* QoS sub-leaf, EAX=0Fh, ECX=1 */
index 2558b1bdef8b547f8f58f0fef79a6e48fbfae263..0a695ce68f462ddb48ca922577048e7546af0e8f 100644 (file)
@@ -339,6 +339,7 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
        unsigned int mbm_offset = boot_cpu_data.x86_cache_mbm_width_offset;
        struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
        unsigned int threshold;
+       u32 eax, ebx, ecx, edx;
 
        snc_nodes_per_l3_cache = snc_get_config();
 
@@ -368,14 +369,18 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
         */
        resctrl_rmid_realloc_threshold = resctrl_arch_round_mon_val(threshold);
 
-       if (rdt_cpu_has(X86_FEATURE_BMEC)) {
-               u32 eax, ebx, ecx, edx;
-
+       if (rdt_cpu_has(X86_FEATURE_BMEC) || rdt_cpu_has(X86_FEATURE_ABMC)) {
                /* Detect list of bandwidth sources that can be tracked */
                cpuid_count(0x80000020, 3, &eax, &ebx, &ecx, &edx);
                r->mon.mbm_cfg_mask = ecx & MAX_EVT_CONFIG_BITS;
        }
 
+       if (rdt_cpu_has(X86_FEATURE_ABMC)) {
+               r->mon.mbm_cntr_assignable = true;
+               cpuid_count(0x80000020, 5, &eax, &ebx, &ecx, &edx);
+               r->mon.num_mbm_cntrs = (ebx & GENMASK(15, 0)) + 1;
+       }
+
        r->mon_capable = true;
 
        return 0;
index e0dfa5fb969e4fca5e3797dbe6df0b0a7e8b65bb..b578451de2b50b7dfa44c358d7d812d599e65aaa 100644 (file)
@@ -922,6 +922,13 @@ int resctrl_mon_resource_init(void)
        else if (resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID))
                mba_mbps_default_event = QOS_L3_MBM_TOTAL_EVENT_ID;
 
+       if (r->mon.mbm_cntr_assignable) {
+               if (!resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID))
+                       resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID);
+               if (!resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID))
+                       resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID);
+       }
+
        return 0;
 }
 
index fe2af6cb96d4b47683eb165b8674e0deb26c2d6b..eb80cc233be431db0818d334ed10962f402bc4d7 100644 (file)
@@ -260,10 +260,14 @@ enum resctrl_schema_fmt {
  * @num_rmid:          Number of RMIDs available.
  * @mbm_cfg_mask:      Memory transactions that can be tracked when bandwidth
  *                     monitoring events can be configured.
+ * @num_mbm_cntrs:     Number of assignable counters.
+ * @mbm_cntr_assignable:Is system capable of supporting counter assignment?
  */
 struct resctrl_mon {
        int                     num_rmid;
        unsigned int            mbm_cfg_mask;
+       int                     num_mbm_cntrs;
+       bool                    mbm_cntr_assignable;
 };
 
 /**