162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Cache Monitoring Technology (CMT) test 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2018 Intel Corporation 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Authors: 862306a36Sopenharmony_ci * Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>, 962306a36Sopenharmony_ci * Fenghua Yu <fenghua.yu@intel.com> 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci#include "resctrl.h" 1262306a36Sopenharmony_ci#include <unistd.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define RESULT_FILE_NAME "result_cmt" 1562306a36Sopenharmony_ci#define NUM_OF_RUNS 5 1662306a36Sopenharmony_ci#define MAX_DIFF 2000000 1762306a36Sopenharmony_ci#define MAX_DIFF_PERCENT 15 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistatic int cmt_setup(struct resctrl_val_param *p) 2062306a36Sopenharmony_ci{ 2162306a36Sopenharmony_ci /* Run NUM_OF_RUNS times */ 2262306a36Sopenharmony_ci if (p->num_of_runs >= NUM_OF_RUNS) 2362306a36Sopenharmony_ci return END_OF_TESTS; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci p->num_of_runs++; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci return 0; 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistatic int check_results(struct resctrl_val_param *param, size_t span, int no_of_bits) 3162306a36Sopenharmony_ci{ 3262306a36Sopenharmony_ci char *token_array[8], temp[512]; 3362306a36Sopenharmony_ci unsigned long sum_llc_occu_resc = 0; 3462306a36Sopenharmony_ci int runs = 0; 3562306a36Sopenharmony_ci FILE *fp; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci ksft_print_msg("Checking for pass/fail\n"); 3862306a36Sopenharmony_ci fp = fopen(param->filename, "r"); 3962306a36Sopenharmony_ci if (!fp) { 4062306a36Sopenharmony_ci perror("# Error in opening file\n"); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci return errno; 4362306a36Sopenharmony_ci } 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci while (fgets(temp, sizeof(temp), fp)) { 4662306a36Sopenharmony_ci char *token = strtok(temp, ":\t"); 4762306a36Sopenharmony_ci int fields = 0; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci while (token) { 5062306a36Sopenharmony_ci token_array[fields++] = token; 5162306a36Sopenharmony_ci token = strtok(NULL, ":\t"); 5262306a36Sopenharmony_ci } 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci /* Field 3 is llc occ resc value */ 5562306a36Sopenharmony_ci if (runs > 0) 5662306a36Sopenharmony_ci sum_llc_occu_resc += strtoul(token_array[3], NULL, 0); 5762306a36Sopenharmony_ci runs++; 5862306a36Sopenharmony_ci } 5962306a36Sopenharmony_ci fclose(fp); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci return show_cache_info(sum_llc_occu_resc, no_of_bits, span, 6262306a36Sopenharmony_ci MAX_DIFF, MAX_DIFF_PERCENT, runs - 1, 6362306a36Sopenharmony_ci true, true); 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_civoid cmt_test_cleanup(void) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci remove(RESULT_FILE_NAME); 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ciint cmt_resctrl_val(int cpu_no, int n, const char * const *benchmark_cmd) 7262306a36Sopenharmony_ci{ 7362306a36Sopenharmony_ci const char * const *cmd = benchmark_cmd; 7462306a36Sopenharmony_ci const char *new_cmd[BENCHMARK_ARGS]; 7562306a36Sopenharmony_ci unsigned long cache_size = 0; 7662306a36Sopenharmony_ci unsigned long long_mask; 7762306a36Sopenharmony_ci char *span_str = NULL; 7862306a36Sopenharmony_ci char cbm_mask[256]; 7962306a36Sopenharmony_ci int count_of_bits; 8062306a36Sopenharmony_ci size_t span; 8162306a36Sopenharmony_ci int ret, i; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci ret = get_cbm_mask("L3", cbm_mask); 8462306a36Sopenharmony_ci if (ret) 8562306a36Sopenharmony_ci return ret; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci long_mask = strtoul(cbm_mask, NULL, 16); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci ret = get_cache_size(cpu_no, "L3", &cache_size); 9062306a36Sopenharmony_ci if (ret) 9162306a36Sopenharmony_ci return ret; 9262306a36Sopenharmony_ci ksft_print_msg("Cache size :%lu\n", cache_size); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci count_of_bits = count_bits(long_mask); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci if (n < 1 || n > count_of_bits) { 9762306a36Sopenharmony_ci ksft_print_msg("Invalid input value for numbr_of_bits n!\n"); 9862306a36Sopenharmony_ci ksft_print_msg("Please enter value in range 1 to %d\n", count_of_bits); 9962306a36Sopenharmony_ci return -1; 10062306a36Sopenharmony_ci } 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci struct resctrl_val_param param = { 10362306a36Sopenharmony_ci .resctrl_val = CMT_STR, 10462306a36Sopenharmony_ci .ctrlgrp = "c1", 10562306a36Sopenharmony_ci .mongrp = "m1", 10662306a36Sopenharmony_ci .cpu_no = cpu_no, 10762306a36Sopenharmony_ci .filename = RESULT_FILE_NAME, 10862306a36Sopenharmony_ci .mask = ~(long_mask << n) & long_mask, 10962306a36Sopenharmony_ci .num_of_runs = 0, 11062306a36Sopenharmony_ci .setup = cmt_setup, 11162306a36Sopenharmony_ci }; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci span = cache_size * n / count_of_bits; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci if (strcmp(cmd[0], "fill_buf") == 0) { 11662306a36Sopenharmony_ci /* Duplicate the command to be able to replace span in it */ 11762306a36Sopenharmony_ci for (i = 0; benchmark_cmd[i]; i++) 11862306a36Sopenharmony_ci new_cmd[i] = benchmark_cmd[i]; 11962306a36Sopenharmony_ci new_cmd[i] = NULL; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci ret = asprintf(&span_str, "%zu", span); 12262306a36Sopenharmony_ci if (ret < 0) 12362306a36Sopenharmony_ci return -1; 12462306a36Sopenharmony_ci new_cmd[1] = span_str; 12562306a36Sopenharmony_ci cmd = new_cmd; 12662306a36Sopenharmony_ci } 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci remove(RESULT_FILE_NAME); 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci ret = resctrl_val(cmd, ¶m); 13162306a36Sopenharmony_ci if (ret) 13262306a36Sopenharmony_ci goto out; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci ret = check_results(¶m, span, n); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ciout: 13762306a36Sopenharmony_ci cmt_test_cleanup(); 13862306a36Sopenharmony_ci free(span_str); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci return ret; 14162306a36Sopenharmony_ci} 142