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 count_of_bits;
20 static char cbm_mask[256];
21 static unsigned long long_mask;
22 static unsigned long cache_size;
23
cmt_setup(int num,...)24 static int cmt_setup(int num, ...)
25 {
26 struct resctrl_val_param *p;
27 va_list param;
28
29 va_start(param, num);
30 p = va_arg(param, struct resctrl_val_param *);
31 va_end(param);
32
33 /* Run NUM_OF_RUNS times */
34 if (p->num_of_runs >= NUM_OF_RUNS)
35 return -1;
36
37 p->num_of_runs++;
38
39 return 0;
40 }
41
check_results(struct resctrl_val_param * param,int no_of_bits)42 static int check_results(struct resctrl_val_param *param, int no_of_bits)
43 {
44 char *token_array[8], temp[512];
45 unsigned long sum_llc_occu_resc = 0;
46 int runs = 0;
47 FILE *fp;
48
49 ksft_print_msg("Checking for pass/fail\n");
50 fp = fopen(param->filename, "r");
51 if (!fp) {
52 perror("# Error in opening file\n");
53
54 return errno;
55 }
56
57 while (fgets(temp, sizeof(temp), fp)) {
58 char *token = strtok(temp, ":\t");
59 int fields = 0;
60
61 while (token) {
62 token_array[fields++] = token;
63 token = strtok(NULL, ":\t");
64 }
65
66 /* Field 3 is llc occ resc value */
67 if (runs > 0)
68 sum_llc_occu_resc += strtoul(token_array[3], NULL, 0);
69 runs++;
70 }
71 fclose(fp);
72
73 return show_cache_info(sum_llc_occu_resc, no_of_bits, param->span,
74 MAX_DIFF, MAX_DIFF_PERCENT, NUM_OF_RUNS,
75 true, true);
76 }
77
cmt_test_cleanup(void)78 void cmt_test_cleanup(void)
79 {
80 remove(RESULT_FILE_NAME);
81 }
82
cmt_resctrl_val(int cpu_no,int n,char ** benchmark_cmd)83 int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
84 {
85 int ret, mum_resctrlfs;
86
87 cache_size = 0;
88 mum_resctrlfs = 1;
89
90 ret = remount_resctrlfs(mum_resctrlfs);
91 if (ret)
92 return ret;
93
94 if (!validate_resctrl_feature_request(CMT_STR))
95 return -1;
96
97 ret = get_cbm_mask("L3", cbm_mask);
98 if (ret)
99 return ret;
100
101 long_mask = strtoul(cbm_mask, NULL, 16);
102
103 ret = get_cache_size(cpu_no, "L3", &cache_size);
104 if (ret)
105 return ret;
106 ksft_print_msg("Cache size :%lu\n", cache_size);
107
108 count_of_bits = count_bits(long_mask);
109
110 if (n < 1 || n > count_of_bits) {
111 ksft_print_msg("Invalid input value for numbr_of_bits n!\n");
112 ksft_print_msg("Please enter value in range 1 to %d\n", count_of_bits);
113 return -1;
114 }
115
116 struct resctrl_val_param param = {
117 .resctrl_val = CMT_STR,
118 .ctrlgrp = "c1",
119 .mongrp = "m1",
120 .cpu_no = cpu_no,
121 .mum_resctrlfs = 0,
122 .filename = RESULT_FILE_NAME,
123 .mask = ~(long_mask << n) & long_mask,
124 .span = cache_size * n / count_of_bits,
125 .num_of_runs = 0,
126 .setup = cmt_setup,
127 };
128
129 if (strcmp(benchmark_cmd[0], "fill_buf") == 0)
130 sprintf(benchmark_cmd[1], "%lu", param.span);
131
132 remove(RESULT_FILE_NAME);
133
134 ret = resctrl_val(benchmark_cmd, ¶m);
135 if (ret)
136 return ret;
137
138 ret = check_results(¶m, n);
139 if (ret)
140 return ret;
141
142 cmt_test_cleanup();
143
144 return 0;
145 }
146