• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 END_OF_TESTS;
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 	ret = get_cbm_mask("L3", cbm_mask);
95 	if (ret)
96 		return ret;
97 
98 	long_mask = strtoul(cbm_mask, NULL, 16);
99 
100 	ret = get_cache_size(cpu_no, "L3", &cache_size);
101 	if (ret)
102 		return ret;
103 	ksft_print_msg("Cache size :%lu\n", cache_size);
104 
105 	count_of_bits = count_bits(long_mask);
106 
107 	if (n < 1 || n > count_of_bits) {
108 		ksft_print_msg("Invalid input value for numbr_of_bits n!\n");
109 		ksft_print_msg("Please enter value in range 1 to %d\n", count_of_bits);
110 		return -1;
111 	}
112 
113 	struct resctrl_val_param param = {
114 		.resctrl_val	= CMT_STR,
115 		.ctrlgrp	= "c1",
116 		.mongrp		= "m1",
117 		.cpu_no		= cpu_no,
118 		.mum_resctrlfs	= 0,
119 		.filename	= RESULT_FILE_NAME,
120 		.mask		= ~(long_mask << n) & long_mask,
121 		.span		= cache_size * n / count_of_bits,
122 		.num_of_runs	= 0,
123 		.setup		= cmt_setup,
124 	};
125 
126 	if (strcmp(benchmark_cmd[0], "fill_buf") == 0)
127 		sprintf(benchmark_cmd[1], "%lu", param.span);
128 
129 	remove(RESULT_FILE_NAME);
130 
131 	ret = resctrl_val(benchmark_cmd, &param);
132 	if (ret)
133 		return ret;
134 
135 	ret = check_results(&param, n);
136 	if (ret)
137 		return ret;
138 
139 	cmt_test_cleanup();
140 
141 	return 0;
142 }
143