]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/resctrl: Fill out rmid_read structure for smp_call*() to read a counter
authorTony Luck <tony.luck@intel.com>
Fri, 28 Jun 2024 21:56:15 +0000 (14:56 -0700)
committerBorislav Petkov (AMD) <bp@alien8.de>
Tue, 2 Jul 2024 17:57:19 +0000 (19:57 +0200)
mon_event_read() fills out most fields of the struct rmid_read that is passed
via an smp_call*() function to a CPU that is part of the correct domain to
read the monitor counters.

With Sub-NUMA Cluster (SNC) mode there are now two cases to handle:

1) Reading a file that returns a value for a single domain.
   + Choose the CPU to execute from the domain cpu_mask

2) Reading a file that must sum across domains sharing an L3 cache
   instance.
   + Indicate to called code that a sum is needed by passing a NULL
     rdt_mon_domain pointer.
   + Choose the CPU from the L3 shared_cpu_map.

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>
Tested-by: Babu Moger <babu.moger@amd.com>
Link: https://lore.kernel.org/r/20240628215619.76401-16-tony.luck@intel.com
arch/x86/kernel/cpu/resctrl/ctrlmondata.c
arch/x86/kernel/cpu/resctrl/internal.h
arch/x86/kernel/cpu/resctrl/rdtgroup.c

index 4d76ff31a9e0d3f3dbe1fc2ef268999408231469..50fa1fe9a073f5832e687d01a88c1efcc91e22c9 100644 (file)
@@ -515,7 +515,7 @@ static int smp_mon_event_count(void *arg)
 
 void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
                    struct rdt_mon_domain *d, struct rdtgroup *rdtgrp,
-                   int evtid, int first)
+                   cpumask_t *cpumask, int evtid, int first)
 {
        int cpu;
 
@@ -536,7 +536,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
                return;
        }
 
-       cpu = cpumask_any_housekeeping(&d->hdr.cpu_mask, RESCTRL_PICK_ANY_CPU);
+       cpu = cpumask_any_housekeeping(cpumask, RESCTRL_PICK_ANY_CPU);
 
        /*
         * cpumask_any_housekeeping() prefers housekeeping CPUs, but
@@ -545,7 +545,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
         * counters on some platforms if its called in IRQ context.
         */
        if (tick_nohz_full_cpu(cpu))
-               smp_call_function_any(&d->hdr.cpu_mask, mon_event_count, rr, 1);
+               smp_call_function_any(cpumask, mon_event_count, rr, 1);
        else
                smp_call_on_cpu(cpu, smp_mon_event_count, rr, false);
 
@@ -574,16 +574,40 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg)
        resid = md.u.rid;
        domid = md.u.domid;
        evtid = md.u.evtid;
-
        r = &rdt_resources_all[resid].r_resctrl;
-       hdr = rdt_find_domain(&r->mon_domains, domid, NULL);
-       if (!hdr || WARN_ON_ONCE(hdr->type != RESCTRL_MON_DOMAIN)) {
+
+       if (md.u.sum) {
+               /*
+                * This file requires summing across all domains that share
+                * the L3 cache id that was provided in the "domid" field of the
+                * mon_data_bits union. Search all domains in the resource for
+                * one that matches this cache id.
+                */
+               list_for_each_entry(d, &r->mon_domains, hdr.list) {
+                       if (d->ci->id == domid) {
+                               rr.ci = d->ci;
+                               mon_event_read(&rr, r, NULL, rdtgrp,
+                                              &d->ci->shared_cpu_map, evtid, false);
+                               goto checkresult;
+                       }
+               }
                ret = -ENOENT;
                goto out;
+       } else {
+               /*
+                * This file provides data from a single domain. Search
+                * the resource to find the domain with "domid".
+                */
+               hdr = rdt_find_domain(&r->mon_domains, domid, NULL);
+               if (!hdr || WARN_ON_ONCE(hdr->type != RESCTRL_MON_DOMAIN)) {
+                       ret = -ENOENT;
+                       goto out;
+               }
+               d = container_of(hdr, struct rdt_mon_domain, hdr);
+               mon_event_read(&rr, r, d, rdtgrp, &d->hdr.cpu_mask, evtid, false);
        }
-       d = container_of(hdr, struct rdt_mon_domain, hdr);
 
-       mon_event_read(&rr, r, d, rdtgrp, evtid, false);
+checkresult:
 
        if (rr.err == -EIO)
                seq_puts(m, "Error\n");
index 13d862221f9c439fadc404c6aee50a5ac0ebaae4..16982d1baf9929192ec29a80a010a9430511da64 100644 (file)
@@ -632,7 +632,7 @@ void mon_event_count(void *info);
 int rdtgroup_mondata_show(struct seq_file *m, void *arg);
 void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
                    struct rdt_mon_domain *d, struct rdtgroup *rdtgrp,
-                   int evtid, int first);
+                   cpumask_t *cpumask, int evtid, int first);
 void mbm_setup_overflow_handler(struct rdt_mon_domain *dom,
                                unsigned long delay_ms,
                                int exclude_cpu);
index 58e53f1f52a05a149e2fd3e2ca6d63d9bef19334..d7163b764c626824b148c75bcd6a79ce9817ac9b 100644 (file)
@@ -3070,7 +3070,7 @@ static int mon_add_all_files(struct kernfs_node *kn, struct rdt_mon_domain *d,
                        return ret;
 
                if (!do_sum && is_mbm_event(mevt->evtid))
-                       mon_event_read(&rr, r, d, prgrp, mevt->evtid, true);
+                       mon_event_read(&rr, r, d, prgrp, &d->hdr.cpu_mask, mevt->evtid, true);
        }
 
        return 0;