12f320911SFenghua Yu // SPDX-License-Identifier: GPL-2.0
22f320911SFenghua Yu /*
32f320911SFenghua Yu  * Cache Monitoring Technology (CMT) test
42f320911SFenghua Yu  *
52f320911SFenghua Yu  * Copyright (C) 2018 Intel Corporation
62f320911SFenghua Yu  *
72f320911SFenghua Yu  * Authors:
82f320911SFenghua Yu  *    Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>,
92f320911SFenghua Yu  *    Fenghua Yu <fenghua.yu@intel.com>
102f320911SFenghua Yu  */
112f320911SFenghua Yu #include "resctrl.h"
122f320911SFenghua Yu #include <unistd.h>
132f320911SFenghua Yu 
142f320911SFenghua Yu #define RESULT_FILE_NAME	"result_cmt"
152f320911SFenghua Yu #define NUM_OF_RUNS		5
162f320911SFenghua Yu #define MAX_DIFF		2000000
172f320911SFenghua Yu #define MAX_DIFF_PERCENT	15
182f320911SFenghua Yu 
cmt_setup(struct resctrl_val_param * p)198ee592a6SIlpo Järvinen static int cmt_setup(struct resctrl_val_param *p)
202f320911SFenghua Yu {
212f320911SFenghua Yu 	/* Run NUM_OF_RUNS times */
222f320911SFenghua Yu 	if (p->num_of_runs >= NUM_OF_RUNS)
23fa10366cSIlpo Järvinen 		return END_OF_TESTS;
242f320911SFenghua Yu 
252f320911SFenghua Yu 	p->num_of_runs++;
262f320911SFenghua Yu 
272f320911SFenghua Yu 	return 0;
282f320911SFenghua Yu }
292f320911SFenghua Yu 
check_results(struct resctrl_val_param * param,size_t span,int no_of_bits)30ef8454afSIlpo Järvinen static int check_results(struct resctrl_val_param *param, size_t span, int no_of_bits)
312f320911SFenghua Yu {
322f320911SFenghua Yu 	char *token_array[8], temp[512];
332f320911SFenghua Yu 	unsigned long sum_llc_occu_resc = 0;
342f320911SFenghua Yu 	int runs = 0;
352f320911SFenghua Yu 	FILE *fp;
362f320911SFenghua Yu 
37ca2f4214SFenghua Yu 	ksft_print_msg("Checking for pass/fail\n");
382f320911SFenghua Yu 	fp = fopen(param->filename, "r");
392f320911SFenghua Yu 	if (!fp) {
402f320911SFenghua Yu 		perror("# Error in opening file\n");
412f320911SFenghua Yu 
422f320911SFenghua Yu 		return errno;
432f320911SFenghua Yu 	}
442f320911SFenghua Yu 
452f320911SFenghua Yu 	while (fgets(temp, sizeof(temp), fp)) {
462f320911SFenghua Yu 		char *token = strtok(temp, ":\t");
472f320911SFenghua Yu 		int fields = 0;
482f320911SFenghua Yu 
492f320911SFenghua Yu 		while (token) {
502f320911SFenghua Yu 			token_array[fields++] = token;
512f320911SFenghua Yu 			token = strtok(NULL, ":\t");
522f320911SFenghua Yu 		}
532f320911SFenghua Yu 
542f320911SFenghua Yu 		/* Field 3 is llc occ resc value */
552f320911SFenghua Yu 		if (runs > 0)
562f320911SFenghua Yu 			sum_llc_occu_resc += strtoul(token_array[3], NULL, 0);
572f320911SFenghua Yu 		runs++;
582f320911SFenghua Yu 	}
592f320911SFenghua Yu 	fclose(fp);
602f320911SFenghua Yu 
61ef8454afSIlpo Järvinen 	return show_cache_info(sum_llc_occu_resc, no_of_bits, span,
623dad011bSIlpo Järvinen 			       MAX_DIFF, MAX_DIFF_PERCENT, runs - 1,
6303216ed7SFenghua Yu 			       true, true);
642f320911SFenghua Yu }
652f320911SFenghua Yu 
cmt_test_cleanup(void)662f320911SFenghua Yu void cmt_test_cleanup(void)
672f320911SFenghua Yu {
682f320911SFenghua Yu 	remove(RESULT_FILE_NAME);
692f320911SFenghua Yu }
702f320911SFenghua Yu 
cmt_resctrl_val(int cpu_no,int n,const char * const * benchmark_cmd)71*b1d34cb5SIlpo Järvinen int cmt_resctrl_val(int cpu_no, int n, const char * const *benchmark_cmd)
722f320911SFenghua Yu {
73*b1d34cb5SIlpo Järvinen 	const char * const *cmd = benchmark_cmd;
74*b1d34cb5SIlpo Järvinen 	const char *new_cmd[BENCHMARK_ARGS];
7585b73447SIlpo Järvinen 	unsigned long cache_size = 0;
7685b73447SIlpo Järvinen 	unsigned long long_mask;
77*b1d34cb5SIlpo Järvinen 	char *span_str = NULL;
7885b73447SIlpo Järvinen 	char cbm_mask[256];
7985b73447SIlpo Järvinen 	int count_of_bits;
80ef8454afSIlpo Järvinen 	size_t span;
81*b1d34cb5SIlpo Järvinen 	int ret, i;
822f320911SFenghua Yu 
832f320911SFenghua Yu 	ret = get_cbm_mask("L3", cbm_mask);
842f320911SFenghua Yu 	if (ret)
852f320911SFenghua Yu 		return ret;
862f320911SFenghua Yu 
872f320911SFenghua Yu 	long_mask = strtoul(cbm_mask, NULL, 16);
882f320911SFenghua Yu 
892f320911SFenghua Yu 	ret = get_cache_size(cpu_no, "L3", &cache_size);
902f320911SFenghua Yu 	if (ret)
912f320911SFenghua Yu 		return ret;
92ca2f4214SFenghua Yu 	ksft_print_msg("Cache size :%lu\n", cache_size);
932f320911SFenghua Yu 
942f320911SFenghua Yu 	count_of_bits = count_bits(long_mask);
952f320911SFenghua Yu 
962f320911SFenghua Yu 	if (n < 1 || n > count_of_bits) {
97ca2f4214SFenghua Yu 		ksft_print_msg("Invalid input value for numbr_of_bits n!\n");
98ca2f4214SFenghua Yu 		ksft_print_msg("Please enter value in range 1 to %d\n", count_of_bits);
992f320911SFenghua Yu 		return -1;
1002f320911SFenghua Yu 	}
1012f320911SFenghua Yu 
1022f320911SFenghua Yu 	struct resctrl_val_param param = {
1032f320911SFenghua Yu 		.resctrl_val	= CMT_STR,
1042f320911SFenghua Yu 		.ctrlgrp	= "c1",
1052f320911SFenghua Yu 		.mongrp		= "m1",
1062f320911SFenghua Yu 		.cpu_no		= cpu_no,
1072f320911SFenghua Yu 		.filename	= RESULT_FILE_NAME,
1082f320911SFenghua Yu 		.mask		= ~(long_mask << n) & long_mask,
1092f320911SFenghua Yu 		.num_of_runs	= 0,
1102f320911SFenghua Yu 		.setup		= cmt_setup,
1112f320911SFenghua Yu 	};
1122f320911SFenghua Yu 
113ef8454afSIlpo Järvinen 	span = cache_size * n / count_of_bits;
114*b1d34cb5SIlpo Järvinen 
115*b1d34cb5SIlpo Järvinen 	if (strcmp(cmd[0], "fill_buf") == 0) {
116*b1d34cb5SIlpo Järvinen 		/* Duplicate the command to be able to replace span in it */
117*b1d34cb5SIlpo Järvinen 		for (i = 0; benchmark_cmd[i]; i++)
118*b1d34cb5SIlpo Järvinen 			new_cmd[i] = benchmark_cmd[i];
119*b1d34cb5SIlpo Järvinen 		new_cmd[i] = NULL;
120*b1d34cb5SIlpo Järvinen 
121*b1d34cb5SIlpo Järvinen 		ret = asprintf(&span_str, "%zu", span);
122*b1d34cb5SIlpo Järvinen 		if (ret < 0)
123*b1d34cb5SIlpo Järvinen 			return -1;
124*b1d34cb5SIlpo Järvinen 		new_cmd[1] = span_str;
125*b1d34cb5SIlpo Järvinen 		cmd = new_cmd;
126*b1d34cb5SIlpo Järvinen 	}
1272f320911SFenghua Yu 
1282f320911SFenghua Yu 	remove(RESULT_FILE_NAME);
1292f320911SFenghua Yu 
130*b1d34cb5SIlpo Järvinen 	ret = resctrl_val(cmd, &param);
1312f320911SFenghua Yu 	if (ret)
13291db4fd9SShaopeng Tan 		goto out;
1332f320911SFenghua Yu 
134ef8454afSIlpo Järvinen 	ret = check_results(&param, span, n);
1352f320911SFenghua Yu 
13691db4fd9SShaopeng Tan out:
1372f320911SFenghua Yu 	cmt_test_cleanup();
138*b1d34cb5SIlpo Järvinen 	free(span_str);
1392f320911SFenghua Yu 
14091db4fd9SShaopeng Tan 	return ret;
1412f320911SFenghua Yu }
142