1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Cache Monitoring Technology (CMT) test 4 * 5 * Copyright (C) 2018 Intel Corporation 6 * 7 * Authors: 8 * Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>, 9 * Fenghua Yu <fenghua.yu@intel.com> 10 */ 11 #include "resctrl.h" 12 #include <unistd.h> 13 14 #define RESULT_FILE_NAME "result_cmt" 15 #define NUM_OF_RUNS 5 16 #define MAX_DIFF 2000000 17 #define MAX_DIFF_PERCENT 15 18 19 static int cmt_setup(struct resctrl_val_param *p) 20 { 21 /* Run NUM_OF_RUNS times */ 22 if (p->num_of_runs >= NUM_OF_RUNS) 23 return END_OF_TESTS; 24 25 p->num_of_runs++; 26 27 return 0; 28 } 29 30 static int check_results(struct resctrl_val_param *param, int no_of_bits) 31 { 32 char *token_array[8], temp[512]; 33 unsigned long sum_llc_occu_resc = 0; 34 int runs = 0; 35 FILE *fp; 36 37 ksft_print_msg("Checking for pass/fail\n"); 38 fp = fopen(param->filename, "r"); 39 if (!fp) { 40 perror("# Error in opening file\n"); 41 42 return errno; 43 } 44 45 while (fgets(temp, sizeof(temp), fp)) { 46 char *token = strtok(temp, ":\t"); 47 int fields = 0; 48 49 while (token) { 50 token_array[fields++] = token; 51 token = strtok(NULL, ":\t"); 52 } 53 54 /* Field 3 is llc occ resc value */ 55 if (runs > 0) 56 sum_llc_occu_resc += strtoul(token_array[3], NULL, 0); 57 runs++; 58 } 59 fclose(fp); 60 61 return show_cache_info(sum_llc_occu_resc, no_of_bits, param->span, 62 MAX_DIFF, MAX_DIFF_PERCENT, runs - 1, 63 true, true); 64 } 65 66 void cmt_test_cleanup(void) 67 { 68 remove(RESULT_FILE_NAME); 69 } 70 71 int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) 72 { 73 unsigned long cache_size = 0; 74 unsigned long long_mask; 75 char cbm_mask[256]; 76 int count_of_bits; 77 int ret; 78 79 if (!validate_resctrl_feature_request(CMT_STR)) 80 return -1; 81 82 ret = get_cbm_mask("L3", cbm_mask); 83 if (ret) 84 return ret; 85 86 long_mask = strtoul(cbm_mask, NULL, 16); 87 88 ret = get_cache_size(cpu_no, "L3", &cache_size); 89 if (ret) 90 return ret; 91 ksft_print_msg("Cache size :%lu\n", cache_size); 92 93 count_of_bits = count_bits(long_mask); 94 95 if (n < 1 || n > count_of_bits) { 96 ksft_print_msg("Invalid input value for numbr_of_bits n!\n"); 97 ksft_print_msg("Please enter value in range 1 to %d\n", count_of_bits); 98 return -1; 99 } 100 101 struct resctrl_val_param param = { 102 .resctrl_val = CMT_STR, 103 .ctrlgrp = "c1", 104 .mongrp = "m1", 105 .cpu_no = cpu_no, 106 .filename = RESULT_FILE_NAME, 107 .mask = ~(long_mask << n) & long_mask, 108 .span = cache_size * n / count_of_bits, 109 .num_of_runs = 0, 110 .setup = cmt_setup, 111 }; 112 113 if (strcmp(benchmark_cmd[0], "fill_buf") == 0) 114 sprintf(benchmark_cmd[1], "%zu", param.span); 115 116 remove(RESULT_FILE_NAME); 117 118 ret = resctrl_val(benchmark_cmd, ¶m); 119 if (ret) 120 goto out; 121 122 ret = check_results(¶m, n); 123 124 out: 125 cmt_test_cleanup(); 126 127 return ret; 128 } 129