Currently, the resctrl_val.c is tightly coupled with X86's uncore IMC
counter, which is inapplicable on other platforms like ARM.

This commit refactor resctrl_val.c by introducing a structure to support
vendor-specific PMU, event and scale. This allows the test to dynamically
select the PMU based on the detected CPU vendor, paving the way for
supporting multiple vendors and architectures.

Signed-off-by: Yifan Wu <[email protected]>
---
 tools/testing/selftests/resctrl/resctrl_val.c | 48 +++++++++++++++----
 1 file changed, 40 insertions(+), 8 deletions(-)

diff --git a/tools/testing/selftests/resctrl/resctrl_val.c 
b/tools/testing/selftests/resctrl/resctrl_val.c
index 85ac96c7cb8f..b0570c615aac 100644
--- a/tools/testing/selftests/resctrl/resctrl_val.c
+++ b/tools/testing/selftests/resctrl/resctrl_val.c
@@ -10,10 +10,7 @@
  */
 #include "resctrl.h"
 
-#define UNCORE_IMC             "uncore_imc"
-#define READ_FILE_NAME         "events/cas_count_read"
 #define DYN_PMU_PATH           "/sys/bus/event_source/devices"
-#define SCALE                  0.00006103515625
 #define MAX_IMCS               20
 #define MAX_TOKENS             5
 
@@ -36,10 +33,30 @@ struct imc_counter_config {
        int fd;
 };
 
+struct membw_read_config {
+       int vendor_id;
+       const char *name;
+       const char *event;
+       double scale;
+};
+
+static struct membw_read_config membw_read_configs[] = {
+       {
+               .vendor_id = ARCH_INTEL | ARCH_AMD | ARCH_HYGON,
+               .name = "uncore_imc",
+               .event = "events/cas_count_read",
+               .scale = 64.0 / MB,
+       },
+       {
+               .vendor_id = NULL
+       }
+};
+
 static char mbm_total_path[1024];
 static int imcs;
 static struct imc_counter_config imc_counters_config[MAX_IMCS];
 static const struct resctrl_test *current_test;
+static struct membw_read_config *current_config;
 
 static void read_mem_bw_initialize_perf_event_attr(int i)
 {
@@ -133,7 +150,7 @@ static int read_from_imc_dir(char *imc_dir, int count)
        fclose(fp);
 
        /* Get read config */
-       sprintf(imc_counter_cfg, "%s%s", imc_dir, READ_FILE_NAME);
+       sprintf(imc_counter_cfg, "%s%s", imc_dir, current_config->event);
        fp = fopen(imc_counter_cfg, "r");
        if (!fp) {
                ksft_perror("Failed to open iMC config file");
@@ -176,18 +193,18 @@ static int num_of_imcs(void)
        dp = opendir(DYN_PMU_PATH);
        if (dp) {
                while ((ep = readdir(dp))) {
-                       temp = strstr(ep->d_name, UNCORE_IMC);
+                       temp = strstr(ep->d_name, current_config->name);
                        if (!temp)
                                continue;
 
                        /*
                         * imc counters are named as "uncore_imc_<n>", hence
                         * increment the pointer to point to <n>. Note that
-                        * sizeof(UNCORE_IMC) would count for null character as
+                        * sizeof("uncore_imc") would count for null character 
as
                         * well and hence the last underscore character in
                         * uncore_imc'_' need not be counted.
                         */
-                       temp = temp + sizeof(UNCORE_IMC);
+                       temp = temp + strlen(current_config->name) + 1;
 
                        /*
                         * Some directories under "DYN_PMU_PATH" could have
@@ -328,7 +345,7 @@ static int get_read_mem_bw_imc(float *bw_imc)
                        of_mul_read = (float)r_time_enabled /
                                        (float)r_time_running;
 
-               reads += r->return_value.value * of_mul_read * SCALE;
+               reads += r->return_value.value * of_mul_read * 
current_config->scale;
        }
 
        *bw_imc = reads;
@@ -469,6 +486,21 @@ static int print_results_bw(char *filename, pid_t bm_pid, 
float bw_imc,
        return 0;
 }
 
+int initialize_measure_read_mem_bw(const struct resctrl_val_param *param, int 
domain_id)
+{
+       unsigned int vendor = get_vendor();
+
+       for (current_config = membw_read_configs;
+               !(current_config->vendor_id & vendor);
+               current_config++)
+               continue;
+
+       if (!current_config->vendor_id)
+               return -1;
+
+       return 0;
+}
+
 /*
  * measure_read_mem_bw - Measures read memory bandwidth numbers while 
benchmark runs
  * @uparams:           User supplied parameters
-- 
2.33.0


Reply via email to