Skip to content

Commit da50de0

Browse files
ij-intelshuahkh
authored andcommitted
selftests/resctrl: Calculate resctrl FS derived mem bw over sleep(1) only
For MBM/MBA tests, measure_vals() calls get_mem_bw_imc() that performs the measurement over a duration of sleep(1) call. The memory bandwidth numbers from IMC are derived over this duration. The resctrl FS derived memory bandwidth, however, is calculated inside measure_vals() and only takes delta between the previous value and the current one which besides the actual test, also samples inter-test noise. Rework the logic in measure_vals() and get_mem_bw_imc() such that the resctrl FS memory bandwidth section covers much shorter duration closely matching that of the IMC perf counters to improve measurement accuracy. For the second read after rewind() to return a fresh value, also newline has to be consumed by the fscanf(). Suggested-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Tested-by: Babu Moger <babu.moger@amd.com> Reviewed-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
1 parent c44000b commit da50de0

1 file changed

Lines changed: 91 additions & 50 deletions

File tree

tools/testing/selftests/resctrl/resctrl_val.c

Lines changed: 91 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -306,35 +306,47 @@ static void perf_close_imc_mem_bw(void)
306306
}
307307

308308
/*
309-
* get_mem_bw_imc: Memory band width as reported by iMC counters
310-
* @cpu_no: CPU number that the benchmark PID is binded to
311-
* @bw_report: Bandwidth report type (reads, writes)
312-
*
313-
* Memory B/W utilized by a process on a socket can be calculated using
314-
* iMC counters. Perf events are used to read these counters.
309+
* perf_open_imc_mem_bw - Open perf fds for IMCs
310+
* @cpu_no: CPU number that the benchmark PID is bound to
315311
*
316312
* Return: = 0 on success. < 0 on failure.
317313
*/
318-
static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc)
314+
static int perf_open_imc_mem_bw(int cpu_no)
319315
{
320-
float reads, writes, of_mul_read, of_mul_write;
321316
int imc, ret;
322317

323318
for (imc = 0; imc < imcs; imc++) {
324319
imc_counters_config[imc][READ].fd = -1;
325320
imc_counters_config[imc][WRITE].fd = -1;
326321
}
327322

328-
/* Start all iMC counters to log values (both read and write) */
329-
reads = 0, writes = 0, of_mul_read = 1, of_mul_write = 1;
330323
for (imc = 0; imc < imcs; imc++) {
331324
ret = open_perf_event(imc, cpu_no, READ);
332325
if (ret)
333326
goto close_fds;
334327
ret = open_perf_event(imc, cpu_no, WRITE);
335328
if (ret)
336329
goto close_fds;
330+
}
331+
332+
return 0;
337333

334+
close_fds:
335+
perf_close_imc_mem_bw();
336+
return -1;
337+
}
338+
339+
/*
340+
* do_mem_bw_test - Perform memory bandwidth test
341+
*
342+
* Runs memory bandwidth test over one second period. Also, handles starting
343+
* and stopping of the IMC perf counters around the test.
344+
*/
345+
static void do_imc_mem_bw_test(void)
346+
{
347+
int imc;
348+
349+
for (imc = 0; imc < imcs; imc++) {
338350
membw_ioctl_perf_event_ioc_reset_enable(imc, READ);
339351
membw_ioctl_perf_event_ioc_reset_enable(imc, WRITE);
340352
}
@@ -346,6 +358,24 @@ static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc)
346358
membw_ioctl_perf_event_ioc_disable(imc, READ);
347359
membw_ioctl_perf_event_ioc_disable(imc, WRITE);
348360
}
361+
}
362+
363+
/*
364+
* get_mem_bw_imc - Memory band width as reported by iMC counters
365+
* @bw_report: Bandwidth report type (reads, writes)
366+
*
367+
* Memory B/W utilized by a process on a socket can be calculated using
368+
* iMC counters. Perf events are used to read these counters.
369+
*
370+
* Return: = 0 on success. < 0 on failure.
371+
*/
372+
static int get_mem_bw_imc(char *bw_report, float *bw_imc)
373+
{
374+
float reads, writes, of_mul_read, of_mul_write;
375+
int imc;
376+
377+
/* Start all iMC counters to log values (both read and write) */
378+
reads = 0, writes = 0, of_mul_read = 1, of_mul_write = 1;
349379

350380
/*
351381
* Get results which are stored in struct type imc_counter_config
@@ -360,13 +390,13 @@ static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc)
360390
if (read(r->fd, &r->return_value,
361391
sizeof(struct membw_read_format)) == -1) {
362392
ksft_perror("Couldn't get read b/w through iMC");
363-
goto close_fds;
393+
return -1;
364394
}
365395

366396
if (read(w->fd, &w->return_value,
367397
sizeof(struct membw_read_format)) == -1) {
368398
ksft_perror("Couldn't get write bw through iMC");
369-
goto close_fds;
399+
return -1;
370400
}
371401

372402
__u64 r_time_enabled = r->return_value.time_enabled;
@@ -386,8 +416,6 @@ static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc)
386416
writes += w->return_value.value * of_mul_write * SCALE;
387417
}
388418

389-
perf_close_imc_mem_bw();
390-
391419
if (strcmp(bw_report, "reads") == 0) {
392420
*bw_imc = reads;
393421
return 0;
@@ -400,10 +428,6 @@ static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc)
400428

401429
*bw_imc = reads + writes;
402430
return 0;
403-
404-
close_fds:
405-
perf_close_imc_mem_bw();
406-
return -1;
407431
}
408432

409433
void set_mbm_path(const char *ctrlgrp, const char *mongrp, int domain_id)
@@ -462,24 +486,23 @@ static void initialize_mem_bw_resctrl(const char *ctrlgrp, const char *mongrp,
462486
* 1. If con_mon grp is given, then read from it
463487
* 2. If con_mon grp is not given, then read from root con_mon grp
464488
*/
465-
static int get_mem_bw_resctrl(unsigned long *mbm_total)
489+
static FILE *open_mem_bw_resctrl(const char *mbm_bw_file)
466490
{
467491
FILE *fp;
468492

469-
fp = fopen(mbm_total_path, "r");
470-
if (!fp) {
493+
fp = fopen(mbm_bw_file, "r");
494+
if (!fp)
471495
ksft_perror("Failed to open total bw file");
472496

473-
return -1;
474-
}
475-
if (fscanf(fp, "%lu", mbm_total) <= 0) {
476-
ksft_perror("Could not get mbm local bytes");
477-
fclose(fp);
497+
return fp;
498+
}
478499

500+
static int get_mem_bw_resctrl(FILE *fp, unsigned long *mbm_total)
501+
{
502+
if (fscanf(fp, "%lu\n", mbm_total) <= 0) {
503+
ksft_perror("Could not get MBM local bytes");
479504
return -1;
480505
}
481-
fclose(fp);
482-
483506
return 0;
484507
}
485508

@@ -615,37 +638,56 @@ static void initialize_llc_occu_resctrl(const char *ctrlgrp, const char *mongrp,
615638
set_cmt_path(ctrlgrp, mongrp, domain_id);
616639
}
617640

641+
/*
642+
* Measure memory bandwidth from resctrl and from another source which is
643+
* perf imc value or could be something else if perf imc event is not
644+
* available. Compare the two values to validate resctrl value. It takes
645+
* 1 sec to measure the data.
646+
*/
618647
static int measure_vals(const struct user_params *uparams,
619-
struct resctrl_val_param *param,
620-
unsigned long *bw_resc_start)
648+
struct resctrl_val_param *param)
621649
{
622-
unsigned long bw_resc, bw_resc_end;
650+
unsigned long bw_resc, bw_resc_start, bw_resc_end;
651+
FILE *mem_bw_fp;
623652
float bw_imc;
624653
int ret;
625654

626-
/*
627-
* Measure memory bandwidth from resctrl and from
628-
* another source which is perf imc value or could
629-
* be something else if perf imc event is not available.
630-
* Compare the two values to validate resctrl value.
631-
* It takes 1sec to measure the data.
632-
*/
633-
ret = get_mem_bw_imc(uparams->cpu, param->bw_report, &bw_imc);
655+
mem_bw_fp = open_mem_bw_resctrl(mbm_total_path);
656+
if (!mem_bw_fp)
657+
return -1;
658+
659+
ret = perf_open_imc_mem_bw(uparams->cpu);
634660
if (ret < 0)
635-
return ret;
661+
goto close_fp;
636662

637-
ret = get_mem_bw_resctrl(&bw_resc_end);
663+
ret = get_mem_bw_resctrl(mem_bw_fp, &bw_resc_start);
638664
if (ret < 0)
639-
return ret;
665+
goto close_imc;
640666

641-
bw_resc = (bw_resc_end - *bw_resc_start) / MB;
642-
ret = print_results_bw(param->filename, bm_pid, bw_imc, bw_resc);
643-
if (ret)
644-
return ret;
667+
rewind(mem_bw_fp);
645668

646-
*bw_resc_start = bw_resc_end;
669+
do_imc_mem_bw_test();
647670

648-
return 0;
671+
ret = get_mem_bw_resctrl(mem_bw_fp, &bw_resc_end);
672+
if (ret < 0)
673+
goto close_imc;
674+
675+
ret = get_mem_bw_imc(param->bw_report, &bw_imc);
676+
if (ret < 0)
677+
goto close_imc;
678+
679+
perf_close_imc_mem_bw();
680+
fclose(mem_bw_fp);
681+
682+
bw_resc = (bw_resc_end - bw_resc_start) / MB;
683+
684+
return print_results_bw(param->filename, bm_pid, bw_imc, bw_resc);
685+
686+
close_imc:
687+
perf_close_imc_mem_bw();
688+
close_fp:
689+
fclose(mem_bw_fp);
690+
return ret;
649691
}
650692

651693
/*
@@ -719,7 +761,6 @@ int resctrl_val(const struct resctrl_test *test,
719761
struct resctrl_val_param *param)
720762
{
721763
char *resctrl_val = param->resctrl_val;
722-
unsigned long bw_resc_start = 0;
723764
struct sigaction sigact;
724765
int ret = 0, pipefd[2];
725766
char pipe_message = 0;
@@ -861,7 +902,7 @@ int resctrl_val(const struct resctrl_test *test,
861902

862903
if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
863904
!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
864-
ret = measure_vals(uparams, param, &bw_resc_start);
905+
ret = measure_vals(uparams, param);
865906
if (ret)
866907
break;
867908
} else if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {

0 commit comments

Comments
 (0)