]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86/resctrl: Prepare for new domain scope
authorTony Luck <tony.luck@intel.com>
Fri, 28 Jun 2024 21:56:01 +0000 (14:56 -0700)
committerBorislav Petkov (AMD) <bp@alien8.de>
Tue, 2 Jul 2024 17:49:53 +0000 (19:49 +0200)
Resctrl resources operate on subsets of CPUs in the system with the
defining attribute of each subset being an instance of a particular
level of cache. E.g. all CPUs sharing an L3 cache would be part of the
same domain.

In preparation for features that are scoped at the NUMA node level,
change the code from explicit references to "cache_level" to a more
generic scope. At this point the only options for this scope are groups
of CPUs that share an L2 cache or L3 cache.

Clean up the error handling when looking up domains. Report invalid ids
before calling rdt_find_domain() in preparation for better messages when
scope can be other than cache scope. This means that rdt_find_domain()
will never return an error. So remove checks for error from the call sites.

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-2-tony.luck@intel.com
arch/x86/kernel/cpu/resctrl/core.c
arch/x86/kernel/cpu/resctrl/ctrlmondata.c
arch/x86/kernel/cpu/resctrl/pseudo_lock.c
arch/x86/kernel/cpu/resctrl/rdtgroup.c
include/linux/resctrl.h

