]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86/resctrl: Use schema type to determine how to parse schema values
authorJames Morse <james.morse@arm.com>
Tue, 11 Mar 2025 18:36:49 +0000 (18:36 +0000)
committerBorislav Petkov (AMD) <bp@alien8.de>
Wed, 12 Mar 2025 11:22:30 +0000 (12:22 +0100)
Resctrl's architecture code gets to specify a function pointer that is used
when parsing schema entries. This is expected to be one of two helpers from
the filesystem code.

Setting this function pointer allows the architecture code to change the ABI
resctrl presents to user-space, and forces resctrl to expose these helpers.

Instead, add a schema format enum to choose which schema parser to use. This
allows the helpers to be made static and the structs used for passing
arguments moved out of shared headers.

Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
Reviewed-by: Babu Moger <babu.moger@amd.com>
Tested-by: Carl Worth <carl@os.amperecomputing.com> # arm64
Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Tested-by: Peter Newman <peternewman@google.com>
Tested-by: Amit Singh Tomar <amitsinght@marvell.com> # arm64
Tested-by: Shanker Donthineni <sdonthineni@nvidia.com> # arm64
Tested-by: Babu Moger <babu.moger@amd.com>
Link: https://lore.kernel.org/r/20250311183715.16445-5-james.morse@arm.com
arch/x86/kernel/cpu/resctrl/core.c
arch/x86/kernel/cpu/resctrl/ctrlmondata.c
arch/x86/kernel/cpu/resctrl/internal.h
include/linux/resctrl.h

index 8ef2e449b4650acb48aad3b8f6482a88e4610ae9..e9fe129a02f84eeeacd73535afe9d217a9fae37b 100644 (file)
@@ -72,7 +72,7 @@ struct rdt_hw_resource rdt_resources_all[RDT_NUM_RESOURCES] = {
                        .mon_scope              = RESCTRL_L3_CACHE,
                        .ctrl_domains           = ctrl_domain_init(RDT_RESOURCE_L3),
                        .mon_domains            = mon_domain_init(RDT_RESOURCE_L3),
-                       .parse_ctrlval          = parse_cbm,
+                       .schema_fmt             = RESCTRL_SCHEMA_BITMAP,
                        .format_str             = "%d=%0*x",
                },
                .msr_base               = MSR_IA32_L3_CBM_BASE,
@@ -85,7 +85,7 @@ struct rdt_hw_resource rdt_resources_all[RDT_NUM_RESOURCES] = {
                        .name                   = "L2",
                        .ctrl_scope             = RESCTRL_L2_CACHE,
                        .ctrl_domains           = ctrl_domain_init(RDT_RESOURCE_L2),
-                       .parse_ctrlval          = parse_cbm,
+                       .schema_fmt             = RESCTRL_SCHEMA_BITMAP,
                        .format_str             = "%d=%0*x",
                },
                .msr_base               = MSR_IA32_L2_CBM_BASE,
@@ -98,7 +98,7 @@ struct rdt_hw_resource rdt_resources_all[RDT_NUM_RESOURCES] = {
                        .name                   = "MB",
                        .ctrl_scope             = RESCTRL_L3_CACHE,
                        .ctrl_domains           = ctrl_domain_init(RDT_RESOURCE_MBA),
-                       .parse_ctrlval          = parse_bw,
+                       .schema_fmt             = RESCTRL_SCHEMA_RANGE,
                        .format_str             = "%d=%*u",
                },
        },
@@ -109,7 +109,7 @@ struct rdt_hw_resource rdt_resources_all[RDT_NUM_RESOURCES] = {
                        .name                   = "SMBA",
                        .ctrl_scope             = RESCTRL_L3_CACHE,
                        .ctrl_domains           = ctrl_domain_init(RDT_RESOURCE_SMBA),
-                       .parse_ctrlval          = parse_bw,
+                       .schema_fmt             = RESCTRL_SCHEMA_RANGE,
                        .format_str             = "%d=%*u",
                },
        },
index 4af27ef5a8a19f8bc74d5c9ea5968b563c70b695..f4334f437ffc7d0ceab01f7ba522ba19b51a4028 100644 (file)
 
 #include "internal.h"
 
+struct rdt_parse_data {
+       struct rdtgroup         *rdtgrp;
+       char                    *buf;
+};
+
+typedef int (ctrlval_parser_t)(struct rdt_parse_data *data,
+                              struct resctrl_schema *s,
+                              struct rdt_ctrl_domain *d);
+
 /*
  * Check whether MBA bandwidth percentage value is correct. The value is
  * checked against the minimum and max bandwidth values specified by the
@@ -64,8 +73,8 @@ static bool bw_validate(char *buf, u32 *data, struct rdt_resource *r)
        return true;
 }
 
-int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
-            struct rdt_ctrl_domain *d)
+static int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
+                   struct rdt_ctrl_domain *d)
 {
        struct resctrl_staged_config *cfg;
        u32 closid = data->rdtgrp->closid;
@@ -143,8 +152,8 @@ static bool cbm_validate(char *buf, u32 *data, struct rdt_resource *r)
  * Read one cache bit mask (hex). Check that it is valid for the current
  * resource type.
  */
