cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mbm_test.c (3073B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Memory Bandwidth Monitoring (MBM) 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
     13#define RESULT_FILE_NAME	"result_mbm"
     14#define MAX_DIFF_PERCENT	5
     15#define NUM_OF_RUNS		5
     16
     17static int
     18show_bw_info(unsigned long *bw_imc, unsigned long *bw_resc, int span)
     19{
     20	unsigned long avg_bw_imc = 0, avg_bw_resc = 0;
     21	unsigned long sum_bw_imc = 0, sum_bw_resc = 0;
     22	int runs, ret, avg_diff_per;
     23	float avg_diff = 0;
     24
     25	/*
     26	 * Discard the first value which is inaccurate due to monitoring setup
     27	 * transition phase.
     28	 */
     29	for (runs = 1; runs < NUM_OF_RUNS ; runs++) {
     30		sum_bw_imc += bw_imc[runs];
     31		sum_bw_resc += bw_resc[runs];
     32	}
     33
     34	avg_bw_imc = sum_bw_imc / 4;
     35	avg_bw_resc = sum_bw_resc / 4;
     36	avg_diff = (float)labs(avg_bw_resc - avg_bw_imc) / avg_bw_imc;
     37	avg_diff_per = (int)(avg_diff * 100);
     38
     39	ret = avg_diff_per > MAX_DIFF_PERCENT;
     40	ksft_print_msg("%s Check MBM diff within %d%%\n",
     41		       ret ? "Fail:" : "Pass:", MAX_DIFF_PERCENT);
     42	ksft_print_msg("avg_diff_per: %d%%\n", avg_diff_per);
     43	ksft_print_msg("Span (MB): %d\n", span);
     44	ksft_print_msg("avg_bw_imc: %lu\n", avg_bw_imc);
     45	ksft_print_msg("avg_bw_resc: %lu\n", avg_bw_resc);
     46
     47	return ret;
     48}
     49
     50static int check_results(int span)
     51{
     52	unsigned long bw_imc[NUM_OF_RUNS], bw_resc[NUM_OF_RUNS];
     53	char temp[1024], *token_array[8];
     54	char output[] = RESULT_FILE_NAME;
     55	int runs, ret;
     56	FILE *fp;
     57
     58	ksft_print_msg("Checking for pass/fail\n");
     59
     60	fp = fopen(output, "r");
     61	if (!fp) {
     62		perror(output);
     63
     64		return errno;
     65	}
     66
     67	runs = 0;
     68	while (fgets(temp, sizeof(temp), fp)) {
     69		char *token = strtok(temp, ":\t");
     70		int i = 0;
     71
     72		while (token) {
     73			token_array[i++] = token;
     74			token = strtok(NULL, ":\t");
     75		}
     76
     77		bw_resc[runs] = strtoul(token_array[5], NULL, 0);
     78		bw_imc[runs] = strtoul(token_array[3], NULL, 0);
     79		runs++;
     80	}
     81
     82	ret = show_bw_info(bw_imc, bw_resc, span);
     83
     84	fclose(fp);
     85
     86	return ret;
     87}
     88
     89static int mbm_setup(int num, ...)
     90{
     91	struct resctrl_val_param *p;
     92	static int num_of_runs;
     93	va_list param;
     94	int ret = 0;
     95
     96	/* Run NUM_OF_RUNS times */
     97	if (num_of_runs++ >= NUM_OF_RUNS)
     98		return -1;
     99
    100	va_start(param, num);
    101	p = va_arg(param, struct resctrl_val_param *);
    102	va_end(param);
    103
    104	/* Set up shemata with 100% allocation on the first run. */
    105	if (num_of_runs == 0)
    106		ret = write_schemata(p->ctrlgrp, "100", p->cpu_no,
    107				     p->resctrl_val);
    108
    109	return ret;
    110}
    111
    112void mbm_test_cleanup(void)
    113{
    114	remove(RESULT_FILE_NAME);
    115}
    116
    117int mbm_bw_change(int span, int cpu_no, char *bw_report, char **benchmark_cmd)
    118{
    119	struct resctrl_val_param param = {
    120		.resctrl_val	= MBM_STR,
    121		.ctrlgrp	= "c1",
    122		.mongrp		= "m1",
    123		.span		= span,
    124		.cpu_no		= cpu_no,
    125		.mum_resctrlfs	= 1,
    126		.filename	= RESULT_FILE_NAME,
    127		.bw_report	=  bw_report,
    128		.setup		= mbm_setup
    129	};
    130	int ret;
    131
    132	remove(RESULT_FILE_NAME);
    133
    134	ret = resctrl_val(benchmark_cmd, &param);
    135	if (ret)
    136		return ret;
    137
    138	ret = check_results(span);
    139	if (ret)
    140		return ret;
    141
    142	mbm_test_cleanup();
    143
    144	return 0;
    145}