1*591a6e85SSai Praneeth Prakhya // SPDX-License-Identifier: GPL-2.0 2*591a6e85SSai Praneeth Prakhya /* 3*591a6e85SSai Praneeth Prakhya * Basic resctrl file system operations 4*591a6e85SSai Praneeth Prakhya * 5*591a6e85SSai Praneeth Prakhya * Copyright (C) 2018 Intel Corporation 6*591a6e85SSai Praneeth Prakhya * 7*591a6e85SSai Praneeth Prakhya * Authors: 8*591a6e85SSai Praneeth Prakhya * Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>, 9*591a6e85SSai Praneeth Prakhya * Fenghua Yu <fenghua.yu@intel.com> 10*591a6e85SSai Praneeth Prakhya */ 11*591a6e85SSai Praneeth Prakhya #include "resctrl.h" 12*591a6e85SSai Praneeth Prakhya 13*591a6e85SSai Praneeth Prakhya int tests_run; 14*591a6e85SSai Praneeth Prakhya 15*591a6e85SSai Praneeth Prakhya static int find_resctrl_mount(char *buffer) 16*591a6e85SSai Praneeth Prakhya { 17*591a6e85SSai Praneeth Prakhya FILE *mounts; 18*591a6e85SSai Praneeth Prakhya char line[256], *fs, *mntpoint; 19*591a6e85SSai Praneeth Prakhya 20*591a6e85SSai Praneeth Prakhya mounts = fopen("/proc/mounts", "r"); 21*591a6e85SSai Praneeth Prakhya if (!mounts) { 22*591a6e85SSai Praneeth Prakhya perror("/proc/mounts"); 23*591a6e85SSai Praneeth Prakhya return -ENXIO; 24*591a6e85SSai Praneeth Prakhya } 25*591a6e85SSai Praneeth Prakhya while (!feof(mounts)) { 26*591a6e85SSai Praneeth Prakhya if (!fgets(line, 256, mounts)) 27*591a6e85SSai Praneeth Prakhya break; 28*591a6e85SSai Praneeth Prakhya fs = strtok(line, " \t"); 29*591a6e85SSai Praneeth Prakhya if (!fs) 30*591a6e85SSai Praneeth Prakhya continue; 31*591a6e85SSai Praneeth Prakhya mntpoint = strtok(NULL, " \t"); 32*591a6e85SSai Praneeth Prakhya if (!mntpoint) 33*591a6e85SSai Praneeth Prakhya continue; 34*591a6e85SSai Praneeth Prakhya fs = strtok(NULL, " \t"); 35*591a6e85SSai Praneeth Prakhya if (!fs) 36*591a6e85SSai Praneeth Prakhya continue; 37*591a6e85SSai Praneeth Prakhya if (strcmp(fs, "resctrl")) 38*591a6e85SSai Praneeth Prakhya continue; 39*591a6e85SSai Praneeth Prakhya 40*591a6e85SSai Praneeth Prakhya fclose(mounts); 41*591a6e85SSai Praneeth Prakhya if (buffer) 42*591a6e85SSai Praneeth Prakhya strncpy(buffer, mntpoint, 256); 43*591a6e85SSai Praneeth Prakhya 44*591a6e85SSai Praneeth Prakhya return 0; 45*591a6e85SSai Praneeth Prakhya } 46*591a6e85SSai Praneeth Prakhya 47*591a6e85SSai Praneeth Prakhya fclose(mounts); 48*591a6e85SSai Praneeth Prakhya 49*591a6e85SSai Praneeth Prakhya return -ENOENT; 50*591a6e85SSai Praneeth Prakhya } 51*591a6e85SSai Praneeth Prakhya 52*591a6e85SSai Praneeth Prakhya /* 53*591a6e85SSai Praneeth Prakhya * remount_resctrlfs - Remount resctrl FS at /sys/fs/resctrl 54*591a6e85SSai Praneeth Prakhya * @mum_resctrlfs: Should the resctrl FS be remounted? 55*591a6e85SSai Praneeth Prakhya * 56*591a6e85SSai Praneeth Prakhya * If not mounted, mount it. 57*591a6e85SSai Praneeth Prakhya * If mounted and mum_resctrlfs then remount resctrl FS. 58*591a6e85SSai Praneeth Prakhya * If mounted and !mum_resctrlfs then noop 59*591a6e85SSai Praneeth Prakhya * 60*591a6e85SSai Praneeth Prakhya * Return: 0 on success, non-zero on failure 61*591a6e85SSai Praneeth Prakhya */ 62*591a6e85SSai Praneeth Prakhya int remount_resctrlfs(bool mum_resctrlfs) 63*591a6e85SSai Praneeth Prakhya { 64*591a6e85SSai Praneeth Prakhya char mountpoint[256]; 65*591a6e85SSai Praneeth Prakhya int ret; 66*591a6e85SSai Praneeth Prakhya 67*591a6e85SSai Praneeth Prakhya ret = find_resctrl_mount(mountpoint); 68*591a6e85SSai Praneeth Prakhya if (ret) 69*591a6e85SSai Praneeth Prakhya strcpy(mountpoint, RESCTRL_PATH); 70*591a6e85SSai Praneeth Prakhya 71*591a6e85SSai Praneeth Prakhya if (!ret && mum_resctrlfs && umount(mountpoint)) { 72*591a6e85SSai Praneeth Prakhya printf("not ok unmounting \"%s\"\n", mountpoint); 73*591a6e85SSai Praneeth Prakhya perror("# umount"); 74*591a6e85SSai Praneeth Prakhya tests_run++; 75*591a6e85SSai Praneeth Prakhya } 76*591a6e85SSai Praneeth Prakhya 77*591a6e85SSai Praneeth Prakhya if (!ret && !mum_resctrlfs) 78*591a6e85SSai Praneeth Prakhya return 0; 79*591a6e85SSai Praneeth Prakhya 80*591a6e85SSai Praneeth Prakhya ret = mount("resctrl", RESCTRL_PATH, "resctrl", 0, NULL); 81*591a6e85SSai Praneeth Prakhya printf("%sok mounting resctrl to \"%s\"\n", ret ? "not " : "", 82*591a6e85SSai Praneeth Prakhya RESCTRL_PATH); 83*591a6e85SSai Praneeth Prakhya if (ret) 84*591a6e85SSai Praneeth Prakhya perror("# mount"); 85*591a6e85SSai Praneeth Prakhya 86*591a6e85SSai Praneeth Prakhya tests_run++; 87*591a6e85SSai Praneeth Prakhya 88*591a6e85SSai Praneeth Prakhya return ret; 89*591a6e85SSai Praneeth Prakhya } 90*591a6e85SSai Praneeth Prakhya 91*591a6e85SSai Praneeth Prakhya int umount_resctrlfs(void) 92*591a6e85SSai Praneeth Prakhya { 93*591a6e85SSai Praneeth Prakhya if (umount(RESCTRL_PATH)) { 94*591a6e85SSai Praneeth Prakhya perror("# Unable to umount resctrl"); 95*591a6e85SSai Praneeth Prakhya 96*591a6e85SSai Praneeth Prakhya return errno; 97*591a6e85SSai Praneeth Prakhya } 98*591a6e85SSai Praneeth Prakhya 99*591a6e85SSai Praneeth Prakhya return 0; 100*591a6e85SSai Praneeth Prakhya } 101*591a6e85SSai Praneeth Prakhya 102*591a6e85SSai Praneeth Prakhya /* 103*591a6e85SSai Praneeth Prakhya * get_resource_id - Get socket number/l3 id for a specified CPU 104*591a6e85SSai Praneeth Prakhya * @cpu_no: CPU number 105*591a6e85SSai Praneeth Prakhya * @resource_id: Socket number or l3_id 106*591a6e85SSai Praneeth Prakhya * 107*591a6e85SSai Praneeth Prakhya * Return: >= 0 on success, < 0 on failure. 108*591a6e85SSai Praneeth Prakhya */ 109*591a6e85SSai Praneeth Prakhya int get_resource_id(int cpu_no, int *resource_id) 110*591a6e85SSai Praneeth Prakhya { 111*591a6e85SSai Praneeth Prakhya char phys_pkg_path[1024]; 112*591a6e85SSai Praneeth Prakhya FILE *fp; 113*591a6e85SSai Praneeth Prakhya 114*591a6e85SSai Praneeth Prakhya sprintf(phys_pkg_path, "%s%d/topology/physical_package_id", 115*591a6e85SSai Praneeth Prakhya PHYS_ID_PATH, cpu_no); 116*591a6e85SSai Praneeth Prakhya fp = fopen(phys_pkg_path, "r"); 117*591a6e85SSai Praneeth Prakhya if (!fp) { 118*591a6e85SSai Praneeth Prakhya perror("Failed to open physical_package_id"); 119*591a6e85SSai Praneeth Prakhya 120*591a6e85SSai Praneeth Prakhya return -1; 121*591a6e85SSai Praneeth Prakhya } 122*591a6e85SSai Praneeth Prakhya if (fscanf(fp, "%d", resource_id) <= 0) { 123*591a6e85SSai Praneeth Prakhya perror("Could not get socket number or l3 id"); 124*591a6e85SSai Praneeth Prakhya fclose(fp); 125*591a6e85SSai Praneeth Prakhya 126*591a6e85SSai Praneeth Prakhya return -1; 127*591a6e85SSai Praneeth Prakhya } 128*591a6e85SSai Praneeth Prakhya fclose(fp); 129*591a6e85SSai Praneeth Prakhya 130*591a6e85SSai Praneeth Prakhya return 0; 131*591a6e85SSai Praneeth Prakhya } 132*591a6e85SSai Praneeth Prakhya 133*591a6e85SSai Praneeth Prakhya /* 134*591a6e85SSai Praneeth Prakhya * taskset_benchmark - Taskset PID (i.e. benchmark) to a specified cpu 135*591a6e85SSai Praneeth Prakhya * @bm_pid: PID that should be binded 136*591a6e85SSai Praneeth Prakhya * @cpu_no: CPU number at which the PID would be binded 137*591a6e85SSai Praneeth Prakhya * 138*591a6e85SSai Praneeth Prakhya * Return: 0 on success, non-zero on failure 139*591a6e85SSai Praneeth Prakhya */ 140*591a6e85SSai Praneeth Prakhya int taskset_benchmark(pid_t bm_pid, int cpu_no) 141*591a6e85SSai Praneeth Prakhya { 142*591a6e85SSai Praneeth Prakhya cpu_set_t my_set; 143*591a6e85SSai Praneeth Prakhya 144*591a6e85SSai Praneeth Prakhya CPU_ZERO(&my_set); 145*591a6e85SSai Praneeth Prakhya CPU_SET(cpu_no, &my_set); 146*591a6e85SSai Praneeth Prakhya 147*591a6e85SSai Praneeth Prakhya if (sched_setaffinity(bm_pid, sizeof(cpu_set_t), &my_set)) { 148*591a6e85SSai Praneeth Prakhya perror("Unable to taskset benchmark"); 149*591a6e85SSai Praneeth Prakhya 150*591a6e85SSai Praneeth Prakhya return -1; 151*591a6e85SSai Praneeth Prakhya } 152*591a6e85SSai Praneeth Prakhya 153*591a6e85SSai Praneeth Prakhya return 0; 154*591a6e85SSai Praneeth Prakhya } 155*591a6e85SSai Praneeth Prakhya 156*591a6e85SSai Praneeth Prakhya /* 157*591a6e85SSai Praneeth Prakhya * run_benchmark - Run a specified benchmark or fill_buf (default benchmark) 158*591a6e85SSai Praneeth Prakhya * in specified signal. Direct benchmark stdio to /dev/null. 159*591a6e85SSai Praneeth Prakhya * @signum: signal number 160*591a6e85SSai Praneeth Prakhya * @info: signal info 161*591a6e85SSai Praneeth Prakhya * @ucontext: user context in signal handling 162*591a6e85SSai Praneeth Prakhya * 163*591a6e85SSai Praneeth Prakhya * Return: void 164*591a6e85SSai Praneeth Prakhya */ 165*591a6e85SSai Praneeth Prakhya void run_benchmark(int signum, siginfo_t *info, void *ucontext) 166*591a6e85SSai Praneeth Prakhya { 167*591a6e85SSai Praneeth Prakhya unsigned long span; 168*591a6e85SSai Praneeth Prakhya int operation, ret; 169*591a6e85SSai Praneeth Prakhya char **benchmark_cmd; 170*591a6e85SSai Praneeth Prakhya FILE *fp; 171*591a6e85SSai Praneeth Prakhya 172*591a6e85SSai Praneeth Prakhya benchmark_cmd = info->si_ptr; 173*591a6e85SSai Praneeth Prakhya 174*591a6e85SSai Praneeth Prakhya /* 175*591a6e85SSai Praneeth Prakhya * Direct stdio of child to /dev/null, so that only parent writes to 176*591a6e85SSai Praneeth Prakhya * stdio (console) 177*591a6e85SSai Praneeth Prakhya */ 178*591a6e85SSai Praneeth Prakhya fp = freopen("/dev/null", "w", stdout); 179*591a6e85SSai Praneeth Prakhya if (!fp) 180*591a6e85SSai Praneeth Prakhya PARENT_EXIT("Unable to direct benchmark status to /dev/null"); 181*591a6e85SSai Praneeth Prakhya 182*591a6e85SSai Praneeth Prakhya if (strcmp(benchmark_cmd[0], "fill_buf") == 0) { 183*591a6e85SSai Praneeth Prakhya /* Execute default fill_buf benchmark */ 184*591a6e85SSai Praneeth Prakhya span = strtoul(benchmark_cmd[1], NULL, 10); 185*591a6e85SSai Praneeth Prakhya operation = atoi(benchmark_cmd[4]); 186*591a6e85SSai Praneeth Prakhya if (run_fill_buf(span, 1, 1, operation, NULL)) 187*591a6e85SSai Praneeth Prakhya fprintf(stderr, "Error in running fill buffer\n"); 188*591a6e85SSai Praneeth Prakhya } else { 189*591a6e85SSai Praneeth Prakhya /* Execute specified benchmark */ 190*591a6e85SSai Praneeth Prakhya ret = execvp(benchmark_cmd[0], benchmark_cmd); 191*591a6e85SSai Praneeth Prakhya if (ret) 192*591a6e85SSai Praneeth Prakhya perror("wrong\n"); 193*591a6e85SSai Praneeth Prakhya } 194*591a6e85SSai Praneeth Prakhya 195*591a6e85SSai Praneeth Prakhya fclose(stdout); 196*591a6e85SSai Praneeth Prakhya PARENT_EXIT("Unable to run specified benchmark"); 197*591a6e85SSai Praneeth Prakhya } 198*591a6e85SSai Praneeth Prakhya 199*591a6e85SSai Praneeth Prakhya /* 200*591a6e85SSai Praneeth Prakhya * create_grp - Create a group only if one doesn't exist 201*591a6e85SSai Praneeth Prakhya * @grp_name: Name of the group 202*591a6e85SSai Praneeth Prakhya * @grp: Full path and name of the group 203*591a6e85SSai Praneeth Prakhya * @parent_grp: Full path and name of the parent group 204*591a6e85SSai Praneeth Prakhya * 205*591a6e85SSai Praneeth Prakhya * Return: 0 on success, non-zero on failure 206*591a6e85SSai Praneeth Prakhya */ 207*591a6e85SSai Praneeth Prakhya static int create_grp(const char *grp_name, char *grp, const char *parent_grp) 208*591a6e85SSai Praneeth Prakhya { 209*591a6e85SSai Praneeth Prakhya int found_grp = 0; 210*591a6e85SSai Praneeth Prakhya struct dirent *ep; 211*591a6e85SSai Praneeth Prakhya DIR *dp; 212*591a6e85SSai Praneeth Prakhya 213*591a6e85SSai Praneeth Prakhya /* Check if requested grp exists or not */ 214*591a6e85SSai Praneeth Prakhya dp = opendir(parent_grp); 215*591a6e85SSai Praneeth Prakhya if (dp) { 216*591a6e85SSai Praneeth Prakhya while ((ep = readdir(dp)) != NULL) { 217*591a6e85SSai Praneeth Prakhya if (strcmp(ep->d_name, grp_name) == 0) 218*591a6e85SSai Praneeth Prakhya found_grp = 1; 219*591a6e85SSai Praneeth Prakhya } 220*591a6e85SSai Praneeth Prakhya closedir(dp); 221*591a6e85SSai Praneeth Prakhya } else { 222*591a6e85SSai Praneeth Prakhya perror("Unable to open resctrl for group"); 223*591a6e85SSai Praneeth Prakhya 224*591a6e85SSai Praneeth Prakhya return -1; 225*591a6e85SSai Praneeth Prakhya } 226*591a6e85SSai Praneeth Prakhya 227*591a6e85SSai Praneeth Prakhya /* Requested grp doesn't exist, hence create it */ 228*591a6e85SSai Praneeth Prakhya if (found_grp == 0) { 229*591a6e85SSai Praneeth Prakhya if (mkdir(grp, 0) == -1) { 230*591a6e85SSai Praneeth Prakhya perror("Unable to create group"); 231*591a6e85SSai Praneeth Prakhya 232*591a6e85SSai Praneeth Prakhya return -1; 233*591a6e85SSai Praneeth Prakhya } 234*591a6e85SSai Praneeth Prakhya } 235*591a6e85SSai Praneeth Prakhya 236*591a6e85SSai Praneeth Prakhya return 0; 237*591a6e85SSai Praneeth Prakhya } 238*591a6e85SSai Praneeth Prakhya 239*591a6e85SSai Praneeth Prakhya static int write_pid_to_tasks(char *tasks, pid_t pid) 240*591a6e85SSai Praneeth Prakhya { 241*591a6e85SSai Praneeth Prakhya FILE *fp; 242*591a6e85SSai Praneeth Prakhya 243*591a6e85SSai Praneeth Prakhya fp = fopen(tasks, "w"); 244*591a6e85SSai Praneeth Prakhya if (!fp) { 245*591a6e85SSai Praneeth Prakhya perror("Failed to open tasks file"); 246*591a6e85SSai Praneeth Prakhya 247*591a6e85SSai Praneeth Prakhya return -1; 248*591a6e85SSai Praneeth Prakhya } 249*591a6e85SSai Praneeth Prakhya if (fprintf(fp, "%d\n", pid) < 0) { 250*591a6e85SSai Praneeth Prakhya perror("Failed to wr pid to tasks file"); 251*591a6e85SSai Praneeth Prakhya fclose(fp); 252*591a6e85SSai Praneeth Prakhya 253*591a6e85SSai Praneeth Prakhya return -1; 254*591a6e85SSai Praneeth Prakhya } 255*591a6e85SSai Praneeth Prakhya fclose(fp); 256*591a6e85SSai Praneeth Prakhya 257*591a6e85SSai Praneeth Prakhya return 0; 258*591a6e85SSai Praneeth Prakhya } 259*591a6e85SSai Praneeth Prakhya 260*591a6e85SSai Praneeth Prakhya /* 261*591a6e85SSai Praneeth Prakhya * write_bm_pid_to_resctrl - Write a PID (i.e. benchmark) to resctrl FS 262*591a6e85SSai Praneeth Prakhya * @bm_pid: PID that should be written 263*591a6e85SSai Praneeth Prakhya * @ctrlgrp: Name of the control monitor group (con_mon grp) 264*591a6e85SSai Praneeth Prakhya * @mongrp: Name of the monitor group (mon grp) 265*591a6e85SSai Praneeth Prakhya * @resctrl_val: Resctrl feature (Eg: mbm, mba.. etc) 266*591a6e85SSai Praneeth Prakhya * 267*591a6e85SSai Praneeth Prakhya * If a con_mon grp is requested, create it and write pid to it, otherwise 268*591a6e85SSai Praneeth Prakhya * write pid to root con_mon grp. 269*591a6e85SSai Praneeth Prakhya * If a mon grp is requested, create it and write pid to it, otherwise 270*591a6e85SSai Praneeth Prakhya * pid is not written, this means that pid is in con_mon grp and hence 271*591a6e85SSai Praneeth Prakhya * should consult con_mon grp's mon_data directory for results. 272*591a6e85SSai Praneeth Prakhya * 273*591a6e85SSai Praneeth Prakhya * Return: 0 on success, non-zero on failure 274*591a6e85SSai Praneeth Prakhya */ 275*591a6e85SSai Praneeth Prakhya int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp, 276*591a6e85SSai Praneeth Prakhya char *resctrl_val) 277*591a6e85SSai Praneeth Prakhya { 278*591a6e85SSai Praneeth Prakhya char controlgroup[128], monitorgroup[512], monitorgroup_p[256]; 279*591a6e85SSai Praneeth Prakhya char tasks[1024]; 280*591a6e85SSai Praneeth Prakhya int ret = 0; 281*591a6e85SSai Praneeth Prakhya 282*591a6e85SSai Praneeth Prakhya if (strlen(ctrlgrp)) 283*591a6e85SSai Praneeth Prakhya sprintf(controlgroup, "%s/%s", RESCTRL_PATH, ctrlgrp); 284*591a6e85SSai Praneeth Prakhya else 285*591a6e85SSai Praneeth Prakhya sprintf(controlgroup, "%s", RESCTRL_PATH); 286*591a6e85SSai Praneeth Prakhya 287*591a6e85SSai Praneeth Prakhya /* Create control and monitoring group and write pid into it */ 288*591a6e85SSai Praneeth Prakhya ret = create_grp(ctrlgrp, controlgroup, RESCTRL_PATH); 289*591a6e85SSai Praneeth Prakhya if (ret) 290*591a6e85SSai Praneeth Prakhya goto out; 291*591a6e85SSai Praneeth Prakhya sprintf(tasks, "%s/tasks", controlgroup); 292*591a6e85SSai Praneeth Prakhya ret = write_pid_to_tasks(tasks, bm_pid); 293*591a6e85SSai Praneeth Prakhya if (ret) 294*591a6e85SSai Praneeth Prakhya goto out; 295*591a6e85SSai Praneeth Prakhya 296*591a6e85SSai Praneeth Prakhya /* Create mon grp and write pid into it for "mbm" test */ 297*591a6e85SSai Praneeth Prakhya if ((strcmp(resctrl_val, "mbm") == 0)) { 298*591a6e85SSai Praneeth Prakhya if (mongrp) { 299*591a6e85SSai Praneeth Prakhya sprintf(monitorgroup_p, "%s/mon_groups", controlgroup); 300*591a6e85SSai Praneeth Prakhya sprintf(monitorgroup, "%s/%s", monitorgroup_p, mongrp); 301*591a6e85SSai Praneeth Prakhya ret = create_grp(mongrp, monitorgroup, monitorgroup_p); 302*591a6e85SSai Praneeth Prakhya if (ret) 303*591a6e85SSai Praneeth Prakhya goto out; 304*591a6e85SSai Praneeth Prakhya 305*591a6e85SSai Praneeth Prakhya sprintf(tasks, "%s/mon_groups/%s/tasks", 306*591a6e85SSai Praneeth Prakhya controlgroup, mongrp); 307*591a6e85SSai Praneeth Prakhya ret = write_pid_to_tasks(tasks, bm_pid); 308*591a6e85SSai Praneeth Prakhya if (ret) 309*591a6e85SSai Praneeth Prakhya goto out; 310*591a6e85SSai Praneeth Prakhya } 311*591a6e85SSai Praneeth Prakhya } 312*591a6e85SSai Praneeth Prakhya 313*591a6e85SSai Praneeth Prakhya out: 314*591a6e85SSai Praneeth Prakhya printf("%sok writing benchmark parameters to resctrl FS\n", 315*591a6e85SSai Praneeth Prakhya ret ? "not " : ""); 316*591a6e85SSai Praneeth Prakhya if (ret) 317*591a6e85SSai Praneeth Prakhya perror("# writing to resctrlfs"); 318*591a6e85SSai Praneeth Prakhya 319*591a6e85SSai Praneeth Prakhya tests_run++; 320*591a6e85SSai Praneeth Prakhya 321*591a6e85SSai Praneeth Prakhya return ret; 322*591a6e85SSai Praneeth Prakhya } 323*591a6e85SSai Praneeth Prakhya 324*591a6e85SSai Praneeth Prakhya /* 325*591a6e85SSai Praneeth Prakhya * write_schemata - Update schemata of a con_mon grp 326*591a6e85SSai Praneeth Prakhya * @ctrlgrp: Name of the con_mon grp 327*591a6e85SSai Praneeth Prakhya * @schemata: Schemata that should be updated to 328*591a6e85SSai Praneeth Prakhya * @cpu_no: CPU number that the benchmark PID is binded to 329*591a6e85SSai Praneeth Prakhya * @resctrl_val: Resctrl feature (Eg: mbm, mba.. etc) 330*591a6e85SSai Praneeth Prakhya * 331*591a6e85SSai Praneeth Prakhya * Update schemata of a con_mon grp *only* if requested resctrl feature is 332*591a6e85SSai Praneeth Prakhya * allocation type 333*591a6e85SSai Praneeth Prakhya * 334*591a6e85SSai Praneeth Prakhya * Return: 0 on success, non-zero on failure 335*591a6e85SSai Praneeth Prakhya */ 336*591a6e85SSai Praneeth Prakhya int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val) 337*591a6e85SSai Praneeth Prakhya { 338*591a6e85SSai Praneeth Prakhya char controlgroup[1024], schema[1024], reason[64]; 339*591a6e85SSai Praneeth Prakhya int resource_id, ret = 0; 340*591a6e85SSai Praneeth Prakhya FILE *fp; 341*591a6e85SSai Praneeth Prakhya 342*591a6e85SSai Praneeth Prakhya if (strcmp(resctrl_val, "mba") != 0) 343*591a6e85SSai Praneeth Prakhya return -ENOENT; 344*591a6e85SSai Praneeth Prakhya 345*591a6e85SSai Praneeth Prakhya if (!schemata) { 346*591a6e85SSai Praneeth Prakhya printf("# Skipping empty schemata update\n"); 347*591a6e85SSai Praneeth Prakhya 348*591a6e85SSai Praneeth Prakhya return -1; 349*591a6e85SSai Praneeth Prakhya } 350*591a6e85SSai Praneeth Prakhya 351*591a6e85SSai Praneeth Prakhya if (get_resource_id(cpu_no, &resource_id) < 0) { 352*591a6e85SSai Praneeth Prakhya sprintf(reason, "Failed to get resource id"); 353*591a6e85SSai Praneeth Prakhya ret = -1; 354*591a6e85SSai Praneeth Prakhya 355*591a6e85SSai Praneeth Prakhya goto out; 356*591a6e85SSai Praneeth Prakhya } 357*591a6e85SSai Praneeth Prakhya 358*591a6e85SSai Praneeth Prakhya if (strlen(ctrlgrp) != 0) 359*591a6e85SSai Praneeth Prakhya sprintf(controlgroup, "%s/%s/schemata", RESCTRL_PATH, ctrlgrp); 360*591a6e85SSai Praneeth Prakhya else 361*591a6e85SSai Praneeth Prakhya sprintf(controlgroup, "%s/schemata", RESCTRL_PATH); 362*591a6e85SSai Praneeth Prakhya 363*591a6e85SSai Praneeth Prakhya sprintf(schema, "%s%d%c%s", "MB:", resource_id, '=', schemata); 364*591a6e85SSai Praneeth Prakhya 365*591a6e85SSai Praneeth Prakhya fp = fopen(controlgroup, "w"); 366*591a6e85SSai Praneeth Prakhya if (!fp) { 367*591a6e85SSai Praneeth Prakhya sprintf(reason, "Failed to open control group"); 368*591a6e85SSai Praneeth Prakhya ret = -1; 369*591a6e85SSai Praneeth Prakhya 370*591a6e85SSai Praneeth Prakhya goto out; 371*591a6e85SSai Praneeth Prakhya } 372*591a6e85SSai Praneeth Prakhya 373*591a6e85SSai Praneeth Prakhya if (fprintf(fp, "%s\n", schema) < 0) { 374*591a6e85SSai Praneeth Prakhya sprintf(reason, "Failed to write schemata in control group"); 375*591a6e85SSai Praneeth Prakhya fclose(fp); 376*591a6e85SSai Praneeth Prakhya ret = -1; 377*591a6e85SSai Praneeth Prakhya 378*591a6e85SSai Praneeth Prakhya goto out; 379*591a6e85SSai Praneeth Prakhya } 380*591a6e85SSai Praneeth Prakhya fclose(fp); 381*591a6e85SSai Praneeth Prakhya 382*591a6e85SSai Praneeth Prakhya out: 383*591a6e85SSai Praneeth Prakhya printf("%sok Write schema \"%s\" to resctrl FS%s%s\n", 384*591a6e85SSai Praneeth Prakhya ret ? "not " : "", schema, ret ? " # " : "", 385*591a6e85SSai Praneeth Prakhya ret ? reason : ""); 386*591a6e85SSai Praneeth Prakhya tests_run++; 387*591a6e85SSai Praneeth Prakhya 388*591a6e85SSai Praneeth Prakhya return ret; 389*591a6e85SSai Praneeth Prakhya } 390*591a6e85SSai Praneeth Prakhya 391*591a6e85SSai Praneeth Prakhya char *fgrep(FILE *inf, const char *str) 392*591a6e85SSai Praneeth Prakhya { 393*591a6e85SSai Praneeth Prakhya char line[256]; 394*591a6e85SSai Praneeth Prakhya int slen = strlen(str); 395*591a6e85SSai Praneeth Prakhya 396*591a6e85SSai Praneeth Prakhya while (!feof(inf)) { 397*591a6e85SSai Praneeth Prakhya if (!fgets(line, 256, inf)) 398*591a6e85SSai Praneeth Prakhya break; 399*591a6e85SSai Praneeth Prakhya if (strncmp(line, str, slen)) 400*591a6e85SSai Praneeth Prakhya continue; 401*591a6e85SSai Praneeth Prakhya 402*591a6e85SSai Praneeth Prakhya return strdup(line); 403*591a6e85SSai Praneeth Prakhya } 404*591a6e85SSai Praneeth Prakhya 405*591a6e85SSai Praneeth Prakhya return NULL; 406*591a6e85SSai Praneeth Prakhya } 407*591a6e85SSai Praneeth Prakhya 408*591a6e85SSai Praneeth Prakhya /* 409*591a6e85SSai Praneeth Prakhya * validate_resctrl_feature_request - Check if requested feature is valid. 410*591a6e85SSai Praneeth Prakhya * @resctrl_val: Requested feature 411*591a6e85SSai Praneeth Prakhya * 412*591a6e85SSai Praneeth Prakhya * Return: 0 on success, non-zero on failure 413*591a6e85SSai Praneeth Prakhya */ 414*591a6e85SSai Praneeth Prakhya bool validate_resctrl_feature_request(char *resctrl_val) 415*591a6e85SSai Praneeth Prakhya { 416*591a6e85SSai Praneeth Prakhya FILE *inf = fopen("/proc/cpuinfo", "r"); 417*591a6e85SSai Praneeth Prakhya bool found = false; 418*591a6e85SSai Praneeth Prakhya char *res; 419*591a6e85SSai Praneeth Prakhya 420*591a6e85SSai Praneeth Prakhya if (!inf) 421*591a6e85SSai Praneeth Prakhya return false; 422*591a6e85SSai Praneeth Prakhya 423*591a6e85SSai Praneeth Prakhya res = fgrep(inf, "flags"); 424*591a6e85SSai Praneeth Prakhya 425*591a6e85SSai Praneeth Prakhya if (res) { 426*591a6e85SSai Praneeth Prakhya char *s = strchr(res, ':'); 427*591a6e85SSai Praneeth Prakhya 428*591a6e85SSai Praneeth Prakhya found = s && !strstr(s, resctrl_val); 429*591a6e85SSai Praneeth Prakhya free(res); 430*591a6e85SSai Praneeth Prakhya } 431*591a6e85SSai Praneeth Prakhya fclose(inf); 432*591a6e85SSai Praneeth Prakhya 433*591a6e85SSai Praneeth Prakhya return found; 434*591a6e85SSai Praneeth Prakhya } 435*591a6e85SSai Praneeth Prakhya 436*591a6e85SSai Praneeth Prakhya int validate_bw_report_request(char *bw_report) 437*591a6e85SSai Praneeth Prakhya { 438*591a6e85SSai Praneeth Prakhya if (strcmp(bw_report, "reads") == 0) 439*591a6e85SSai Praneeth Prakhya return 0; 440*591a6e85SSai Praneeth Prakhya if (strcmp(bw_report, "writes") == 0) 441*591a6e85SSai Praneeth Prakhya return 0; 442*591a6e85SSai Praneeth Prakhya if (strcmp(bw_report, "nt-writes") == 0) { 443*591a6e85SSai Praneeth Prakhya strcpy(bw_report, "writes"); 444*591a6e85SSai Praneeth Prakhya return 0; 445*591a6e85SSai Praneeth Prakhya } 446*591a6e85SSai Praneeth Prakhya if (strcmp(bw_report, "total") == 0) 447*591a6e85SSai Praneeth Prakhya return 0; 448*591a6e85SSai Praneeth Prakhya 449*591a6e85SSai Praneeth Prakhya fprintf(stderr, "Requested iMC B/W report type unavailable\n"); 450*591a6e85SSai Praneeth Prakhya 451*591a6e85SSai Praneeth Prakhya return -1; 452*591a6e85SSai Praneeth Prakhya } 453*591a6e85SSai Praneeth Prakhya 454*591a6e85SSai Praneeth Prakhya int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, 455*591a6e85SSai Praneeth Prakhya int group_fd, unsigned long flags) 456*591a6e85SSai Praneeth Prakhya { 457*591a6e85SSai Praneeth Prakhya int ret; 458*591a6e85SSai Praneeth Prakhya 459*591a6e85SSai Praneeth Prakhya ret = syscall(__NR_perf_event_open, hw_event, pid, cpu, 460*591a6e85SSai Praneeth Prakhya group_fd, flags); 461*591a6e85SSai Praneeth Prakhya return ret; 462*591a6e85SSai Praneeth Prakhya } 463