-int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s,
-             struct rdt_ctrl_domain *d)
+static int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s,
+                    struct rdt_ctrl_domain *d)
 {
        struct rdtgroup *rdtgrp = data->rdtgrp;
        struct resctrl_staged_config *cfg;
@@ -210,6 +219,7 @@ static int parse_line(char *line, struct resctrl_schema *s,
                      struct rdtgroup *rdtgrp)
 {
        enum resctrl_conf_type t = s->conf_type;
+       ctrlval_parser_t *parse_ctrlval = NULL;
        struct resctrl_staged_config *cfg;
        struct rdt_resource *r = s->res;
        struct rdt_parse_data data;
@@ -220,6 +230,18 @@ static int parse_line(char *line, struct resctrl_schema *s,
        /* Walking r->domains, ensure it can't race with cpuhp */
        lockdep_assert_cpus_held();
 
+       switch (r->schema_fmt) {
+       case RESCTRL_SCHEMA_BITMAP:
+               parse_ctrlval = &parse_cbm;
+               break;
+       case RESCTRL_SCHEMA_RANGE:
+               parse_ctrlval = &parse_bw;
+               break;
+       }
+
+       if (WARN_ON_ONCE(!parse_ctrlval))
+               return -EINVAL;
+
        if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP &&
            (r->rid == RDT_RESOURCE_MBA || r->rid == RDT_RESOURCE_SMBA)) {
                rdt_last_cmd_puts("Cannot pseudo-lock MBA resource\n");
@@ -240,7 +262,7 @@ next:
                if (d->hdr.id == dom_id) {
                        data.buf = dom;
                        data.rdtgrp = rdtgrp;
-                       if (r->parse_ctrlval(&data, s, d))
+                       if (parse_ctrlval(&data, s, d))
                                return -EINVAL;
                        if (rdtgrp->mode ==  RDT_MODE_PSEUDO_LOCKSETUP) {
                                cfg = &d->staged_config[t];
index 75252a7e1ebc6e84bfe27a2e88a63a741759a110..b5543bd506c3b9d91af1d08f87f49a1f5a3b04ad 100644 (file)
@@ -459,11 +459,6 @@ static inline bool is_mbm_event(int e)
                e <= QOS_L3_MBM_LOCAL_EVENT_ID);
 }
 
-struct rdt_parse_data {
-       struct rdtgroup         *rdtgrp;
-       char                    *buf;
-};
-
 /**
  * struct rdt_hw_resource - arch private attributes of a resctrl resource
  * @r_resctrl:         Attributes of the resource used directly by resctrl.
@@ -500,11 +495,6 @@ static inline struct rdt_hw_resource *resctrl_to_arch_res(struct rdt_resource *r
        return container_of(r, struct rdt_hw_resource, r_resctrl);
 }
 
-int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s,
-             struct rdt_ctrl_domain *d);
-int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
-            struct rdt_ctrl_domain *d);
-
 extern struct mutex rdtgroup_mutex;
 
 extern struct rdt_hw_resource rdt_resources_all[];
index 496ddcaa4ecf369c853cfb2059f3f8ff1ecf8f50..3e1a41356b2a79876386b28f0effc67024ed7c85 100644 (file)
@@ -183,7 +183,6 @@ struct resctrl_membw {
        u32                             *mb_map;
 };
 
-struct rdt_parse_data;
 struct resctrl_schema;
 
 enum resctrl_scope {
@@ -192,6 +191,16 @@ enum resctrl_scope {
        RESCTRL_L3_NODE,
 };
 
+/**
+ * enum resctrl_schema_fmt - The format user-space provides for a schema.
+ * @RESCTRL_SCHEMA_BITMAP:     The schema is a bitmap in hex.
+ * @RESCTRL_SCHEMA_RANGE:      The schema is a decimal number.
+ */
+enum resctrl_schema_fmt {
+       RESCTRL_SCHEMA_BITMAP,
+       RESCTRL_SCHEMA_RANGE,
+};
+
 /**
  * struct rdt_resource - attributes of a resctrl resource
  * @rid:               The index of the resource
@@ -208,7 +217,7 @@ enum resctrl_scope {
  * @data_width:                Character width of data when displaying
  * @default_ctrl:      Specifies default cache cbm or memory B/W percent.
  * @format_str:                Per resource format string to show domain value
- * @parse_ctrlval:     Per resource function pointer to parse control values
+ * @schema_fmt:                Which format string and parser is used for this schema.
  * @evt_list:          List of monitoring events
  * @cdp_capable:       Is the CDP feature available on this resource
  */
@@ -227,9 +236,7 @@ struct rdt_resource {
        int                     data_width;
        u32                     default_ctrl;
        const char              *format_str;
-       int                     (*parse_ctrlval)(struct rdt_parse_data *data,
-                                                struct resctrl_schema *s,
-                                                struct rdt_ctrl_domain *d);
+       enum resctrl_schema_fmt schema_fmt;
        struct list_head        evt_list;
        bool                    cdp_capable;
 };