2020-01-16 13:32:35 -08:00
// SPDX-License-Identifier: GPL-2.0
/*
* Basic resctrl file system operations
*
* Copyright ( C ) 2018 Intel Corporation
*
* Authors :
* Sai Praneeth Prakhya < sai . praneeth . prakhya @ intel . com > ,
* Fenghua Yu < fenghua . yu @ intel . com >
*/
# include "resctrl.h"
static int find_resctrl_mount ( char * buffer )
{
FILE * mounts ;
char line [ 256 ] , * fs , * mntpoint ;
mounts = fopen ( " /proc/mounts " , " r " ) ;
if ( ! mounts ) {
perror ( " /proc/mounts " ) ;
return - ENXIO ;
}
while ( ! feof ( mounts ) ) {
if ( ! fgets ( line , 256 , mounts ) )
break ;
fs = strtok ( line , " \t " ) ;
if ( ! fs )
continue ;
mntpoint = strtok ( NULL , " \t " ) ;
if ( ! mntpoint )
continue ;
fs = strtok ( NULL , " \t " ) ;
if ( ! fs )
continue ;
if ( strcmp ( fs , " resctrl " ) )
continue ;
fclose ( mounts ) ;
if ( buffer )
strncpy ( buffer , mntpoint , 256 ) ;
return 0 ;
}
fclose ( mounts ) ;
return - ENOENT ;
}
/*
* remount_resctrlfs - Remount resctrl FS at / sys / fs / resctrl
* @ mum_resctrlfs : Should the resctrl FS be remounted ?
*
* If not mounted , mount it .
* If mounted and mum_resctrlfs then remount resctrl FS .
* If mounted and ! mum_resctrlfs then noop
*
* Return : 0 on success , non - zero on failure
*/
int remount_resctrlfs ( bool mum_resctrlfs )
{
char mountpoint [ 256 ] ;
int ret ;
ret = find_resctrl_mount ( mountpoint ) ;
if ( ret )
strcpy ( mountpoint , RESCTRL_PATH ) ;
2021-03-17 02:22:42 +00:00
if ( ! ret & & mum_resctrlfs & & umount ( mountpoint ) )
ksft_print_msg ( " Fail: unmounting \" %s \" \n " , mountpoint ) ;
2020-01-16 13:32:35 -08:00
if ( ! ret & & ! mum_resctrlfs )
return 0 ;
2021-03-17 02:22:42 +00:00
ksft_print_msg ( " Mounting resctrl to \" %s \" \n " , RESCTRL_PATH ) ;
2020-01-16 13:32:35 -08:00
ret = mount ( " resctrl " , RESCTRL_PATH , " resctrl " , 0 , NULL ) ;
if ( ret )
perror ( " # mount " ) ;
return ret ;
}
int umount_resctrlfs ( void )
{
2021-03-17 02:22:52 +00:00
if ( find_resctrl_mount ( NULL ) )
return 0 ;
2020-01-16 13:32:35 -08:00
if ( umount ( RESCTRL_PATH ) ) {
perror ( " # Unable to umount resctrl " ) ;
return errno ;
}
return 0 ;
}
/*
* get_resource_id - Get socket number / l3 id for a specified CPU
* @ cpu_no : CPU number
* @ resource_id : Socket number or l3_id
*
* Return : > = 0 on success , < 0 on failure .
*/
int get_resource_id ( int cpu_no , int * resource_id )
{
char phys_pkg_path [ 1024 ] ;
FILE * fp ;
2020-01-16 13:32:44 -08:00
if ( is_amd )
sprintf ( phys_pkg_path , " %s%d/cache/index3/id " ,
PHYS_ID_PATH , cpu_no ) ;
else
sprintf ( phys_pkg_path , " %s%d/topology/physical_package_id " ,
PHYS_ID_PATH , cpu_no ) ;
2020-01-16 13:32:35 -08:00
fp = fopen ( phys_pkg_path , " r " ) ;
if ( ! fp ) {
perror ( " Failed to open physical_package_id " ) ;
return - 1 ;
}
if ( fscanf ( fp , " %d " , resource_id ) < = 0 ) {
perror ( " Could not get socket number or l3 id " ) ;
fclose ( fp ) ;
return - 1 ;
}
fclose ( fp ) ;
return 0 ;
}
2020-01-16 13:32:41 -08:00
/*
* get_cache_size - Get cache size for a specified CPU
* @ cpu_no : CPU number
* @ cache_type : Cache level L2 / L3
* @ cache_size : pointer to cache_size
*
* Return : = 0 on success , < 0 on failure .
*/
int get_cache_size ( int cpu_no , char * cache_type , unsigned long * cache_size )
{
char cache_path [ 1024 ] , cache_str [ 64 ] ;
int length , i , cache_num ;
FILE * fp ;
if ( ! strcmp ( cache_type , " L3 " ) ) {
cache_num = 3 ;
} else if ( ! strcmp ( cache_type , " L2 " ) ) {
cache_num = 2 ;
} else {
perror ( " Invalid cache level " ) ;
return - 1 ;
}
sprintf ( cache_path , " /sys/bus/cpu/devices/cpu%d/cache/index%d/size " ,
cpu_no , cache_num ) ;
fp = fopen ( cache_path , " r " ) ;
if ( ! fp ) {
perror ( " Failed to open cache size " ) ;
return - 1 ;
}
if ( fscanf ( fp , " %s " , cache_str ) < = 0 ) {
perror ( " Could not get cache_size " ) ;
fclose ( fp ) ;
return - 1 ;
}
fclose ( fp ) ;
length = ( int ) strlen ( cache_str ) ;
* cache_size = 0 ;
for ( i = 0 ; i < length ; i + + ) {
if ( ( cache_str [ i ] > = ' 0 ' ) & & ( cache_str [ i ] < = ' 9 ' ) )
* cache_size = * cache_size * 10 + ( cache_str [ i ] - ' 0 ' ) ;
else if ( cache_str [ i ] = = ' K ' )
* cache_size = * cache_size * 1024 ;
else if ( cache_str [ i ] = = ' M ' )
* cache_size = * cache_size * 1024 * 1024 ;
else
break ;
}
return 0 ;
}
# define CORE_SIBLINGS_PATH " / sys / bus / cpu / devices / cpu"
/*
* get_cbm_mask - Get cbm mask for given cache
* @ cache_type : Cache level L2 / L3
2021-03-17 02:22:36 +00:00
* @ cbm_mask : cbm_mask returned as a string
2020-01-16 13:32:41 -08:00
*
* Return : = 0 on success , < 0 on failure .
*/
2021-03-17 02:22:36 +00:00
int get_cbm_mask ( char * cache_type , char * cbm_mask )
2020-01-16 13:32:41 -08:00
{
char cbm_mask_path [ 1024 ] ;
FILE * fp ;
2021-03-17 02:22:36 +00:00
if ( ! cbm_mask )
return - 1 ;
2020-01-16 13:32:41 -08:00
sprintf ( cbm_mask_path , " %s/%s/cbm_mask " , CBM_MASK_PATH , cache_type ) ;
fp = fopen ( cbm_mask_path , " r " ) ;
if ( ! fp ) {
perror ( " Failed to open cache level " ) ;
return - 1 ;
}
if ( fscanf ( fp , " %s " , cbm_mask ) < = 0 ) {
perror ( " Could not get max cbm_mask " ) ;
fclose ( fp ) ;
return - 1 ;
}
fclose ( fp ) ;
return 0 ;
}
/*
* get_core_sibling - Get sibling core id from the same socket for given CPU
* @ cpu_no : CPU number
*
* Return : > 0 on success , < 0 on failure .
*/
int get_core_sibling ( int cpu_no )
{
char core_siblings_path [ 1024 ] , cpu_list_str [ 64 ] ;
int sibling_cpu_no = - 1 ;
FILE * fp ;
sprintf ( core_siblings_path , " %s%d/topology/core_siblings_list " ,
CORE_SIBLINGS_PATH , cpu_no ) ;
fp = fopen ( core_siblings_path , " r " ) ;
if ( ! fp ) {
perror ( " Failed to open core siblings path " ) ;
return - 1 ;
}
if ( fscanf ( fp , " %s " , cpu_list_str ) < = 0 ) {
perror ( " Could not get core_siblings list " ) ;
fclose ( fp ) ;
return - 1 ;
}
fclose ( fp ) ;
char * token = strtok ( cpu_list_str , " -, " ) ;
while ( token ) {
sibling_cpu_no = atoi ( token ) ;
/* Skipping core 0 as we don't want to run test on core 0 */
2021-03-17 02:22:39 +00:00
if ( sibling_cpu_no ! = 0 & & sibling_cpu_no ! = cpu_no )
2020-01-16 13:32:41 -08:00
break ;
token = strtok ( NULL , " -, " ) ;
}
return sibling_cpu_no ;
}
2020-01-16 13:32:35 -08:00
/*
* taskset_benchmark - Taskset PID ( i . e . benchmark ) to a specified cpu
* @ bm_pid : PID that should be binded
* @ cpu_no : CPU number at which the PID would be binded
*
* Return : 0 on success , non - zero on failure
*/
int taskset_benchmark ( pid_t bm_pid , int cpu_no )
{
cpu_set_t my_set ;
CPU_ZERO ( & my_set ) ;
CPU_SET ( cpu_no , & my_set ) ;
if ( sched_setaffinity ( bm_pid , sizeof ( cpu_set_t ) , & my_set ) ) {
perror ( " Unable to taskset benchmark " ) ;
return - 1 ;
}
return 0 ;
}
/*
* run_benchmark - Run a specified benchmark or fill_buf ( default benchmark )
* in specified signal . Direct benchmark stdio to / dev / null .
* @ signum : signal number
* @ info : signal info
* @ ucontext : user context in signal handling
*
* Return : void
*/
void run_benchmark ( int signum , siginfo_t * info , void * ucontext )
{
2020-01-16 13:32:41 -08:00
int operation , ret , malloc_and_init_memory , memflush ;
unsigned long span , buffer_span ;
2020-01-16 13:32:35 -08:00
char * * benchmark_cmd ;
2020-01-16 13:32:41 -08:00
char resctrl_val [ 64 ] ;
2020-01-16 13:32:35 -08:00
FILE * fp ;
benchmark_cmd = info - > si_ptr ;
/*
* Direct stdio of child to / dev / null , so that only parent writes to
* stdio ( console )
*/
fp = freopen ( " /dev/null " , " w " , stdout ) ;
if ( ! fp )
PARENT_EXIT ( " Unable to direct benchmark status to /dev/null " ) ;
if ( strcmp ( benchmark_cmd [ 0 ] , " fill_buf " ) = = 0 ) {
/* Execute default fill_buf benchmark */
span = strtoul ( benchmark_cmd [ 1 ] , NULL , 10 ) ;
2020-01-16 13:32:41 -08:00
malloc_and_init_memory = atoi ( benchmark_cmd [ 2 ] ) ;
memflush = atoi ( benchmark_cmd [ 3 ] ) ;
2020-01-16 13:32:35 -08:00
operation = atoi ( benchmark_cmd [ 4 ] ) ;
2020-01-16 13:32:41 -08:00
sprintf ( resctrl_val , " %s " , benchmark_cmd [ 5 ] ) ;
selftests/resctrl: Rename CQM test as CMT test
CMT (Cache Monitoring Technology) [1] is a H/W feature that reports cache
occupancy of a process. resctrl selftest suite has a unit test to test CMT
for LLC but the test is named as CQM (Cache Quality Monitoring).
Furthermore, the unit test source file is named as cqm_test.c and several
functions, variables, comments, preprocessors and statements widely use
"cqm" as either suffix or prefix. This rampant misusage of CQM for CMT
might confuse someone who is newly looking at resctrl selftests because
this feature is named CMT in the Intel Software Developer's Manual.
Hence, rename all the occurrences (unit test source file name, functions,
variables, comments and preprocessors) of cqm with cmt.
[1] Please see Intel SDM, Volume 3, chapter 17 and section 18 for more
information on CMT: https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html
Suggested-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 02:22:41 +00:00
if ( strncmp ( resctrl_val , CMT_STR , sizeof ( CMT_STR ) ) )
2020-01-16 13:32:41 -08:00
buffer_span = span * MB ;
else
buffer_span = span ;
if ( run_fill_buf ( buffer_span , malloc_and_init_memory , memflush ,
operation , resctrl_val ) )
2020-01-16 13:32:35 -08:00
fprintf ( stderr , " Error in running fill buffer \n " ) ;
} else {
/* Execute specified benchmark */
ret = execvp ( benchmark_cmd [ 0 ] , benchmark_cmd ) ;
if ( ret )
perror ( " wrong \n " ) ;
}
fclose ( stdout ) ;
PARENT_EXIT ( " Unable to run specified benchmark " ) ;
}
/*
* create_grp - Create a group only if one doesn ' t exist
* @ grp_name : Name of the group
* @ grp : Full path and name of the group
* @ parent_grp : Full path and name of the parent group
*
* Return : 0 on success , non - zero on failure
*/
static int create_grp ( const char * grp_name , char * grp , const char * parent_grp )
{
int found_grp = 0 ;
struct dirent * ep ;
DIR * dp ;
2020-01-16 13:32:41 -08:00
/*
* At this point , we are guaranteed to have resctrl FS mounted and if
* length of grp_name = = 0 , it means , user wants to use root con_mon
* grp , so do nothing
*/
if ( strlen ( grp_name ) = = 0 )
return 0 ;
2020-01-16 13:32:35 -08:00
/* Check if requested grp exists or not */
dp = opendir ( parent_grp ) ;
if ( dp ) {
while ( ( ep = readdir ( dp ) ) ! = NULL ) {
if ( strcmp ( ep - > d_name , grp_name ) = = 0 )
found_grp = 1 ;
}
closedir ( dp ) ;
} else {
perror ( " Unable to open resctrl for group " ) ;
return - 1 ;
}
/* Requested grp doesn't exist, hence create it */
if ( found_grp = = 0 ) {
if ( mkdir ( grp , 0 ) = = - 1 ) {
perror ( " Unable to create group " ) ;
return - 1 ;
}
}
return 0 ;
}
static int write_pid_to_tasks ( char * tasks , pid_t pid )
{
FILE * fp ;
fp = fopen ( tasks , " w " ) ;
if ( ! fp ) {
perror ( " Failed to open tasks file " ) ;
return - 1 ;
}
if ( fprintf ( fp , " %d \n " , pid ) < 0 ) {
perror ( " Failed to wr pid to tasks file " ) ;
fclose ( fp ) ;
return - 1 ;
}
fclose ( fp ) ;
return 0 ;
}
/*
* write_bm_pid_to_resctrl - Write a PID ( i . e . benchmark ) to resctrl FS
* @ bm_pid : PID that should be written
* @ ctrlgrp : Name of the control monitor group ( con_mon grp )
* @ mongrp : Name of the monitor group ( mon grp )
* @ resctrl_val : Resctrl feature ( Eg : mbm , mba . . etc )
*
* If a con_mon grp is requested , create it and write pid to it , otherwise
* write pid to root con_mon grp .
* If a mon grp is requested , create it and write pid to it , otherwise
* pid is not written , this means that pid is in con_mon grp and hence
* should consult con_mon grp ' s mon_data directory for results .
*
* Return : 0 on success , non - zero on failure
*/
int write_bm_pid_to_resctrl ( pid_t bm_pid , char * ctrlgrp , char * mongrp ,
char * resctrl_val )
{
char controlgroup [ 128 ] , monitorgroup [ 512 ] , monitorgroup_p [ 256 ] ;
char tasks [ 1024 ] ;
int ret = 0 ;
if ( strlen ( ctrlgrp ) )
sprintf ( controlgroup , " %s/%s " , RESCTRL_PATH , ctrlgrp ) ;
else
sprintf ( controlgroup , " %s " , RESCTRL_PATH ) ;
/* Create control and monitoring group and write pid into it */
ret = create_grp ( ctrlgrp , controlgroup , RESCTRL_PATH ) ;
if ( ret )
goto out ;
sprintf ( tasks , " %s/tasks " , controlgroup ) ;
ret = write_pid_to_tasks ( tasks , bm_pid ) ;
if ( ret )
goto out ;
selftests/resctrl: Rename CQM test as CMT test
CMT (Cache Monitoring Technology) [1] is a H/W feature that reports cache
occupancy of a process. resctrl selftest suite has a unit test to test CMT
for LLC but the test is named as CQM (Cache Quality Monitoring).
Furthermore, the unit test source file is named as cqm_test.c and several
functions, variables, comments, preprocessors and statements widely use
"cqm" as either suffix or prefix. This rampant misusage of CQM for CMT
might confuse someone who is newly looking at resctrl selftests because
this feature is named CMT in the Intel Software Developer's Manual.
Hence, rename all the occurrences (unit test source file name, functions,
variables, comments and preprocessors) of cqm with cmt.
[1] Please see Intel SDM, Volume 3, chapter 17 and section 18 for more
information on CMT: https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html
Suggested-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 02:22:41 +00:00
/* Create mon grp and write pid into it for "mbm" and "cmt" test */
if ( ! strncmp ( resctrl_val , CMT_STR , sizeof ( CMT_STR ) ) | |
2021-03-17 02:22:38 +00:00
! strncmp ( resctrl_val , MBM_STR , sizeof ( MBM_STR ) ) ) {
2020-01-16 13:32:41 -08:00
if ( strlen ( mongrp ) ) {
2020-01-16 13:32:35 -08:00
sprintf ( monitorgroup_p , " %s/mon_groups " , controlgroup ) ;
sprintf ( monitorgroup , " %s/%s " , monitorgroup_p , mongrp ) ;
ret = create_grp ( mongrp , monitorgroup , monitorgroup_p ) ;
if ( ret )
goto out ;
sprintf ( tasks , " %s/mon_groups/%s/tasks " ,
controlgroup , mongrp ) ;
ret = write_pid_to_tasks ( tasks , bm_pid ) ;
if ( ret )
goto out ;
}
}
out :
2021-03-17 02:22:42 +00:00
ksft_print_msg ( " Writing benchmark parameters to resctrl FS \n " ) ;
2020-01-16 13:32:35 -08:00
if ( ret )
perror ( " # writing to resctrlfs " ) ;
return ret ;
}
/*
* write_schemata - Update schemata of a con_mon grp
* @ ctrlgrp : Name of the con_mon grp
* @ schemata : Schemata that should be updated to
* @ cpu_no : CPU number that the benchmark PID is binded to
* @ resctrl_val : Resctrl feature ( Eg : mbm , mba . . etc )
*
* Update schemata of a con_mon grp * only * if requested resctrl feature is
* allocation type
*
* Return : 0 on success , non - zero on failure
*/
int write_schemata ( char * ctrlgrp , char * schemata , int cpu_no , char * resctrl_val )
{
char controlgroup [ 1024 ] , schema [ 1024 ] , reason [ 64 ] ;
int resource_id , ret = 0 ;
FILE * fp ;
2021-03-17 02:22:38 +00:00
if ( strncmp ( resctrl_val , MBA_STR , sizeof ( MBA_STR ) ) & &
strncmp ( resctrl_val , CAT_STR , sizeof ( CAT_STR ) ) & &
selftests/resctrl: Rename CQM test as CMT test
CMT (Cache Monitoring Technology) [1] is a H/W feature that reports cache
occupancy of a process. resctrl selftest suite has a unit test to test CMT
for LLC but the test is named as CQM (Cache Quality Monitoring).
Furthermore, the unit test source file is named as cqm_test.c and several
functions, variables, comments, preprocessors and statements widely use
"cqm" as either suffix or prefix. This rampant misusage of CQM for CMT
might confuse someone who is newly looking at resctrl selftests because
this feature is named CMT in the Intel Software Developer's Manual.
Hence, rename all the occurrences (unit test source file name, functions,
variables, comments and preprocessors) of cqm with cmt.
[1] Please see Intel SDM, Volume 3, chapter 17 and section 18 for more
information on CMT: https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html
Suggested-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 02:22:41 +00:00
strncmp ( resctrl_val , CMT_STR , sizeof ( CMT_STR ) ) )
2020-01-16 13:32:35 -08:00
return - ENOENT ;
if ( ! schemata ) {
2021-03-17 02:22:42 +00:00
ksft_print_msg ( " Skipping empty schemata update \n " ) ;
2020-01-16 13:32:35 -08:00
return - 1 ;
}
if ( get_resource_id ( cpu_no , & resource_id ) < 0 ) {
sprintf ( reason , " Failed to get resource id " ) ;
ret = - 1 ;
goto out ;
}
if ( strlen ( ctrlgrp ) ! = 0 )
sprintf ( controlgroup , " %s/%s/schemata " , RESCTRL_PATH , ctrlgrp ) ;
else
sprintf ( controlgroup , " %s/schemata " , RESCTRL_PATH ) ;
2021-03-17 02:22:38 +00:00
if ( ! strncmp ( resctrl_val , CAT_STR , sizeof ( CAT_STR ) ) | |
selftests/resctrl: Rename CQM test as CMT test
CMT (Cache Monitoring Technology) [1] is a H/W feature that reports cache
occupancy of a process. resctrl selftest suite has a unit test to test CMT
for LLC but the test is named as CQM (Cache Quality Monitoring).
Furthermore, the unit test source file is named as cqm_test.c and several
functions, variables, comments, preprocessors and statements widely use
"cqm" as either suffix or prefix. This rampant misusage of CQM for CMT
might confuse someone who is newly looking at resctrl selftests because
this feature is named CMT in the Intel Software Developer's Manual.
Hence, rename all the occurrences (unit test source file name, functions,
variables, comments and preprocessors) of cqm with cmt.
[1] Please see Intel SDM, Volume 3, chapter 17 and section 18 for more
information on CMT: https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html
Suggested-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 02:22:41 +00:00
! strncmp ( resctrl_val , CMT_STR , sizeof ( CMT_STR ) ) )
2020-01-16 13:32:41 -08:00
sprintf ( schema , " %s%d%c%s " , " L3: " , resource_id , ' = ' , schemata ) ;
2021-03-17 02:22:38 +00:00
if ( ! strncmp ( resctrl_val , MBA_STR , sizeof ( MBA_STR ) ) )
2020-01-16 13:32:41 -08:00
sprintf ( schema , " %s%d%c%s " , " MB: " , resource_id , ' = ' , schemata ) ;
2020-01-16 13:32:35 -08:00
fp = fopen ( controlgroup , " w " ) ;
if ( ! fp ) {
sprintf ( reason , " Failed to open control group " ) ;
ret = - 1 ;
goto out ;
}
if ( fprintf ( fp , " %s \n " , schema ) < 0 ) {
sprintf ( reason , " Failed to write schemata in control group " ) ;
fclose ( fp ) ;
ret = - 1 ;
goto out ;
}
fclose ( fp ) ;
out :
2021-03-17 02:22:42 +00:00
ksft_print_msg ( " Write schema \" %s \" to resctrl FS%s%s \n " ,
schema , ret ? " # " : " " ,
ret ? reason : " " ) ;
2020-01-16 13:32:35 -08:00
return ret ;
}
2020-01-16 13:32:39 -08:00
bool check_resctrlfs_support ( void )
{
FILE * inf = fopen ( " /proc/filesystems " , " r " ) ;
DIR * dp ;
char * res ;
bool ret = false ;
if ( ! inf )
return false ;
res = fgrep ( inf , " nodev \t resctrl \n " ) ;
if ( res ) {
ret = true ;
free ( res ) ;
}
fclose ( inf ) ;
2021-04-07 19:57:28 +00:00
ksft_print_msg ( " %s Check kernel supports resctrl filesystem \n " ,
2021-03-17 02:22:42 +00:00
ret ? " Pass: " : " Fail: " ) ;
2020-01-16 13:32:39 -08:00
2021-03-17 02:22:46 +00:00
if ( ! ret )
return ret ;
2020-01-16 13:32:39 -08:00
dp = opendir ( RESCTRL_PATH ) ;
2021-04-07 19:57:28 +00:00
ksft_print_msg ( " %s Check resctrl mountpoint \" %s \" exists \n " ,
2021-03-17 02:22:42 +00:00
dp ? " Pass: " : " Fail: " , RESCTRL_PATH ) ;
2020-01-16 13:32:39 -08:00
if ( dp )
closedir ( dp ) ;
2021-03-17 02:22:42 +00:00
ksft_print_msg ( " resctrl filesystem %s mounted \n " ,
find_resctrl_mount ( NULL ) ? " not " : " is " ) ;
2020-01-16 13:32:39 -08:00
return ret ;
}
2020-01-16 13:32:35 -08:00
char * fgrep ( FILE * inf , const char * str )
{
char line [ 256 ] ;
int slen = strlen ( str ) ;
while ( ! feof ( inf ) ) {
if ( ! fgets ( line , 256 , inf ) )
break ;
if ( strncmp ( line , str , slen ) )
continue ;
return strdup ( line ) ;
}
return NULL ;
}
/*
* validate_resctrl_feature_request - Check if requested feature is valid .
* @ resctrl_val : Requested feature
*
selftests/resctrl: Use resctrl/info for feature detection
Resctrl test suite before running any unit test (like cmt, cat, mbm and
mba) should first check if the feature is enabled (by kernel and not just
supported by H/W) on the platform or not.
validate_resctrl_feature_request() is supposed to do that. This function
intends to grep for relevant flags in /proc/cpuinfo but there are several
issues here
1. validate_resctrl_feature_request() calls fgrep() to get flags from
/proc/cpuinfo. But, fgrep() can only return a string with maximum of 255
characters and hence the complete cpu flags are never returned.
2. The substring search logic is also busted. If strstr() finds requested
resctrl feature in the cpu flags, it returns pointer to the first
occurrence. But, the logic negates the return value of strstr() and
hence validate_resctrl_feature_request() returns false if the feature is
present in the cpu flags and returns true if the feature is not present.
3. validate_resctrl_feature_request() checks if a resctrl feature is
reported in /proc/cpuinfo flags or not. Having a cpu flag means that the
H/W supports the feature, but it doesn't mean that the kernel enabled
it. A user could selectively enable only a subset of resctrl features
using kernel command line arguments. Hence, /proc/cpuinfo isn't a
reliable source to check if a feature is enabled or not.
The 3rd issue being the major one and fixing it requires changing the way
validate_resctrl_feature_request() works. Since, /proc/cpuinfo isn't the
right place to check if a resctrl feature is enabled or not, a more
appropriate place is /sys/fs/resctrl/info directory. Change
validate_resctrl_feature_request() such that,
1. For cat, check if /sys/fs/resctrl/info/L3 directory is present or not
2. For mba, check if /sys/fs/resctrl/info/MB directory is present or not
3. For cmt, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has llc_occupancy
4. For mbm, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has
mbm_<total/local>_bytes
Please note that only L3_CAT, L3_CMT, MBA and MBM are supported. CDP and L2
variants can be added later.
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 02:22:47 +00:00
* Return : True if the feature is supported , else false
2020-01-16 13:32:35 -08:00
*/
selftests/resctrl: Use resctrl/info for feature detection
Resctrl test suite before running any unit test (like cmt, cat, mbm and
mba) should first check if the feature is enabled (by kernel and not just
supported by H/W) on the platform or not.
validate_resctrl_feature_request() is supposed to do that. This function
intends to grep for relevant flags in /proc/cpuinfo but there are several
issues here
1. validate_resctrl_feature_request() calls fgrep() to get flags from
/proc/cpuinfo. But, fgrep() can only return a string with maximum of 255
characters and hence the complete cpu flags are never returned.
2. The substring search logic is also busted. If strstr() finds requested
resctrl feature in the cpu flags, it returns pointer to the first
occurrence. But, the logic negates the return value of strstr() and
hence validate_resctrl_feature_request() returns false if the feature is
present in the cpu flags and returns true if the feature is not present.
3. validate_resctrl_feature_request() checks if a resctrl feature is
reported in /proc/cpuinfo flags or not. Having a cpu flag means that the
H/W supports the feature, but it doesn't mean that the kernel enabled
it. A user could selectively enable only a subset of resctrl features
using kernel command line arguments. Hence, /proc/cpuinfo isn't a
reliable source to check if a feature is enabled or not.
The 3rd issue being the major one and fixing it requires changing the way
validate_resctrl_feature_request() works. Since, /proc/cpuinfo isn't the
right place to check if a resctrl feature is enabled or not, a more
appropriate place is /sys/fs/resctrl/info directory. Change
validate_resctrl_feature_request() such that,
1. For cat, check if /sys/fs/resctrl/info/L3 directory is present or not
2. For mba, check if /sys/fs/resctrl/info/MB directory is present or not
3. For cmt, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has llc_occupancy
4. For mbm, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has
mbm_<total/local>_bytes
Please note that only L3_CAT, L3_CMT, MBA and MBM are supported. CDP and L2
variants can be added later.
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 02:22:47 +00:00
bool validate_resctrl_feature_request ( const char * resctrl_val )
2020-01-16 13:32:35 -08:00
{
selftests/resctrl: Use resctrl/info for feature detection
Resctrl test suite before running any unit test (like cmt, cat, mbm and
mba) should first check if the feature is enabled (by kernel and not just
supported by H/W) on the platform or not.
validate_resctrl_feature_request() is supposed to do that. This function
intends to grep for relevant flags in /proc/cpuinfo but there are several
issues here
1. validate_resctrl_feature_request() calls fgrep() to get flags from
/proc/cpuinfo. But, fgrep() can only return a string with maximum of 255
characters and hence the complete cpu flags are never returned.
2. The substring search logic is also busted. If strstr() finds requested
resctrl feature in the cpu flags, it returns pointer to the first
occurrence. But, the logic negates the return value of strstr() and
hence validate_resctrl_feature_request() returns false if the feature is
present in the cpu flags and returns true if the feature is not present.
3. validate_resctrl_feature_request() checks if a resctrl feature is
reported in /proc/cpuinfo flags or not. Having a cpu flag means that the
H/W supports the feature, but it doesn't mean that the kernel enabled
it. A user could selectively enable only a subset of resctrl features
using kernel command line arguments. Hence, /proc/cpuinfo isn't a
reliable source to check if a feature is enabled or not.
The 3rd issue being the major one and fixing it requires changing the way
validate_resctrl_feature_request() works. Since, /proc/cpuinfo isn't the
right place to check if a resctrl feature is enabled or not, a more
appropriate place is /sys/fs/resctrl/info directory. Change
validate_resctrl_feature_request() such that,
1. For cat, check if /sys/fs/resctrl/info/L3 directory is present or not
2. For mba, check if /sys/fs/resctrl/info/MB directory is present or not
3. For cmt, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has llc_occupancy
4. For mbm, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has
mbm_<total/local>_bytes
Please note that only L3_CAT, L3_CMT, MBA and MBM are supported. CDP and L2
variants can be added later.
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 02:22:47 +00:00
struct stat statbuf ;
2020-01-16 13:32:35 -08:00
bool found = false ;
char * res ;
selftests/resctrl: Use resctrl/info for feature detection
Resctrl test suite before running any unit test (like cmt, cat, mbm and
mba) should first check if the feature is enabled (by kernel and not just
supported by H/W) on the platform or not.
validate_resctrl_feature_request() is supposed to do that. This function
intends to grep for relevant flags in /proc/cpuinfo but there are several
issues here
1. validate_resctrl_feature_request() calls fgrep() to get flags from
/proc/cpuinfo. But, fgrep() can only return a string with maximum of 255
characters and hence the complete cpu flags are never returned.
2. The substring search logic is also busted. If strstr() finds requested
resctrl feature in the cpu flags, it returns pointer to the first
occurrence. But, the logic negates the return value of strstr() and
hence validate_resctrl_feature_request() returns false if the feature is
present in the cpu flags and returns true if the feature is not present.
3. validate_resctrl_feature_request() checks if a resctrl feature is
reported in /proc/cpuinfo flags or not. Having a cpu flag means that the
H/W supports the feature, but it doesn't mean that the kernel enabled
it. A user could selectively enable only a subset of resctrl features
using kernel command line arguments. Hence, /proc/cpuinfo isn't a
reliable source to check if a feature is enabled or not.
The 3rd issue being the major one and fixing it requires changing the way
validate_resctrl_feature_request() works. Since, /proc/cpuinfo isn't the
right place to check if a resctrl feature is enabled or not, a more
appropriate place is /sys/fs/resctrl/info directory. Change
validate_resctrl_feature_request() such that,
1. For cat, check if /sys/fs/resctrl/info/L3 directory is present or not
2. For mba, check if /sys/fs/resctrl/info/MB directory is present or not
3. For cmt, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has llc_occupancy
4. For mbm, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has
mbm_<total/local>_bytes
Please note that only L3_CAT, L3_CMT, MBA and MBM are supported. CDP and L2
variants can be added later.
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 02:22:47 +00:00
FILE * inf ;
2020-01-16 13:32:35 -08:00
selftests/resctrl: Use resctrl/info for feature detection
Resctrl test suite before running any unit test (like cmt, cat, mbm and
mba) should first check if the feature is enabled (by kernel and not just
supported by H/W) on the platform or not.
validate_resctrl_feature_request() is supposed to do that. This function
intends to grep for relevant flags in /proc/cpuinfo but there are several
issues here
1. validate_resctrl_feature_request() calls fgrep() to get flags from
/proc/cpuinfo. But, fgrep() can only return a string with maximum of 255
characters and hence the complete cpu flags are never returned.
2. The substring search logic is also busted. If strstr() finds requested
resctrl feature in the cpu flags, it returns pointer to the first
occurrence. But, the logic negates the return value of strstr() and
hence validate_resctrl_feature_request() returns false if the feature is
present in the cpu flags and returns true if the feature is not present.
3. validate_resctrl_feature_request() checks if a resctrl feature is
reported in /proc/cpuinfo flags or not. Having a cpu flag means that the
H/W supports the feature, but it doesn't mean that the kernel enabled
it. A user could selectively enable only a subset of resctrl features
using kernel command line arguments. Hence, /proc/cpuinfo isn't a
reliable source to check if a feature is enabled or not.
The 3rd issue being the major one and fixing it requires changing the way
validate_resctrl_feature_request() works. Since, /proc/cpuinfo isn't the
right place to check if a resctrl feature is enabled or not, a more
appropriate place is /sys/fs/resctrl/info directory. Change
validate_resctrl_feature_request() such that,
1. For cat, check if /sys/fs/resctrl/info/L3 directory is present or not
2. For mba, check if /sys/fs/resctrl/info/MB directory is present or not
3. For cmt, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has llc_occupancy
4. For mbm, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has
mbm_<total/local>_bytes
Please note that only L3_CAT, L3_CMT, MBA and MBM are supported. CDP and L2
variants can be added later.
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 02:22:47 +00:00
if ( ! resctrl_val )
2020-01-16 13:32:35 -08:00
return false ;
selftests/resctrl: Use resctrl/info for feature detection
Resctrl test suite before running any unit test (like cmt, cat, mbm and
mba) should first check if the feature is enabled (by kernel and not just
supported by H/W) on the platform or not.
validate_resctrl_feature_request() is supposed to do that. This function
intends to grep for relevant flags in /proc/cpuinfo but there are several
issues here
1. validate_resctrl_feature_request() calls fgrep() to get flags from
/proc/cpuinfo. But, fgrep() can only return a string with maximum of 255
characters and hence the complete cpu flags are never returned.
2. The substring search logic is also busted. If strstr() finds requested
resctrl feature in the cpu flags, it returns pointer to the first
occurrence. But, the logic negates the return value of strstr() and
hence validate_resctrl_feature_request() returns false if the feature is
present in the cpu flags and returns true if the feature is not present.
3. validate_resctrl_feature_request() checks if a resctrl feature is
reported in /proc/cpuinfo flags or not. Having a cpu flag means that the
H/W supports the feature, but it doesn't mean that the kernel enabled
it. A user could selectively enable only a subset of resctrl features
using kernel command line arguments. Hence, /proc/cpuinfo isn't a
reliable source to check if a feature is enabled or not.
The 3rd issue being the major one and fixing it requires changing the way
validate_resctrl_feature_request() works. Since, /proc/cpuinfo isn't the
right place to check if a resctrl feature is enabled or not, a more
appropriate place is /sys/fs/resctrl/info directory. Change
validate_resctrl_feature_request() such that,
1. For cat, check if /sys/fs/resctrl/info/L3 directory is present or not
2. For mba, check if /sys/fs/resctrl/info/MB directory is present or not
3. For cmt, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has llc_occupancy
4. For mbm, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has
mbm_<total/local>_bytes
Please note that only L3_CAT, L3_CMT, MBA and MBM are supported. CDP and L2
variants can be added later.
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 02:22:47 +00:00
if ( remount_resctrlfs ( false ) )
return false ;
2020-01-16 13:32:35 -08:00
selftests/resctrl: Use resctrl/info for feature detection
Resctrl test suite before running any unit test (like cmt, cat, mbm and
mba) should first check if the feature is enabled (by kernel and not just
supported by H/W) on the platform or not.
validate_resctrl_feature_request() is supposed to do that. This function
intends to grep for relevant flags in /proc/cpuinfo but there are several
issues here
1. validate_resctrl_feature_request() calls fgrep() to get flags from
/proc/cpuinfo. But, fgrep() can only return a string with maximum of 255
characters and hence the complete cpu flags are never returned.
2. The substring search logic is also busted. If strstr() finds requested
resctrl feature in the cpu flags, it returns pointer to the first
occurrence. But, the logic negates the return value of strstr() and
hence validate_resctrl_feature_request() returns false if the feature is
present in the cpu flags and returns true if the feature is not present.
3. validate_resctrl_feature_request() checks if a resctrl feature is
reported in /proc/cpuinfo flags or not. Having a cpu flag means that the
H/W supports the feature, but it doesn't mean that the kernel enabled
it. A user could selectively enable only a subset of resctrl features
using kernel command line arguments. Hence, /proc/cpuinfo isn't a
reliable source to check if a feature is enabled or not.
The 3rd issue being the major one and fixing it requires changing the way
validate_resctrl_feature_request() works. Since, /proc/cpuinfo isn't the
right place to check if a resctrl feature is enabled or not, a more
appropriate place is /sys/fs/resctrl/info directory. Change
validate_resctrl_feature_request() such that,
1. For cat, check if /sys/fs/resctrl/info/L3 directory is present or not
2. For mba, check if /sys/fs/resctrl/info/MB directory is present or not
3. For cmt, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has llc_occupancy
4. For mbm, check if /sys/fs/resctrl/info/L3_MON directory is present and
check if /sys/fs/resctrl/info/L3_MON/mon_features has
mbm_<total/local>_bytes
Please note that only L3_CAT, L3_CMT, MBA and MBM are supported. CDP and L2
variants can be added later.
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 02:22:47 +00:00
if ( ! strncmp ( resctrl_val , CAT_STR , sizeof ( CAT_STR ) ) ) {
if ( ! stat ( L3_PATH , & statbuf ) )
return true ;
} else if ( ! strncmp ( resctrl_val , MBA_STR , sizeof ( MBA_STR ) ) ) {
if ( ! stat ( MB_PATH , & statbuf ) )
return true ;
} else if ( ! strncmp ( resctrl_val , MBM_STR , sizeof ( MBM_STR ) ) | |
! strncmp ( resctrl_val , CMT_STR , sizeof ( CMT_STR ) ) ) {
if ( ! stat ( L3_MON_PATH , & statbuf ) ) {
inf = fopen ( L3_MON_FEATURES_PATH , " r " ) ;
if ( ! inf )
return false ;
if ( ! strncmp ( resctrl_val , CMT_STR , sizeof ( CMT_STR ) ) ) {
res = fgrep ( inf , " llc_occupancy " ) ;
if ( res ) {
found = true ;
free ( res ) ;
}
}
if ( ! strncmp ( resctrl_val , MBM_STR , sizeof ( MBM_STR ) ) ) {
res = fgrep ( inf , " mbm_total_bytes " ) ;
if ( res ) {
free ( res ) ;
res = fgrep ( inf , " mbm_local_bytes " ) ;
if ( res ) {
found = true ;
free ( res ) ;
}
}
}
fclose ( inf ) ;
}
2020-01-16 13:32:35 -08:00
}
return found ;
}
2020-01-16 13:32:39 -08:00
int filter_dmesg ( void )
{
char line [ 1024 ] ;
FILE * fp ;
int pipefds [ 2 ] ;
pid_t pid ;
int ret ;
ret = pipe ( pipefds ) ;
if ( ret ) {
perror ( " pipe " ) ;
return ret ;
}
pid = fork ( ) ;
if ( pid = = 0 ) {
close ( pipefds [ 0 ] ) ;
dup2 ( pipefds [ 1 ] , STDOUT_FILENO ) ;
execlp ( " dmesg " , " dmesg " , NULL ) ;
perror ( " executing dmesg " ) ;
exit ( 1 ) ;
}
close ( pipefds [ 1 ] ) ;
fp = fdopen ( pipefds [ 0 ] , " r " ) ;
if ( ! fp ) {
perror ( " fdopen(pipe) " ) ;
kill ( pid , SIGTERM ) ;
return - 1 ;
}
while ( fgets ( line , 1024 , fp ) ) {
if ( strstr ( line , " intel_rdt: " ) )
2021-03-17 02:22:42 +00:00
ksft_print_msg ( " dmesg: %s " , line ) ;
2020-01-16 13:32:39 -08:00
if ( strstr ( line , " resctrl: " ) )
2021-03-17 02:22:42 +00:00
ksft_print_msg ( " dmesg: %s " , line ) ;
2020-01-16 13:32:39 -08:00
}
fclose ( fp ) ;
waitpid ( pid , NULL , 0 ) ;
return 0 ;
}
2020-01-16 13:32:35 -08:00
int validate_bw_report_request ( char * bw_report )
{
if ( strcmp ( bw_report , " reads " ) = = 0 )
return 0 ;
if ( strcmp ( bw_report , " writes " ) = = 0 )
return 0 ;
if ( strcmp ( bw_report , " nt-writes " ) = = 0 ) {
strcpy ( bw_report , " writes " ) ;
return 0 ;
}
if ( strcmp ( bw_report , " total " ) = = 0 )
return 0 ;
fprintf ( stderr , " Requested iMC B/W report type unavailable \n " ) ;
return - 1 ;
}
int perf_event_open ( struct perf_event_attr * hw_event , pid_t pid , int cpu ,
int group_fd , unsigned long flags )
{
int ret ;
ret = syscall ( __NR_perf_event_open , hw_event , pid , cpu ,
group_fd , flags ) ;
return ret ;
}
2020-01-16 13:32:41 -08:00
unsigned int count_bits ( unsigned long n )
{
unsigned int count = 0 ;
while ( n ) {
count + = n & 1 ;
n > > = 1 ;
}
return count ;
}