1591a6e85SSai Praneeth Prakhya // SPDX-License-Identifier: GPL-2.0 2591a6e85SSai Praneeth Prakhya /* 3591a6e85SSai Praneeth Prakhya * Basic resctrl file system operations 4591a6e85SSai Praneeth Prakhya * 5591a6e85SSai Praneeth Prakhya * Copyright (C) 2018 Intel Corporation 6591a6e85SSai Praneeth Prakhya * 7591a6e85SSai Praneeth Prakhya * Authors: 8591a6e85SSai Praneeth Prakhya * Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>, 9591a6e85SSai Praneeth Prakhya * Fenghua Yu <fenghua.yu@intel.com> 10591a6e85SSai Praneeth Prakhya */ 11591a6e85SSai Praneeth Prakhya #include "resctrl.h" 12591a6e85SSai Praneeth Prakhya 13591a6e85SSai Praneeth Prakhya static int find_resctrl_mount(char *buffer) 14591a6e85SSai Praneeth Prakhya { 15591a6e85SSai Praneeth Prakhya FILE *mounts; 16591a6e85SSai Praneeth Prakhya char line[256], *fs, *mntpoint; 17591a6e85SSai Praneeth Prakhya 18591a6e85SSai Praneeth Prakhya mounts = fopen("/proc/mounts", "r"); 19591a6e85SSai Praneeth Prakhya if (!mounts) { 20591a6e85SSai Praneeth Prakhya perror("/proc/mounts"); 21591a6e85SSai Praneeth Prakhya return -ENXIO; 22591a6e85SSai Praneeth Prakhya } 23591a6e85SSai Praneeth Prakhya while (!feof(mounts)) { 24591a6e85SSai Praneeth Prakhya if (!fgets(line, 256, mounts)) 25591a6e85SSai Praneeth Prakhya break; 26591a6e85SSai Praneeth Prakhya fs = strtok(line, " \t"); 27591a6e85SSai Praneeth Prakhya if (!fs) 28591a6e85SSai Praneeth Prakhya continue; 29591a6e85SSai Praneeth Prakhya mntpoint = strtok(NULL, " \t"); 30591a6e85SSai Praneeth Prakhya if (!mntpoint) 31591a6e85SSai Praneeth Prakhya continue; 32591a6e85SSai Praneeth Prakhya fs = strtok(NULL, " \t"); 33591a6e85SSai Praneeth Prakhya if (!fs) 34591a6e85SSai Praneeth Prakhya continue; 35591a6e85SSai Praneeth Prakhya if (strcmp(fs, "resctrl")) 36591a6e85SSai Praneeth Prakhya continue; 37591a6e85SSai Praneeth Prakhya 38591a6e85SSai Praneeth Prakhya fclose(mounts); 39591a6e85SSai Praneeth Prakhya if (buffer) 40591a6e85SSai Praneeth Prakhya strncpy(buffer, mntpoint, 256); 41591a6e85SSai Praneeth Prakhya 42591a6e85SSai Praneeth Prakhya return 0; 43591a6e85SSai Praneeth Prakhya } 44591a6e85SSai Praneeth Prakhya 45591a6e85SSai Praneeth Prakhya fclose(mounts); 46591a6e85SSai Praneeth Prakhya 47591a6e85SSai Praneeth Prakhya return -ENOENT; 48591a6e85SSai Praneeth Prakhya } 49591a6e85SSai Praneeth Prakhya 50591a6e85SSai Praneeth Prakhya /* 51591a6e85SSai Praneeth Prakhya * remount_resctrlfs - Remount resctrl FS at /sys/fs/resctrl 52591a6e85SSai Praneeth Prakhya * @mum_resctrlfs: Should the resctrl FS be remounted? 53591a6e85SSai Praneeth Prakhya * 54591a6e85SSai Praneeth Prakhya * If not mounted, mount it. 55591a6e85SSai Praneeth Prakhya * If mounted and mum_resctrlfs then remount resctrl FS. 56591a6e85SSai Praneeth Prakhya * If mounted and !mum_resctrlfs then noop 57591a6e85SSai Praneeth Prakhya * 58591a6e85SSai Praneeth Prakhya * Return: 0 on success, non-zero on failure 59591a6e85SSai Praneeth Prakhya */ 60591a6e85SSai Praneeth Prakhya int remount_resctrlfs(bool mum_resctrlfs) 61591a6e85SSai Praneeth Prakhya { 62591a6e85SSai Praneeth Prakhya char mountpoint[256]; 63591a6e85SSai Praneeth Prakhya int ret; 64591a6e85SSai Praneeth Prakhya 65591a6e85SSai Praneeth Prakhya ret = find_resctrl_mount(mountpoint); 66591a6e85SSai Praneeth Prakhya if (ret) 67591a6e85SSai Praneeth Prakhya strcpy(mountpoint, RESCTRL_PATH); 68591a6e85SSai Praneeth Prakhya 69ca2f4214SFenghua Yu if (!ret && mum_resctrlfs && umount(mountpoint)) 70ca2f4214SFenghua Yu ksft_print_msg("Fail: unmounting \"%s\"\n", mountpoint); 71591a6e85SSai Praneeth Prakhya 72591a6e85SSai Praneeth Prakhya if (!ret && !mum_resctrlfs) 73591a6e85SSai Praneeth Prakhya return 0; 74591a6e85SSai Praneeth Prakhya 75ca2f4214SFenghua Yu ksft_print_msg("Mounting resctrl to \"%s\"\n", RESCTRL_PATH); 76591a6e85SSai Praneeth Prakhya ret = mount("resctrl", RESCTRL_PATH, "resctrl", 0, NULL); 77591a6e85SSai Praneeth Prakhya if (ret) 78591a6e85SSai Praneeth Prakhya perror("# mount"); 79591a6e85SSai Praneeth Prakhya 80591a6e85SSai Praneeth Prakhya return ret; 81591a6e85SSai Praneeth Prakhya } 82591a6e85SSai Praneeth Prakhya 83591a6e85SSai Praneeth Prakhya int umount_resctrlfs(void) 84591a6e85SSai Praneeth Prakhya { 85ede13008SIlpo Järvinen char mountpoint[256]; 86ede13008SIlpo Järvinen int ret; 874e5cb354SFenghua Yu 88ede13008SIlpo Järvinen ret = find_resctrl_mount(mountpoint); 89ede13008SIlpo Järvinen if (ret == -ENOENT) 90ede13008SIlpo Järvinen return 0; 91ede13008SIlpo Järvinen if (ret) 92ede13008SIlpo Järvinen return ret; 93ede13008SIlpo Järvinen 94ede13008SIlpo Järvinen if (umount(mountpoint)) { 95591a6e85SSai Praneeth Prakhya perror("# Unable to umount resctrl"); 96591a6e85SSai Praneeth Prakhya 97591a6e85SSai Praneeth Prakhya return errno; 98591a6e85SSai Praneeth Prakhya } 99591a6e85SSai Praneeth Prakhya 100591a6e85SSai Praneeth Prakhya return 0; 101591a6e85SSai Praneeth Prakhya } 102591a6e85SSai Praneeth Prakhya 103591a6e85SSai Praneeth Prakhya /* 104591a6e85SSai Praneeth Prakhya * get_resource_id - Get socket number/l3 id for a specified CPU 105591a6e85SSai Praneeth Prakhya * @cpu_no: CPU number 106591a6e85SSai Praneeth Prakhya * @resource_id: Socket number or l3_id 107591a6e85SSai Praneeth Prakhya * 108591a6e85SSai Praneeth Prakhya * Return: >= 0 on success, < 0 on failure. 109591a6e85SSai Praneeth Prakhya */ 110591a6e85SSai Praneeth Prakhya int get_resource_id(int cpu_no, int *resource_id) 111591a6e85SSai Praneeth Prakhya { 112591a6e85SSai Praneeth Prakhya char phys_pkg_path[1024]; 113591a6e85SSai Praneeth Prakhya FILE *fp; 114591a6e85SSai Praneeth Prakhya 1156220f69eSShaopeng Tan if (get_vendor() == ARCH_AMD) 116c0327e1dSBabu Moger sprintf(phys_pkg_path, "%s%d/cache/index3/id", 117c0327e1dSBabu Moger PHYS_ID_PATH, cpu_no); 118c0327e1dSBabu Moger else 119591a6e85SSai Praneeth Prakhya sprintf(phys_pkg_path, "%s%d/topology/physical_package_id", 120591a6e85SSai Praneeth Prakhya PHYS_ID_PATH, cpu_no); 121c0327e1dSBabu Moger 122591a6e85SSai Praneeth Prakhya fp = fopen(phys_pkg_path, "r"); 123591a6e85SSai Praneeth Prakhya if (!fp) { 124591a6e85SSai Praneeth Prakhya perror("Failed to open physical_package_id"); 125591a6e85SSai Praneeth Prakhya 126591a6e85SSai Praneeth Prakhya return -1; 127591a6e85SSai Praneeth Prakhya } 128591a6e85SSai Praneeth Prakhya if (fscanf(fp, "%d", resource_id) <= 0) { 129591a6e85SSai Praneeth Prakhya perror("Could not get socket number or l3 id"); 130591a6e85SSai Praneeth Prakhya fclose(fp); 131591a6e85SSai Praneeth Prakhya 132591a6e85SSai Praneeth Prakhya return -1; 133591a6e85SSai Praneeth Prakhya } 134591a6e85SSai Praneeth Prakhya fclose(fp); 135591a6e85SSai Praneeth Prakhya 136591a6e85SSai Praneeth Prakhya return 0; 137591a6e85SSai Praneeth Prakhya } 138591a6e85SSai Praneeth Prakhya 139591a6e85SSai Praneeth Prakhya /* 14078941183SFenghua Yu * get_cache_size - Get cache size for a specified CPU 14178941183SFenghua Yu * @cpu_no: CPU number 14278941183SFenghua Yu * @cache_type: Cache level L2/L3 14378941183SFenghua Yu * @cache_size: pointer to cache_size 14478941183SFenghua Yu * 14578941183SFenghua Yu * Return: = 0 on success, < 0 on failure. 14678941183SFenghua Yu */ 14778941183SFenghua Yu int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size) 14878941183SFenghua Yu { 14978941183SFenghua Yu char cache_path[1024], cache_str[64]; 15078941183SFenghua Yu int length, i, cache_num; 15178941183SFenghua Yu FILE *fp; 15278941183SFenghua Yu 15378941183SFenghua Yu if (!strcmp(cache_type, "L3")) { 15478941183SFenghua Yu cache_num = 3; 15578941183SFenghua Yu } else if (!strcmp(cache_type, "L2")) { 15678941183SFenghua Yu cache_num = 2; 15778941183SFenghua Yu } else { 15878941183SFenghua Yu perror("Invalid cache level"); 15978941183SFenghua Yu return -1; 16078941183SFenghua Yu } 16178941183SFenghua Yu 16278941183SFenghua Yu sprintf(cache_path, "/sys/bus/cpu/devices/cpu%d/cache/index%d/size", 16378941183SFenghua Yu cpu_no, cache_num); 16478941183SFenghua Yu fp = fopen(cache_path, "r"); 16578941183SFenghua Yu if (!fp) { 16678941183SFenghua Yu perror("Failed to open cache size"); 16778941183SFenghua Yu 16878941183SFenghua Yu return -1; 16978941183SFenghua Yu } 17078941183SFenghua Yu if (fscanf(fp, "%s", cache_str) <= 0) { 17178941183SFenghua Yu perror("Could not get cache_size"); 17278941183SFenghua Yu fclose(fp); 17378941183SFenghua Yu 17478941183SFenghua Yu return -1; 17578941183SFenghua Yu } 17678941183SFenghua Yu fclose(fp); 17778941183SFenghua Yu 17878941183SFenghua Yu length = (int)strlen(cache_str); 17978941183SFenghua Yu 18078941183SFenghua Yu *cache_size = 0; 18178941183SFenghua Yu 18278941183SFenghua Yu for (i = 0; i < length; i++) { 18378941183SFenghua Yu if ((cache_str[i] >= '0') && (cache_str[i] <= '9')) 18478941183SFenghua Yu 18578941183SFenghua Yu *cache_size = *cache_size * 10 + (cache_str[i] - '0'); 18678941183SFenghua Yu 18778941183SFenghua Yu else if (cache_str[i] == 'K') 18878941183SFenghua Yu 18978941183SFenghua Yu *cache_size = *cache_size * 1024; 19078941183SFenghua Yu 19178941183SFenghua Yu else if (cache_str[i] == 'M') 19278941183SFenghua Yu 19378941183SFenghua Yu *cache_size = *cache_size * 1024 * 1024; 19478941183SFenghua Yu 19578941183SFenghua Yu else 19678941183SFenghua Yu break; 19778941183SFenghua Yu } 19878941183SFenghua Yu 19978941183SFenghua Yu return 0; 20078941183SFenghua Yu } 20178941183SFenghua Yu 20278941183SFenghua Yu #define CORE_SIBLINGS_PATH "/sys/bus/cpu/devices/cpu" 20378941183SFenghua Yu 20478941183SFenghua Yu /* 20578941183SFenghua Yu * get_cbm_mask - Get cbm mask for given cache 20678941183SFenghua Yu * @cache_type: Cache level L2/L3 2078236c51dSFenghua Yu * @cbm_mask: cbm_mask returned as a string 20878941183SFenghua Yu * 20978941183SFenghua Yu * Return: = 0 on success, < 0 on failure. 21078941183SFenghua Yu */ 2118236c51dSFenghua Yu int get_cbm_mask(char *cache_type, char *cbm_mask) 21278941183SFenghua Yu { 21378941183SFenghua Yu char cbm_mask_path[1024]; 21478941183SFenghua Yu FILE *fp; 21578941183SFenghua Yu 2168236c51dSFenghua Yu if (!cbm_mask) 2178236c51dSFenghua Yu return -1; 2188236c51dSFenghua Yu 219e48c3230SFenghua Yu sprintf(cbm_mask_path, "%s/%s/cbm_mask", INFO_PATH, cache_type); 22078941183SFenghua Yu 22178941183SFenghua Yu fp = fopen(cbm_mask_path, "r"); 22278941183SFenghua Yu if (!fp) { 22378941183SFenghua Yu perror("Failed to open cache level"); 22478941183SFenghua Yu 22578941183SFenghua Yu return -1; 22678941183SFenghua Yu } 22778941183SFenghua Yu if (fscanf(fp, "%s", cbm_mask) <= 0) { 22878941183SFenghua Yu perror("Could not get max cbm_mask"); 22978941183SFenghua Yu fclose(fp); 23078941183SFenghua Yu 23178941183SFenghua Yu return -1; 23278941183SFenghua Yu } 23378941183SFenghua Yu fclose(fp); 23478941183SFenghua Yu 23578941183SFenghua Yu return 0; 23678941183SFenghua Yu } 23778941183SFenghua Yu 23878941183SFenghua Yu /* 23978941183SFenghua Yu * get_core_sibling - Get sibling core id from the same socket for given CPU 24078941183SFenghua Yu * @cpu_no: CPU number 24178941183SFenghua Yu * 24278941183SFenghua Yu * Return: > 0 on success, < 0 on failure. 24378941183SFenghua Yu */ 24478941183SFenghua Yu int get_core_sibling(int cpu_no) 24578941183SFenghua Yu { 24678941183SFenghua Yu char core_siblings_path[1024], cpu_list_str[64]; 24778941183SFenghua Yu int sibling_cpu_no = -1; 24878941183SFenghua Yu FILE *fp; 24978941183SFenghua Yu 25078941183SFenghua Yu sprintf(core_siblings_path, "%s%d/topology/core_siblings_list", 25178941183SFenghua Yu CORE_SIBLINGS_PATH, cpu_no); 25278941183SFenghua Yu 25378941183SFenghua Yu fp = fopen(core_siblings_path, "r"); 25478941183SFenghua Yu if (!fp) { 25578941183SFenghua Yu perror("Failed to open core siblings path"); 25678941183SFenghua Yu 25778941183SFenghua Yu return -1; 25878941183SFenghua Yu } 25978941183SFenghua Yu if (fscanf(fp, "%s", cpu_list_str) <= 0) { 26078941183SFenghua Yu perror("Could not get core_siblings list"); 26178941183SFenghua Yu fclose(fp); 26278941183SFenghua Yu 26378941183SFenghua Yu return -1; 26478941183SFenghua Yu } 26578941183SFenghua Yu fclose(fp); 26678941183SFenghua Yu 26778941183SFenghua Yu char *token = strtok(cpu_list_str, "-,"); 26878941183SFenghua Yu 26978941183SFenghua Yu while (token) { 27078941183SFenghua Yu sibling_cpu_no = atoi(token); 27178941183SFenghua Yu /* Skipping core 0 as we don't want to run test on core 0 */ 272f5f16ae4SReinette Chatre if (sibling_cpu_no != 0 && sibling_cpu_no != cpu_no) 27378941183SFenghua Yu break; 27478941183SFenghua Yu token = strtok(NULL, "-,"); 27578941183SFenghua Yu } 27678941183SFenghua Yu 27778941183SFenghua Yu return sibling_cpu_no; 27878941183SFenghua Yu } 27978941183SFenghua Yu 28078941183SFenghua Yu /* 281591a6e85SSai Praneeth Prakhya * taskset_benchmark - Taskset PID (i.e. benchmark) to a specified cpu 282591a6e85SSai Praneeth Prakhya * @bm_pid: PID that should be binded 283591a6e85SSai Praneeth Prakhya * @cpu_no: CPU number at which the PID would be binded 284591a6e85SSai Praneeth Prakhya * 285591a6e85SSai Praneeth Prakhya * Return: 0 on success, non-zero on failure 286591a6e85SSai Praneeth Prakhya */ 287591a6e85SSai Praneeth Prakhya int taskset_benchmark(pid_t bm_pid, int cpu_no) 288591a6e85SSai Praneeth Prakhya { 289591a6e85SSai Praneeth Prakhya cpu_set_t my_set; 290591a6e85SSai Praneeth Prakhya 291591a6e85SSai Praneeth Prakhya CPU_ZERO(&my_set); 292591a6e85SSai Praneeth Prakhya CPU_SET(cpu_no, &my_set); 293591a6e85SSai Praneeth Prakhya 294591a6e85SSai Praneeth Prakhya if (sched_setaffinity(bm_pid, sizeof(cpu_set_t), &my_set)) { 295591a6e85SSai Praneeth Prakhya perror("Unable to taskset benchmark"); 296591a6e85SSai Praneeth Prakhya 297591a6e85SSai Praneeth Prakhya return -1; 298591a6e85SSai Praneeth Prakhya } 299591a6e85SSai Praneeth Prakhya 300591a6e85SSai Praneeth Prakhya return 0; 301591a6e85SSai Praneeth Prakhya } 302591a6e85SSai Praneeth Prakhya 303591a6e85SSai Praneeth Prakhya /* 304591a6e85SSai Praneeth Prakhya * run_benchmark - Run a specified benchmark or fill_buf (default benchmark) 305591a6e85SSai Praneeth Prakhya * in specified signal. Direct benchmark stdio to /dev/null. 306591a6e85SSai Praneeth Prakhya * @signum: signal number 307591a6e85SSai Praneeth Prakhya * @info: signal info 308591a6e85SSai Praneeth Prakhya * @ucontext: user context in signal handling 309591a6e85SSai Praneeth Prakhya * 310591a6e85SSai Praneeth Prakhya * Return: void 311591a6e85SSai Praneeth Prakhya */ 312591a6e85SSai Praneeth Prakhya void run_benchmark(int signum, siginfo_t *info, void *ucontext) 313591a6e85SSai Praneeth Prakhya { 31478941183SFenghua Yu int operation, ret, malloc_and_init_memory, memflush; 31578941183SFenghua Yu unsigned long span, buffer_span; 316591a6e85SSai Praneeth Prakhya char **benchmark_cmd; 31778941183SFenghua Yu char resctrl_val[64]; 318591a6e85SSai Praneeth Prakhya FILE *fp; 319591a6e85SSai Praneeth Prakhya 320591a6e85SSai Praneeth Prakhya benchmark_cmd = info->si_ptr; 321591a6e85SSai Praneeth Prakhya 322591a6e85SSai Praneeth Prakhya /* 323591a6e85SSai Praneeth Prakhya * Direct stdio of child to /dev/null, so that only parent writes to 324591a6e85SSai Praneeth Prakhya * stdio (console) 325591a6e85SSai Praneeth Prakhya */ 326591a6e85SSai Praneeth Prakhya fp = freopen("/dev/null", "w", stdout); 327591a6e85SSai Praneeth Prakhya if (!fp) 328591a6e85SSai Praneeth Prakhya PARENT_EXIT("Unable to direct benchmark status to /dev/null"); 329591a6e85SSai Praneeth Prakhya 330591a6e85SSai Praneeth Prakhya if (strcmp(benchmark_cmd[0], "fill_buf") == 0) { 331591a6e85SSai Praneeth Prakhya /* Execute default fill_buf benchmark */ 332591a6e85SSai Praneeth Prakhya span = strtoul(benchmark_cmd[1], NULL, 10); 33378941183SFenghua Yu malloc_and_init_memory = atoi(benchmark_cmd[2]); 33478941183SFenghua Yu memflush = atoi(benchmark_cmd[3]); 335591a6e85SSai Praneeth Prakhya operation = atoi(benchmark_cmd[4]); 33678941183SFenghua Yu sprintf(resctrl_val, "%s", benchmark_cmd[5]); 33778941183SFenghua Yu 3382f320911SFenghua Yu if (strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) 33978941183SFenghua Yu buffer_span = span * MB; 34078941183SFenghua Yu else 34178941183SFenghua Yu buffer_span = span; 34278941183SFenghua Yu 34378941183SFenghua Yu if (run_fill_buf(buffer_span, malloc_and_init_memory, memflush, 34478941183SFenghua Yu operation, resctrl_val)) 345591a6e85SSai Praneeth Prakhya fprintf(stderr, "Error in running fill buffer\n"); 346591a6e85SSai Praneeth Prakhya } else { 347591a6e85SSai Praneeth Prakhya /* Execute specified benchmark */ 348591a6e85SSai Praneeth Prakhya ret = execvp(benchmark_cmd[0], benchmark_cmd); 349591a6e85SSai Praneeth Prakhya if (ret) 350591a6e85SSai Praneeth Prakhya perror("wrong\n"); 351591a6e85SSai Praneeth Prakhya } 352591a6e85SSai Praneeth Prakhya 353591a6e85SSai Praneeth Prakhya fclose(stdout); 354591a6e85SSai Praneeth Prakhya PARENT_EXIT("Unable to run specified benchmark"); 355591a6e85SSai Praneeth Prakhya } 356591a6e85SSai Praneeth Prakhya 357591a6e85SSai Praneeth Prakhya /* 358591a6e85SSai Praneeth Prakhya * create_grp - Create a group only if one doesn't exist 359591a6e85SSai Praneeth Prakhya * @grp_name: Name of the group 360591a6e85SSai Praneeth Prakhya * @grp: Full path and name of the group 361591a6e85SSai Praneeth Prakhya * @parent_grp: Full path and name of the parent group 362591a6e85SSai Praneeth Prakhya * 363591a6e85SSai Praneeth Prakhya * Return: 0 on success, non-zero on failure 364591a6e85SSai Praneeth Prakhya */ 365591a6e85SSai Praneeth Prakhya static int create_grp(const char *grp_name, char *grp, const char *parent_grp) 366591a6e85SSai Praneeth Prakhya { 367591a6e85SSai Praneeth Prakhya int found_grp = 0; 368591a6e85SSai Praneeth Prakhya struct dirent *ep; 369591a6e85SSai Praneeth Prakhya DIR *dp; 370591a6e85SSai Praneeth Prakhya 37178941183SFenghua Yu /* 37278941183SFenghua Yu * At this point, we are guaranteed to have resctrl FS mounted and if 37378941183SFenghua Yu * length of grp_name == 0, it means, user wants to use root con_mon 37478941183SFenghua Yu * grp, so do nothing 37578941183SFenghua Yu */ 37678941183SFenghua Yu if (strlen(grp_name) == 0) 37778941183SFenghua Yu return 0; 37878941183SFenghua Yu 379591a6e85SSai Praneeth Prakhya /* Check if requested grp exists or not */ 380591a6e85SSai Praneeth Prakhya dp = opendir(parent_grp); 381591a6e85SSai Praneeth Prakhya if (dp) { 382591a6e85SSai Praneeth Prakhya while ((ep = readdir(dp)) != NULL) { 383591a6e85SSai Praneeth Prakhya if (strcmp(ep->d_name, grp_name) == 0) 384591a6e85SSai Praneeth Prakhya found_grp = 1; 385591a6e85SSai Praneeth Prakhya } 386591a6e85SSai Praneeth Prakhya closedir(dp); 387591a6e85SSai Praneeth Prakhya } else { 388591a6e85SSai Praneeth Prakhya perror("Unable to open resctrl for group"); 389591a6e85SSai Praneeth Prakhya 390591a6e85SSai Praneeth Prakhya return -1; 391591a6e85SSai Praneeth Prakhya } 392591a6e85SSai Praneeth Prakhya 393591a6e85SSai Praneeth Prakhya /* Requested grp doesn't exist, hence create it */ 394591a6e85SSai Praneeth Prakhya if (found_grp == 0) { 395591a6e85SSai Praneeth Prakhya if (mkdir(grp, 0) == -1) { 396591a6e85SSai Praneeth Prakhya perror("Unable to create group"); 397591a6e85SSai Praneeth Prakhya 398591a6e85SSai Praneeth Prakhya return -1; 399591a6e85SSai Praneeth Prakhya } 400591a6e85SSai Praneeth Prakhya } 401591a6e85SSai Praneeth Prakhya 402591a6e85SSai Praneeth Prakhya return 0; 403591a6e85SSai Praneeth Prakhya } 404591a6e85SSai Praneeth Prakhya 405591a6e85SSai Praneeth Prakhya static int write_pid_to_tasks(char *tasks, pid_t pid) 406591a6e85SSai Praneeth Prakhya { 407591a6e85SSai Praneeth Prakhya FILE *fp; 408591a6e85SSai Praneeth Prakhya 409591a6e85SSai Praneeth Prakhya fp = fopen(tasks, "w"); 410591a6e85SSai Praneeth Prakhya if (!fp) { 411591a6e85SSai Praneeth Prakhya perror("Failed to open tasks file"); 412591a6e85SSai Praneeth Prakhya 413591a6e85SSai Praneeth Prakhya return -1; 414591a6e85SSai Praneeth Prakhya } 415591a6e85SSai Praneeth Prakhya if (fprintf(fp, "%d\n", pid) < 0) { 416591a6e85SSai Praneeth Prakhya perror("Failed to wr pid to tasks file"); 417591a6e85SSai Praneeth Prakhya fclose(fp); 418591a6e85SSai Praneeth Prakhya 419591a6e85SSai Praneeth Prakhya return -1; 420591a6e85SSai Praneeth Prakhya } 421591a6e85SSai Praneeth Prakhya fclose(fp); 422591a6e85SSai Praneeth Prakhya 423591a6e85SSai Praneeth Prakhya return 0; 424591a6e85SSai Praneeth Prakhya } 425591a6e85SSai Praneeth Prakhya 426591a6e85SSai Praneeth Prakhya /* 427591a6e85SSai Praneeth Prakhya * write_bm_pid_to_resctrl - Write a PID (i.e. benchmark) to resctrl FS 428591a6e85SSai Praneeth Prakhya * @bm_pid: PID that should be written 429591a6e85SSai Praneeth Prakhya * @ctrlgrp: Name of the control monitor group (con_mon grp) 430591a6e85SSai Praneeth Prakhya * @mongrp: Name of the monitor group (mon grp) 431591a6e85SSai Praneeth Prakhya * @resctrl_val: Resctrl feature (Eg: mbm, mba.. etc) 432591a6e85SSai Praneeth Prakhya * 433591a6e85SSai Praneeth Prakhya * If a con_mon grp is requested, create it and write pid to it, otherwise 434591a6e85SSai Praneeth Prakhya * write pid to root con_mon grp. 435591a6e85SSai Praneeth Prakhya * If a mon grp is requested, create it and write pid to it, otherwise 436591a6e85SSai Praneeth Prakhya * pid is not written, this means that pid is in con_mon grp and hence 437591a6e85SSai Praneeth Prakhya * should consult con_mon grp's mon_data directory for results. 438591a6e85SSai Praneeth Prakhya * 439591a6e85SSai Praneeth Prakhya * Return: 0 on success, non-zero on failure 440591a6e85SSai Praneeth Prakhya */ 441591a6e85SSai Praneeth Prakhya int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp, 442591a6e85SSai Praneeth Prakhya char *resctrl_val) 443591a6e85SSai Praneeth Prakhya { 444591a6e85SSai Praneeth Prakhya char controlgroup[128], monitorgroup[512], monitorgroup_p[256]; 445591a6e85SSai Praneeth Prakhya char tasks[1024]; 446591a6e85SSai Praneeth Prakhya int ret = 0; 447591a6e85SSai Praneeth Prakhya 448591a6e85SSai Praneeth Prakhya if (strlen(ctrlgrp)) 449591a6e85SSai Praneeth Prakhya sprintf(controlgroup, "%s/%s", RESCTRL_PATH, ctrlgrp); 450591a6e85SSai Praneeth Prakhya else 451591a6e85SSai Praneeth Prakhya sprintf(controlgroup, "%s", RESCTRL_PATH); 452591a6e85SSai Praneeth Prakhya 453591a6e85SSai Praneeth Prakhya /* Create control and monitoring group and write pid into it */ 454591a6e85SSai Praneeth Prakhya ret = create_grp(ctrlgrp, controlgroup, RESCTRL_PATH); 455591a6e85SSai Praneeth Prakhya if (ret) 456591a6e85SSai Praneeth Prakhya goto out; 457591a6e85SSai Praneeth Prakhya sprintf(tasks, "%s/tasks", controlgroup); 458591a6e85SSai Praneeth Prakhya ret = write_pid_to_tasks(tasks, bm_pid); 459591a6e85SSai Praneeth Prakhya if (ret) 460591a6e85SSai Praneeth Prakhya goto out; 461591a6e85SSai Praneeth Prakhya 4622f320911SFenghua Yu /* Create mon grp and write pid into it for "mbm" and "cmt" test */ 4632f320911SFenghua Yu if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)) || 46424286736SFenghua Yu !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) { 46578941183SFenghua Yu if (strlen(mongrp)) { 466591a6e85SSai Praneeth Prakhya sprintf(monitorgroup_p, "%s/mon_groups", controlgroup); 467591a6e85SSai Praneeth Prakhya sprintf(monitorgroup, "%s/%s", monitorgroup_p, mongrp); 468591a6e85SSai Praneeth Prakhya ret = create_grp(mongrp, monitorgroup, monitorgroup_p); 469591a6e85SSai Praneeth Prakhya if (ret) 470591a6e85SSai Praneeth Prakhya goto out; 471591a6e85SSai Praneeth Prakhya 472591a6e85SSai Praneeth Prakhya sprintf(tasks, "%s/mon_groups/%s/tasks", 473591a6e85SSai Praneeth Prakhya controlgroup, mongrp); 474591a6e85SSai Praneeth Prakhya ret = write_pid_to_tasks(tasks, bm_pid); 475591a6e85SSai Praneeth Prakhya if (ret) 476591a6e85SSai Praneeth Prakhya goto out; 477591a6e85SSai Praneeth Prakhya } 478591a6e85SSai Praneeth Prakhya } 479591a6e85SSai Praneeth Prakhya 480591a6e85SSai Praneeth Prakhya out: 481ca2f4214SFenghua Yu ksft_print_msg("Writing benchmark parameters to resctrl FS\n"); 482591a6e85SSai Praneeth Prakhya if (ret) 483591a6e85SSai Praneeth Prakhya perror("# writing to resctrlfs"); 484591a6e85SSai Praneeth Prakhya 485591a6e85SSai Praneeth Prakhya return ret; 486591a6e85SSai Praneeth Prakhya } 487591a6e85SSai Praneeth Prakhya 488591a6e85SSai Praneeth Prakhya /* 489591a6e85SSai Praneeth Prakhya * write_schemata - Update schemata of a con_mon grp 490591a6e85SSai Praneeth Prakhya * @ctrlgrp: Name of the con_mon grp 491591a6e85SSai Praneeth Prakhya * @schemata: Schemata that should be updated to 492591a6e85SSai Praneeth Prakhya * @cpu_no: CPU number that the benchmark PID is binded to 493591a6e85SSai Praneeth Prakhya * @resctrl_val: Resctrl feature (Eg: mbm, mba.. etc) 494591a6e85SSai Praneeth Prakhya * 495591a6e85SSai Praneeth Prakhya * Update schemata of a con_mon grp *only* if requested resctrl feature is 496591a6e85SSai Praneeth Prakhya * allocation type 497591a6e85SSai Praneeth Prakhya * 498591a6e85SSai Praneeth Prakhya * Return: 0 on success, non-zero on failure 499591a6e85SSai Praneeth Prakhya */ 500591a6e85SSai Praneeth Prakhya int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val) 501591a6e85SSai Praneeth Prakhya { 502591a6e85SSai Praneeth Prakhya char controlgroup[1024], schema[1024], reason[64]; 503591a6e85SSai Praneeth Prakhya int resource_id, ret = 0; 504591a6e85SSai Praneeth Prakhya FILE *fp; 505591a6e85SSai Praneeth Prakhya 50624286736SFenghua Yu if (strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) && 50742e3b093SShaopeng Tan strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) && 50824286736SFenghua Yu strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) && 5092f320911SFenghua Yu strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) 510591a6e85SSai Praneeth Prakhya return -ENOENT; 511591a6e85SSai Praneeth Prakhya 512591a6e85SSai Praneeth Prakhya if (!schemata) { 513ca2f4214SFenghua Yu ksft_print_msg("Skipping empty schemata update\n"); 514591a6e85SSai Praneeth Prakhya 515591a6e85SSai Praneeth Prakhya return -1; 516591a6e85SSai Praneeth Prakhya } 517591a6e85SSai Praneeth Prakhya 518591a6e85SSai Praneeth Prakhya if (get_resource_id(cpu_no, &resource_id) < 0) { 519591a6e85SSai Praneeth Prakhya sprintf(reason, "Failed to get resource id"); 520591a6e85SSai Praneeth Prakhya ret = -1; 521591a6e85SSai Praneeth Prakhya 522591a6e85SSai Praneeth Prakhya goto out; 523591a6e85SSai Praneeth Prakhya } 524591a6e85SSai Praneeth Prakhya 525591a6e85SSai Praneeth Prakhya if (strlen(ctrlgrp) != 0) 526591a6e85SSai Praneeth Prakhya sprintf(controlgroup, "%s/%s/schemata", RESCTRL_PATH, ctrlgrp); 527591a6e85SSai Praneeth Prakhya else 528591a6e85SSai Praneeth Prakhya sprintf(controlgroup, "%s/schemata", RESCTRL_PATH); 529591a6e85SSai Praneeth Prakhya 53024286736SFenghua Yu if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) || 5312f320911SFenghua Yu !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) 53278941183SFenghua Yu sprintf(schema, "%s%d%c%s", "L3:", resource_id, '=', schemata); 53342e3b093SShaopeng Tan if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) || 53442e3b093SShaopeng Tan !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) 535591a6e85SSai Praneeth Prakhya sprintf(schema, "%s%d%c%s", "MB:", resource_id, '=', schemata); 536591a6e85SSai Praneeth Prakhya 537591a6e85SSai Praneeth Prakhya fp = fopen(controlgroup, "w"); 538591a6e85SSai Praneeth Prakhya if (!fp) { 539591a6e85SSai Praneeth Prakhya sprintf(reason, "Failed to open control group"); 540591a6e85SSai Praneeth Prakhya ret = -1; 541591a6e85SSai Praneeth Prakhya 542591a6e85SSai Praneeth Prakhya goto out; 543591a6e85SSai Praneeth Prakhya } 544591a6e85SSai Praneeth Prakhya 545591a6e85SSai Praneeth Prakhya if (fprintf(fp, "%s\n", schema) < 0) { 546591a6e85SSai Praneeth Prakhya sprintf(reason, "Failed to write schemata in control group"); 547591a6e85SSai Praneeth Prakhya fclose(fp); 548591a6e85SSai Praneeth Prakhya ret = -1; 549591a6e85SSai Praneeth Prakhya 550591a6e85SSai Praneeth Prakhya goto out; 551591a6e85SSai Praneeth Prakhya } 552591a6e85SSai Praneeth Prakhya fclose(fp); 553591a6e85SSai Praneeth Prakhya 554591a6e85SSai Praneeth Prakhya out: 555ca2f4214SFenghua Yu ksft_print_msg("Write schema \"%s\" to resctrl FS%s%s\n", 556ca2f4214SFenghua Yu schema, ret ? " # " : "", 557591a6e85SSai Praneeth Prakhya ret ? reason : ""); 558591a6e85SSai Praneeth Prakhya 559591a6e85SSai Praneeth Prakhya return ret; 560591a6e85SSai Praneeth Prakhya } 561591a6e85SSai Praneeth Prakhya 562ecdbb911SFenghua Yu bool check_resctrlfs_support(void) 563ecdbb911SFenghua Yu { 564ecdbb911SFenghua Yu FILE *inf = fopen("/proc/filesystems", "r"); 565ecdbb911SFenghua Yu DIR *dp; 566ecdbb911SFenghua Yu char *res; 567ecdbb911SFenghua Yu bool ret = false; 568ecdbb911SFenghua Yu 569ecdbb911SFenghua Yu if (!inf) 570ecdbb911SFenghua Yu return false; 571ecdbb911SFenghua Yu 572ecdbb911SFenghua Yu res = fgrep(inf, "nodev\tresctrl\n"); 573ecdbb911SFenghua Yu 574ecdbb911SFenghua Yu if (res) { 575ecdbb911SFenghua Yu ret = true; 576ecdbb911SFenghua Yu free(res); 577ecdbb911SFenghua Yu } 578ecdbb911SFenghua Yu 579ecdbb911SFenghua Yu fclose(inf); 580ecdbb911SFenghua Yu 581e7507478SFenghua Yu ksft_print_msg("%s Check kernel supports resctrl filesystem\n", 582ca2f4214SFenghua Yu ret ? "Pass:" : "Fail:"); 583ecdbb911SFenghua Yu 584a3611fbcSFenghua Yu if (!ret) 585a3611fbcSFenghua Yu return ret; 586a3611fbcSFenghua Yu 587ecdbb911SFenghua Yu dp = opendir(RESCTRL_PATH); 588e7507478SFenghua Yu ksft_print_msg("%s Check resctrl mountpoint \"%s\" exists\n", 589ca2f4214SFenghua Yu dp ? "Pass:" : "Fail:", RESCTRL_PATH); 590ecdbb911SFenghua Yu if (dp) 591ecdbb911SFenghua Yu closedir(dp); 592ecdbb911SFenghua Yu 593ca2f4214SFenghua Yu ksft_print_msg("resctrl filesystem %s mounted\n", 594ecdbb911SFenghua Yu find_resctrl_mount(NULL) ? "not" : "is"); 595ecdbb911SFenghua Yu 596ecdbb911SFenghua Yu return ret; 597ecdbb911SFenghua Yu } 598ecdbb911SFenghua Yu 599591a6e85SSai Praneeth Prakhya char *fgrep(FILE *inf, const char *str) 600591a6e85SSai Praneeth Prakhya { 601591a6e85SSai Praneeth Prakhya char line[256]; 602591a6e85SSai Praneeth Prakhya int slen = strlen(str); 603591a6e85SSai Praneeth Prakhya 604591a6e85SSai Praneeth Prakhya while (!feof(inf)) { 605591a6e85SSai Praneeth Prakhya if (!fgets(line, 256, inf)) 606591a6e85SSai Praneeth Prakhya break; 607591a6e85SSai Praneeth Prakhya if (strncmp(line, str, slen)) 608591a6e85SSai Praneeth Prakhya continue; 609591a6e85SSai Praneeth Prakhya 610591a6e85SSai Praneeth Prakhya return strdup(line); 611591a6e85SSai Praneeth Prakhya } 612591a6e85SSai Praneeth Prakhya 613591a6e85SSai Praneeth Prakhya return NULL; 614591a6e85SSai Praneeth Prakhya } 615591a6e85SSai Praneeth Prakhya 616591a6e85SSai Praneeth Prakhya /* 617591a6e85SSai Praneeth Prakhya * validate_resctrl_feature_request - Check if requested feature is valid. 618591a6e85SSai Praneeth Prakhya * @resctrl_val: Requested feature 619591a6e85SSai Praneeth Prakhya * 620*caddc0fbSIlpo Järvinen * Return: True if the feature is supported, else false. False is also 621*caddc0fbSIlpo Järvinen * returned if resctrl FS is not mounted. 622591a6e85SSai Praneeth Prakhya */ 623ee041568SFenghua Yu bool validate_resctrl_feature_request(const char *resctrl_val) 624591a6e85SSai Praneeth Prakhya { 625ee041568SFenghua Yu struct stat statbuf; 626591a6e85SSai Praneeth Prakhya bool found = false; 627591a6e85SSai Praneeth Prakhya char *res; 628ee041568SFenghua Yu FILE *inf; 629*caddc0fbSIlpo Järvinen int ret; 630591a6e85SSai Praneeth Prakhya 631ee041568SFenghua Yu if (!resctrl_val) 632ee041568SFenghua Yu return false; 633ee041568SFenghua Yu 634*caddc0fbSIlpo Järvinen ret = find_resctrl_mount(NULL); 635*caddc0fbSIlpo Järvinen if (ret) 636ee041568SFenghua Yu return false; 637ee041568SFenghua Yu 638ee041568SFenghua Yu if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) { 639ee041568SFenghua Yu if (!stat(L3_PATH, &statbuf)) 640ee041568SFenghua Yu return true; 641ee041568SFenghua Yu } else if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) { 642ee041568SFenghua Yu if (!stat(MB_PATH, &statbuf)) 643ee041568SFenghua Yu return true; 644ee041568SFenghua Yu } else if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) || 645ee041568SFenghua Yu !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) { 646ee041568SFenghua Yu if (!stat(L3_MON_PATH, &statbuf)) { 647ee041568SFenghua Yu inf = fopen(L3_MON_FEATURES_PATH, "r"); 648591a6e85SSai Praneeth Prakhya if (!inf) 649591a6e85SSai Praneeth Prakhya return false; 650591a6e85SSai Praneeth Prakhya 651ee041568SFenghua Yu if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) { 652ee041568SFenghua Yu res = fgrep(inf, "llc_occupancy"); 653591a6e85SSai Praneeth Prakhya if (res) { 654ee041568SFenghua Yu found = true; 655591a6e85SSai Praneeth Prakhya free(res); 656591a6e85SSai Praneeth Prakhya } 657ee041568SFenghua Yu } 658ee041568SFenghua Yu 659ee041568SFenghua Yu if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) { 660ee041568SFenghua Yu res = fgrep(inf, "mbm_total_bytes"); 661ee041568SFenghua Yu if (res) { 662ee041568SFenghua Yu free(res); 663ee041568SFenghua Yu res = fgrep(inf, "mbm_local_bytes"); 664ee041568SFenghua Yu if (res) { 665ee041568SFenghua Yu found = true; 666ee041568SFenghua Yu free(res); 667ee041568SFenghua Yu } 668ee041568SFenghua Yu } 669ee041568SFenghua Yu } 670591a6e85SSai Praneeth Prakhya fclose(inf); 671ee041568SFenghua Yu } 672ee041568SFenghua Yu } 673591a6e85SSai Praneeth Prakhya 674591a6e85SSai Praneeth Prakhya return found; 675591a6e85SSai Praneeth Prakhya } 676591a6e85SSai Praneeth Prakhya 677ecdbb911SFenghua Yu int filter_dmesg(void) 678ecdbb911SFenghua Yu { 679ecdbb911SFenghua Yu char line[1024]; 680ecdbb911SFenghua Yu FILE *fp; 681ecdbb911SFenghua Yu int pipefds[2]; 682ecdbb911SFenghua Yu pid_t pid; 683ecdbb911SFenghua Yu int ret; 684ecdbb911SFenghua Yu 685ecdbb911SFenghua Yu ret = pipe(pipefds); 686ecdbb911SFenghua Yu if (ret) { 687ecdbb911SFenghua Yu perror("pipe"); 688ecdbb911SFenghua Yu return ret; 689ecdbb911SFenghua Yu } 690a080b6e7SShaopeng Tan fflush(stdout); 691ecdbb911SFenghua Yu pid = fork(); 692ecdbb911SFenghua Yu if (pid == 0) { 693ecdbb911SFenghua Yu close(pipefds[0]); 694ecdbb911SFenghua Yu dup2(pipefds[1], STDOUT_FILENO); 695ecdbb911SFenghua Yu execlp("dmesg", "dmesg", NULL); 696ecdbb911SFenghua Yu perror("executing dmesg"); 697ecdbb911SFenghua Yu exit(1); 698ecdbb911SFenghua Yu } 699ecdbb911SFenghua Yu close(pipefds[1]); 700ecdbb911SFenghua Yu fp = fdopen(pipefds[0], "r"); 701ecdbb911SFenghua Yu if (!fp) { 702ecdbb911SFenghua Yu perror("fdopen(pipe)"); 703ecdbb911SFenghua Yu kill(pid, SIGTERM); 704ecdbb911SFenghua Yu 705ecdbb911SFenghua Yu return -1; 706ecdbb911SFenghua Yu } 707ecdbb911SFenghua Yu 708ecdbb911SFenghua Yu while (fgets(line, 1024, fp)) { 709ecdbb911SFenghua Yu if (strstr(line, "intel_rdt:")) 710ca2f4214SFenghua Yu ksft_print_msg("dmesg: %s", line); 711ecdbb911SFenghua Yu if (strstr(line, "resctrl:")) 712ca2f4214SFenghua Yu ksft_print_msg("dmesg: %s", line); 713ecdbb911SFenghua Yu } 714ecdbb911SFenghua Yu fclose(fp); 715ecdbb911SFenghua Yu waitpid(pid, NULL, 0); 716ecdbb911SFenghua Yu 717ecdbb911SFenghua Yu return 0; 718ecdbb911SFenghua Yu } 719ecdbb911SFenghua Yu 720591a6e85SSai Praneeth Prakhya int validate_bw_report_request(char *bw_report) 721591a6e85SSai Praneeth Prakhya { 722591a6e85SSai Praneeth Prakhya if (strcmp(bw_report, "reads") == 0) 723591a6e85SSai Praneeth Prakhya return 0; 724591a6e85SSai Praneeth Prakhya if (strcmp(bw_report, "writes") == 0) 725591a6e85SSai Praneeth Prakhya return 0; 726591a6e85SSai Praneeth Prakhya if (strcmp(bw_report, "nt-writes") == 0) { 727591a6e85SSai Praneeth Prakhya strcpy(bw_report, "writes"); 728591a6e85SSai Praneeth Prakhya return 0; 729591a6e85SSai Praneeth Prakhya } 730591a6e85SSai Praneeth Prakhya if (strcmp(bw_report, "total") == 0) 731591a6e85SSai Praneeth Prakhya return 0; 732591a6e85SSai Praneeth Prakhya 733591a6e85SSai Praneeth Prakhya fprintf(stderr, "Requested iMC B/W report type unavailable\n"); 734591a6e85SSai Praneeth Prakhya 735591a6e85SSai Praneeth Prakhya return -1; 736591a6e85SSai Praneeth Prakhya } 737591a6e85SSai Praneeth Prakhya 738591a6e85SSai Praneeth Prakhya int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, 739591a6e85SSai Praneeth Prakhya int group_fd, unsigned long flags) 740591a6e85SSai Praneeth Prakhya { 741591a6e85SSai Praneeth Prakhya int ret; 742591a6e85SSai Praneeth Prakhya 743591a6e85SSai Praneeth Prakhya ret = syscall(__NR_perf_event_open, hw_event, pid, cpu, 744591a6e85SSai Praneeth Prakhya group_fd, flags); 745591a6e85SSai Praneeth Prakhya return ret; 746591a6e85SSai Praneeth Prakhya } 74778941183SFenghua Yu 74878941183SFenghua Yu unsigned int count_bits(unsigned long n) 74978941183SFenghua Yu { 75078941183SFenghua Yu unsigned int count = 0; 75178941183SFenghua Yu 75278941183SFenghua Yu while (n) { 75378941183SFenghua Yu count += n & 1; 75478941183SFenghua Yu n >>= 1; 75578941183SFenghua Yu } 75678941183SFenghua Yu 75778941183SFenghua Yu return count; 75878941183SFenghua Yu } 759