index a113d9aba553e01739a167fbe45e595635984225..f85b2ff40eef0c0f9ebf2bd9c682e292e1b8b486 100644 (file)
@@ -68,7 +68,7 @@ struct rdt_hw_resource rdt_resources_all[] = {
                .r_resctrl = {
                        .rid                    = RDT_RESOURCE_L3,
                        .name                   = "L3",
-                       .cache_level            = 3,
+                       .scope                  = RESCTRL_L3_CACHE,
                        .domains                = domain_init(RDT_RESOURCE_L3),
                        .parse_ctrlval          = parse_cbm,
                        .format_str             = "%d=%0*x",
@@ -82,7 +82,7 @@ struct rdt_hw_resource rdt_resources_all[] = {
                .r_resctrl = {
                        .rid                    = RDT_RESOURCE_L2,
                        .name                   = "L2",
-                       .cache_level            = 2,
+                       .scope                  = RESCTRL_L2_CACHE,
                        .domains                = domain_init(RDT_RESOURCE_L2),
                        .parse_ctrlval          = parse_cbm,
                        .format_str             = "%d=%0*x",
@@ -96,7 +96,7 @@ struct rdt_hw_resource rdt_resources_all[] = {
                .r_resctrl = {
                        .rid                    = RDT_RESOURCE_MBA,
                        .name                   = "MB",
-                       .cache_level            = 3,
+                       .scope                  = RESCTRL_L3_CACHE,
                        .domains                = domain_init(RDT_RESOURCE_MBA),
                        .parse_ctrlval          = parse_bw,
                        .format_str             = "%d=%*u",
@@ -108,7 +108,7 @@ struct rdt_hw_resource rdt_resources_all[] = {
                .r_resctrl = {
                        .rid                    = RDT_RESOURCE_SMBA,
                        .name                   = "SMBA",
-                       .cache_level            = 3,
+                       .scope                  = RESCTRL_L3_CACHE,
                        .domains                = domain_init(RDT_RESOURCE_SMBA),
                        .parse_ctrlval          = parse_bw,
                        .format_str             = "%d=%*u",
@@ -392,9 +392,6 @@ struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id,
        struct rdt_domain *d;
        struct list_head *l;
 
-       if (id < 0)
-               return ERR_PTR(-ENODEV);
-
        list_for_each(l, &r->domains) {
                d = list_entry(l, struct rdt_domain, list);
                /* When id is found, return its domain. */
@@ -484,6 +481,19 @@ static int arch_domain_mbm_alloc(u32 num_rmid, struct rdt_hw_domain *hw_dom)
        return 0;
 }
 
+static int get_domain_id_from_scope(int cpu, enum resctrl_scope scope)
+{
+       switch (scope) {
+       case RESCTRL_L2_CACHE:
+       case RESCTRL_L3_CACHE:
+               return get_cpu_cacheinfo_id(cpu, scope);
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
 /*
  * domain_add_cpu - Add a cpu to a resource's domain list.
  *
@@ -499,7 +509,7 @@ static int arch_domain_mbm_alloc(u32 num_rmid, struct rdt_hw_domain *hw_dom)
  */
 static void domain_add_cpu(int cpu, struct rdt_resource *r)
 {
-       int id = get_cpu_cacheinfo_id(cpu, r->cache_level);
+       int id = get_domain_id_from_scope(cpu, r->scope);
        struct list_head *add_pos = NULL;
        struct rdt_hw_domain *hw_dom;
        struct rdt_domain *d;
@@ -507,12 +517,14 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
 
        lockdep_assert_held(&domain_list_lock);
 
-       d = rdt_find_domain(r, id, &add_pos);
-       if (IS_ERR(d)) {
-               pr_warn("Couldn't find cache id for CPU %d\n", cpu);
+       if (id < 0) {
+               pr_warn_once("Can't find domain id for CPU:%d scope:%d for resource %s\n",
+                            cpu, r->scope, r->name);
                return;
        }
 
+       d = rdt_find_domain(r, id, &add_pos);
+
        if (d) {
                cpumask_set_cpu(cpu, &d->cpu_mask);
                if (r->cache.arch_has_per_cpu_cfg)
@@ -552,15 +564,21 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
 
 static void domain_remove_cpu(int cpu, struct rdt_resource *r)
 {
-       int id = get_cpu_cacheinfo_id(cpu, r->cache_level);
+       int id = get_domain_id_from_scope(cpu, r->scope);
        struct rdt_hw_domain *hw_dom;
        struct rdt_domain *d;
 
        lockdep_assert_held(&domain_list_lock);
 
+       if (id < 0) {
+               pr_warn_once("Can't find domain id for CPU:%d scope:%d for resource %s\n",
+                            cpu, r->scope, r->name);
+               return;
+       }
+
        d = rdt_find_domain(r, id, NULL);
-       if (IS_ERR_OR_NULL(d)) {
-               pr_warn("Couldn't find cache id for CPU %d\n", cpu);
+       if (!d) {
+               pr_warn("Couldn't find domain with id=%d for CPU %d\n", id, cpu);
                return;
        }
        hw_dom = resctrl_to_arch_dom(d);
index b7291f60399c0e759e8bf618a2966fa565ae106b..2bf021d42500740b294ccc7eca7f2d78d2fa8476 100644 (file)
@@ -577,7 +577,7 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg)
 
        r = &rdt_resources_all[resid].r_resctrl;
        d = rdt_find_domain(r, domid, NULL);
-       if (IS_ERR_OR_NULL(d)) {
+       if (!d) {
                ret = -ENOENT;
                goto out;
        }
index 1bbfd3c1e3002982c64e9ee711b8c960af6c6025..201011f0ed0b9ab41c605bc3f1cc7b74e234dfc1 100644 (file)
@@ -292,9 +292,13 @@ static void pseudo_lock_region_clear(struct pseudo_lock_region *plr)
  */
 static int pseudo_lock_region_init(struct pseudo_lock_region *plr)
 {
+       enum resctrl_scope scope = plr->s->res->scope;
        struct cacheinfo *ci;
        int ret;
 
+       if (WARN_ON_ONCE(scope != RESCTRL_L2_CACHE && scope != RESCTRL_L3_CACHE))
+               return -ENODEV;
+
        /* Pick the first cpu we find that is associated with the cache. */
        plr->cpu = cpumask_first(&plr->d->cpu_mask);
 
@@ -305,7 +309,7 @@ static int pseudo_lock_region_init(struct pseudo_lock_region *plr)
                goto out_region;
        }
 
-       ci = get_cpu_cacheinfo_level(plr->cpu, plr->s->res->cache_level);
+       ci = get_cpu_cacheinfo_level(plr->cpu, scope);
        if (ci) {
                plr->line_size = ci->coherency_line_size;
                plr->size = rdtgroup_cbm_to_size(plr->s->res, plr->d, plr->cbm);
index cb68a121dabb6b0131ca7593687e4922f58f531f..50f5876a3020e24c37a42b6148b75736fdf54181 100644 (file)
@@ -1454,8 +1454,11 @@ unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r,
        struct cacheinfo *ci;
        int num_b;
 
+       if (WARN_ON_ONCE(r->scope != RESCTRL_L2_CACHE && r->scope != RESCTRL_L3_CACHE))
+               return size;
+
        num_b = bitmap_weight(&cbm, r->cache.cbm_len);
-       ci = get_cpu_cacheinfo_level(cpumask_any(&d->cpu_mask), r->cache_level);
+       ci = get_cpu_cacheinfo_level(cpumask_any(&d->cpu_mask), r->scope);
        if (ci)
                size = ci->size / r->cache.cbm_len * num_b;
 
index a365f67131eceffe2768fe06af778d2e2360ff92..ed693bfe474d576f98dda65c344e81cae8d8dec7 100644 (file)
@@ -150,13 +150,18 @@ struct resctrl_membw {
 struct rdt_parse_data;
 struct resctrl_schema;
 
+enum resctrl_scope {
+       RESCTRL_L2_CACHE = 2,
+       RESCTRL_L3_CACHE = 3,
+};
+
 /**
  * struct rdt_resource - attributes of a resctrl resource
  * @rid:               The index of the resource
  * @alloc_capable:     Is allocation available on this machine
  * @mon_capable:       Is monitor feature available on this machine
  * @num_rmid:          Number of RMIDs available
- * @cache_level:       Which cache level defines scope of this resource
+ * @scope:             Scope of this resource
  * @cache:             Cache allocation related data
  * @membw:             If the component has bandwidth controls, their properties.
  * @domains:           RCU list of all domains for this resource
@@ -174,7 +179,7 @@ struct rdt_resource {
        bool                    alloc_capable;
        bool                    mon_capable;
        int                     num_rmid;
-       int                     cache_level;
+       enum resctrl_scope      scope;
        struct resctrl_cache    cache;
        struct resctrl_membw    membw;
        struct list_head        domains;