101fee6b4SFenghua Yu // SPDX-License-Identifier: GPL-2.0 201fee6b4SFenghua Yu /* 301fee6b4SFenghua Yu * Memory Bandwidth Allocation (MBA) test 401fee6b4SFenghua Yu * 501fee6b4SFenghua Yu * Copyright (C) 2018 Intel Corporation 601fee6b4SFenghua Yu * 701fee6b4SFenghua Yu * Authors: 801fee6b4SFenghua Yu * Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>, 901fee6b4SFenghua Yu * Fenghua Yu <fenghua.yu@intel.com> 1001fee6b4SFenghua Yu */ 1101fee6b4SFenghua Yu #include "resctrl.h" 1201fee6b4SFenghua Yu 1301fee6b4SFenghua Yu #define RESULT_FILE_NAME "result_mba" 1401fee6b4SFenghua Yu #define NUM_OF_RUNS 5 15ef43c308SIlpo Järvinen #define MAX_DIFF_PERCENT 8 1601fee6b4SFenghua Yu #define ALLOCATION_MAX 100 1701fee6b4SFenghua Yu #define ALLOCATION_MIN 10 1801fee6b4SFenghua Yu #define ALLOCATION_STEP 10 1901fee6b4SFenghua Yu 2001fee6b4SFenghua Yu /* 2101fee6b4SFenghua Yu * Change schemata percentage from 100 to 10%. Write schemata to specified 2201fee6b4SFenghua Yu * con_mon grp, mon_grp in resctrl FS. 2301fee6b4SFenghua Yu * For each allocation, run 5 times in order to get average values. 2401fee6b4SFenghua Yu */ 25ca160887SIlpo Järvinen static int mba_setup(const struct resctrl_test *test, 26ca160887SIlpo Järvinen const struct user_params *uparams, 27ca160887SIlpo Järvinen struct resctrl_val_param *p) 2801fee6b4SFenghua Yu { 2901fee6b4SFenghua Yu static int runs_per_allocation, allocation = 100; 3001fee6b4SFenghua Yu char allocation_str[64]; 310d45c83bSIlpo Järvinen int ret; 3201fee6b4SFenghua Yu 3301fee6b4SFenghua Yu if (runs_per_allocation >= NUM_OF_RUNS) 3401fee6b4SFenghua Yu runs_per_allocation = 0; 3501fee6b4SFenghua Yu 3601fee6b4SFenghua Yu /* Only set up schemata once every NUM_OF_RUNS of allocations */ 3701fee6b4SFenghua Yu if (runs_per_allocation++ != 0) 3801fee6b4SFenghua Yu return 0; 3901fee6b4SFenghua Yu 4001fee6b4SFenghua Yu if (allocation < ALLOCATION_MIN || allocation > ALLOCATION_MAX) 41fa10366cSIlpo Järvinen return END_OF_TESTS; 4201fee6b4SFenghua Yu 4301fee6b4SFenghua Yu sprintf(allocation_str, "%d", allocation); 4401fee6b4SFenghua Yu 45ca160887SIlpo Järvinen ret = write_schemata(p->ctrlgrp, allocation_str, uparams->cpu, test->resource); 460d45c83bSIlpo Järvinen if (ret < 0) 470d45c83bSIlpo Järvinen return ret; 480d45c83bSIlpo Järvinen 4901fee6b4SFenghua Yu allocation -= ALLOCATION_STEP; 5001fee6b4SFenghua Yu 5101fee6b4SFenghua Yu return 0; 5201fee6b4SFenghua Yu } 5301fee6b4SFenghua Yu 541e359b6aSShaopeng Tan static bool show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc) 5501fee6b4SFenghua Yu { 5601fee6b4SFenghua Yu int allocation, runs; 571e359b6aSShaopeng Tan bool ret = false; 5801fee6b4SFenghua Yu 59ca2f4214SFenghua Yu ksft_print_msg("Results are displayed in (MB)\n"); 6001fee6b4SFenghua Yu /* Memory bandwidth from 100% down to 10% */ 6101fee6b4SFenghua Yu for (allocation = 0; allocation < ALLOCATION_MAX / ALLOCATION_STEP; 6201fee6b4SFenghua Yu allocation++) { 6301fee6b4SFenghua Yu unsigned long avg_bw_imc, avg_bw_resc; 6401fee6b4SFenghua Yu unsigned long sum_bw_imc = 0, sum_bw_resc = 0; 6506bd03a5SFenghua Yu int avg_diff_per; 6606bd03a5SFenghua Yu float avg_diff; 6701fee6b4SFenghua Yu 6801fee6b4SFenghua Yu /* 6901fee6b4SFenghua Yu * The first run is discarded due to inaccurate value from 7001fee6b4SFenghua Yu * phase transition. 7101fee6b4SFenghua Yu */ 7201fee6b4SFenghua Yu for (runs = NUM_OF_RUNS * allocation + 1; 7301fee6b4SFenghua Yu runs < NUM_OF_RUNS * allocation + NUM_OF_RUNS ; runs++) { 7401fee6b4SFenghua Yu sum_bw_imc += bw_imc[runs]; 7501fee6b4SFenghua Yu sum_bw_resc += bw_resc[runs]; 7601fee6b4SFenghua Yu } 7701fee6b4SFenghua Yu 7801fee6b4SFenghua Yu avg_bw_imc = sum_bw_imc / (NUM_OF_RUNS - 1); 7901fee6b4SFenghua Yu avg_bw_resc = sum_bw_resc / (NUM_OF_RUNS - 1); 8006bd03a5SFenghua Yu avg_diff = (float)labs(avg_bw_resc - avg_bw_imc) / avg_bw_imc; 8106bd03a5SFenghua Yu avg_diff_per = (int)(avg_diff * 100); 8201fee6b4SFenghua Yu 83e7507478SFenghua Yu ksft_print_msg("%s Check MBA diff within %d%% for schemata %u\n", 8406bd03a5SFenghua Yu avg_diff_per > MAX_DIFF_PERCENT ? 8506bd03a5SFenghua Yu "Fail:" : "Pass:", 8606bd03a5SFenghua Yu MAX_DIFF_PERCENT, 8706bd03a5SFenghua Yu ALLOCATION_MAX - ALLOCATION_STEP * allocation); 8806bd03a5SFenghua Yu 8906bd03a5SFenghua Yu ksft_print_msg("avg_diff_per: %d%%\n", avg_diff_per); 90ca2f4214SFenghua Yu ksft_print_msg("avg_bw_imc: %lu\n", avg_bw_imc); 91ca2f4214SFenghua Yu ksft_print_msg("avg_bw_resc: %lu\n", avg_bw_resc); 9206bd03a5SFenghua Yu if (avg_diff_per > MAX_DIFF_PERCENT) 931e359b6aSShaopeng Tan ret = true; 9401fee6b4SFenghua Yu } 9501fee6b4SFenghua Yu 96e7507478SFenghua Yu ksft_print_msg("%s Check schemata change using MBA\n", 971e359b6aSShaopeng Tan ret ? "Fail:" : "Pass:"); 981e359b6aSShaopeng Tan if (ret) 99e7507478SFenghua Yu ksft_print_msg("At least one test failed\n"); 1001e359b6aSShaopeng Tan 1011e359b6aSShaopeng Tan return ret; 10201fee6b4SFenghua Yu } 10301fee6b4SFenghua Yu 10401fee6b4SFenghua Yu static int check_results(void) 10501fee6b4SFenghua Yu { 10601fee6b4SFenghua Yu char *token_array[8], output[] = RESULT_FILE_NAME, temp[512]; 10701fee6b4SFenghua Yu unsigned long bw_imc[1024], bw_resc[1024]; 10801fee6b4SFenghua Yu int runs; 10901fee6b4SFenghua Yu FILE *fp; 11001fee6b4SFenghua Yu 11101fee6b4SFenghua Yu fp = fopen(output, "r"); 11201fee6b4SFenghua Yu if (!fp) { 113cc8ff7f5SIlpo Järvinen ksft_perror(output); 11401fee6b4SFenghua Yu 115c90fba60SIlpo Järvinen return -1; 11601fee6b4SFenghua Yu } 11701fee6b4SFenghua Yu 11801fee6b4SFenghua Yu runs = 0; 11901fee6b4SFenghua Yu while (fgets(temp, sizeof(temp), fp)) { 12001fee6b4SFenghua Yu char *token = strtok(temp, ":\t"); 12101fee6b4SFenghua Yu int fields = 0; 12201fee6b4SFenghua Yu 12301fee6b4SFenghua Yu while (token) { 12401fee6b4SFenghua Yu token_array[fields++] = token; 12501fee6b4SFenghua Yu token = strtok(NULL, ":\t"); 12601fee6b4SFenghua Yu } 12701fee6b4SFenghua Yu 12801fee6b4SFenghua Yu /* Field 3 is perf imc value */ 12901fee6b4SFenghua Yu bw_imc[runs] = strtoul(token_array[3], NULL, 0); 13001fee6b4SFenghua Yu /* Field 5 is resctrl value */ 13101fee6b4SFenghua Yu bw_resc[runs] = strtoul(token_array[5], NULL, 0); 13201fee6b4SFenghua Yu runs++; 13301fee6b4SFenghua Yu } 13401fee6b4SFenghua Yu 13501fee6b4SFenghua Yu fclose(fp); 13601fee6b4SFenghua Yu 1371e359b6aSShaopeng Tan return show_mba_info(bw_imc, bw_resc); 13801fee6b4SFenghua Yu } 13901fee6b4SFenghua Yu 14001fee6b4SFenghua Yu void mba_test_cleanup(void) 14101fee6b4SFenghua Yu { 14201fee6b4SFenghua Yu remove(RESULT_FILE_NAME); 14301fee6b4SFenghua Yu } 14401fee6b4SFenghua Yu 145c603ff5bSIlpo Järvinen static int mba_run_test(const struct resctrl_test *test, const struct user_params *uparams) 14601fee6b4SFenghua Yu { 14701fee6b4SFenghua Yu struct resctrl_val_param param = { 14824286736SFenghua Yu .resctrl_val = MBA_STR, 14901fee6b4SFenghua Yu .ctrlgrp = "c1", 15001fee6b4SFenghua Yu .mongrp = "m1", 15101fee6b4SFenghua Yu .filename = RESULT_FILE_NAME, 15247e36f16SIlpo Järvinen .bw_report = "reads", 15301fee6b4SFenghua Yu .setup = mba_setup 15401fee6b4SFenghua Yu }; 15501fee6b4SFenghua Yu int ret; 15601fee6b4SFenghua Yu 15701fee6b4SFenghua Yu remove(RESULT_FILE_NAME); 15801fee6b4SFenghua Yu 159ca160887SIlpo Järvinen ret = resctrl_val(test, uparams, uparams->benchmark_cmd, ¶m); 16001fee6b4SFenghua Yu if (ret) 16191db4fd9SShaopeng Tan goto out; 16201fee6b4SFenghua Yu 16301fee6b4SFenghua Yu ret = check_results(); 16401fee6b4SFenghua Yu 16591db4fd9SShaopeng Tan out: 16601fee6b4SFenghua Yu mba_test_cleanup(); 16701fee6b4SFenghua Yu 16891db4fd9SShaopeng Tan return ret; 16901fee6b4SFenghua Yu } 170c603ff5bSIlpo Järvinen 171c603ff5bSIlpo Järvinen static bool mba_feature_check(const struct resctrl_test *test) 172c603ff5bSIlpo Järvinen { 173c603ff5bSIlpo Järvinen return test_resource_feature_check(test) && 174*00616416SMaciej Wieczor-Retman resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes"); 175c603ff5bSIlpo Järvinen } 176c603ff5bSIlpo Järvinen 177c603ff5bSIlpo Järvinen struct resctrl_test mba_test = { 178c603ff5bSIlpo Järvinen .name = "MBA", 179c603ff5bSIlpo Järvinen .resource = "MB", 180c603ff5bSIlpo Järvinen .vendor_specific = ARCH_INTEL, 181c603ff5bSIlpo Järvinen .feature_check = mba_feature_check, 182c603ff5bSIlpo Järvinen .run_test = mba_run_test, 183c603ff5bSIlpo Järvinen }; 184