xref: /linux/tools/testing/selftests/resctrl/resctrlfs.c (revision e814f3fd16acfb7f9966773953de8f740a1e3202)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Basic resctrl file system operations
4  *
5  * Copyright (C) 2018 Intel Corporation
6  *
7  * Authors:
8  *    Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>,
9  *    Fenghua Yu <fenghua.yu@intel.com>
10  */
11 #include <fcntl.h>
12 #include <limits.h>
13 
14 #include "resctrl.h"
15 
16 int snc_unreliable;
17 
18 static int find_resctrl_mount(char *buffer)
19 {
20 	FILE *mounts;
21 	char line[256], *fs, *mntpoint;
22 
23 	mounts = fopen("/proc/mounts", "r");
24 	if (!mounts) {
25 		ksft_perror("/proc/mounts");
26 		return -ENXIO;
27 	}
28 	while (!feof(mounts)) {
29 		if (!fgets(line, 256, mounts))
30 			break;
31 		fs = strtok(line, " \t");
32 		if (!fs)
33 			continue;
34 		mntpoint = strtok(NULL, " \t");
35 		if (!mntpoint)
36 			continue;
37 		fs = strtok(NULL, " \t");
38 		if (!fs)
39 			continue;
40 		if (strcmp(fs, "resctrl"))
41 			continue;
42 
43 		fclose(mounts);
44 		if (buffer)
45 			strncpy(buffer, mntpoint, 256);
46 
47 		return 0;
48 	}
49 
50 	fclose(mounts);
51 
52 	return -ENOENT;
53 }
54 
55 /*
56  * mount_resctrlfs - Mount resctrl FS at /sys/fs/resctrl
57  *
58  * Mounts resctrl FS. Fails if resctrl FS is already mounted to avoid
59  * pre-existing settings interfering with the test results.
60  *
61  * Return: 0 on success, < 0 on error.
62  */
63 int mount_resctrlfs(void)
64 {
65 	int ret;
66 
67 	ret = find_resctrl_mount(NULL);
68 	if (ret != -ENOENT)
69 		return -1;
70 
71 	ksft_print_msg("Mounting resctrl to \"%s\"\n", RESCTRL_PATH);
72 	ret = mount("resctrl", RESCTRL_PATH, "resctrl", 0, NULL);
73 	if (ret)
74 		ksft_perror("mount");
75 
76 	return ret;
77 }
78 
79 int umount_resctrlfs(void)
80 {
81 	char mountpoint[256];
82 	int ret;
83 
84 	ret = find_resctrl_mount(mountpoint);
85 	if (ret == -ENOENT)
86 		return 0;
87 	if (ret)
88 		return ret;
89 
90 	if (umount(mountpoint)) {
91 		ksft_perror("Unable to umount resctrl");
92 
93 		return -1;
94 	}
95 
96 	return 0;
97 }
98 
99 /*
100  * get_cache_level - Convert cache level from string to integer
101  * @cache_type:		Cache level as string
102  *
103  * Return: cache level as integer or -1 if @cache_type is invalid.
104  */
105 static int get_cache_level(const char *cache_type)
106 {
107 	if (!strcmp(cache_type, "L3"))
108 		return 3;
109 	if (!strcmp(cache_type, "L2"))
110 		return 2;
111 
112 	ksft_print_msg("Invalid cache level\n");
113 	return -1;
114 }
115 
116 static int get_resource_cache_level(const char *resource)
117 {
118 	/* "MB" use L3 (LLC) as resource */
119 	if (!strcmp(resource, "MB"))
120 		return 3;
121 	return get_cache_level(resource);
122 }
123 
124 /*
125  * get_domain_id - Get resctrl domain ID for a specified CPU
126  * @resource:	resource name
127  * @cpu_no:	CPU number
128  * @domain_id:	domain ID (cache ID; for MB, L3 cache ID)
129  *
130  * Return: >= 0 on success, < 0 on failure.
131  */
132 int get_domain_id(const char *resource, int cpu_no, int *domain_id)
133 {
134 	char phys_pkg_path[1024];
135 	int cache_num;
136 	FILE *fp;
137 
138 	cache_num = get_resource_cache_level(resource);
139 	if (cache_num < 0)
140 		return cache_num;
141 
142 	sprintf(phys_pkg_path, "%s%d/cache/index%d/id", PHYS_ID_PATH, cpu_no, cache_num);
143 
144 	fp = fopen(phys_pkg_path, "r");
145 	if (!fp) {
146 		ksft_perror("Failed to open cache id file");
147 
148 		return -1;
149 	}
150 	if (fscanf(fp, "%d", domain_id) <= 0) {
151 		ksft_perror("Could not get domain ID");
152 		fclose(fp);
153 
154 		return -1;
155 	}
156 	fclose(fp);
157 
158 	return 0;
159 }
160 
161 /*
162  * Count number of CPUs in a /sys bitmap
163  */
164 static unsigned int count_sys_bitmap_bits(char *name)
165 {
166 	FILE *fp = fopen(name, "r");
167 	int count = 0, c;
168 
169 	if (!fp)
170 		return 0;
171 
172 	while ((c = fgetc(fp)) != EOF) {
173 		if (!isxdigit(c))
174 			continue;
175 		switch (c) {
176 		case 'f':
177 			count++;
178 			fallthrough;
179 		case '7': case 'b': case 'd': case 'e':
180 			count++;
181 			fallthrough;
182 		case '3': case '5': case '6': case '9': case 'a': case 'c':
183 			count++;
184 			fallthrough;
185 		case '1': case '2': case '4': case '8':
186 			count++;
187 			break;
188 		}
189 	}
190 	fclose(fp);
191 
192 	return count;
193 }
194 
195 static bool cpus_offline_empty(void)
196 {
197 	char offline_cpus_str[64];
198 	FILE *fp;
199 
200 	fp = fopen("/sys/devices/system/cpu/offline", "r");
201 	if (!fp) {
202 		ksft_perror("Could not open /sys/devices/system/cpu/offline");
203 		return 0;
204 	}
205 
206 	if (fscanf(fp, "%63s", offline_cpus_str) < 0) {
207 		if (!errno) {
208 			fclose(fp);
209 			return 1;
210 		}
211 		ksft_perror("Could not read /sys/devices/system/cpu/offline");
212 	}
213 
214 	fclose(fp);
215 
216 	return 0;
217 }
218 
219 /*
220  * Detect SNC by comparing #CPUs in node0 with #CPUs sharing LLC with CPU0.
221  * If any CPUs are offline declare the detection as unreliable.
222  */
223 int snc_nodes_per_l3_cache(void)
224 {
225 	int node_cpus, cache_cpus;
226 	static int snc_mode;
227 
228 	if (!snc_mode) {
229 		snc_mode = 1;
230 		if (!cpus_offline_empty()) {
231 			ksft_print_msg("Runtime SNC detection unreliable due to offline CPUs.\n");
232 			ksft_print_msg("Setting SNC mode to disabled.\n");
233 			snc_unreliable = 1;
234 			return snc_mode;
235 		}
236 		node_cpus = count_sys_bitmap_bits("/sys/devices/system/node/node0/cpumap");
237 		cache_cpus = count_sys_bitmap_bits("/sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_map");
238 
239 		if (!node_cpus || !cache_cpus) {
240 			ksft_print_msg("Could not determine Sub-NUMA Cluster mode.\n");
241 			snc_unreliable = 1;
242 			return snc_mode;
243 		}
244 		snc_mode = cache_cpus / node_cpus;
245 
246 		if (snc_mode > 1)
247 			ksft_print_msg("SNC-%d mode discovered.\n", snc_mode);
248 	}
249 
250 	return snc_mode;
251 }
252 
253 /*
254  * get_cache_size - Get cache size for a specified CPU
255  * @cpu_no:	CPU number
256  * @cache_type:	Cache level L2/L3
257  * @cache_size:	pointer to cache_size
258  *
259  * Return: = 0 on success, < 0 on failure.
260  */
261 int get_cache_size(int cpu_no, const char *cache_type, unsigned long *cache_size)
262 {
263 	char cache_path[1024], cache_str[64];
264 	int length, i, cache_num;
265 	FILE *fp;
266 
267 	cache_num = get_cache_level(cache_type);
268 	if (cache_num < 0)
269 		return cache_num;
270 
271 	sprintf(cache_path, "/sys/bus/cpu/devices/cpu%d/cache/index%d/size",
272 		cpu_no, cache_num);
273 	fp = fopen(cache_path, "r");
274 	if (!fp) {
275 		ksft_perror("Failed to open cache size");
276 
277 		return -1;
278 	}
279 	if (fscanf(fp, "%63s", cache_str) <= 0) {
280 		ksft_perror("Could not get cache_size");
281 		fclose(fp);
282 
283 		return -1;
284 	}
285 	fclose(fp);
286 
287 	length = (int)strlen(cache_str);
288 
289 	*cache_size = 0;
290 
291 	for (i = 0; i < length; i++) {
292 		if ((cache_str[i] >= '0') && (cache_str[i] <= '9'))
293 
294 			*cache_size = *cache_size * 10 + (cache_str[i] - '0');
295 
296 		else if (cache_str[i] == 'K')
297 
298 			*cache_size = *cache_size * 1024;
299 
300 		else if (cache_str[i] == 'M')
301 
302 			*cache_size = *cache_size * 1024 * 1024;
303 
304 		else
305 			break;
306 	}
307 
308 	/*
309 	 * The amount of cache represented by each bit in the masks
310 	 * in the schemata file is reduced by a factor equal to SNC
311 	 * nodes per L3 cache.
312 	 * E.g. on a SNC-2 system with a 100MB L3 cache a test that
313 	 * allocates memory from its local SNC node (default behavior
314 	 * without using libnuma) will only see 50 MB llc_occupancy
315 	 * with a fully populated L3 mask in the schemata file.
316 	 */
317 	if (cache_num == 3)
318 		*cache_size /= snc_nodes_per_l3_cache();
319 	return 0;
320 }
321 
322 #define CORE_SIBLINGS_PATH	"/sys/bus/cpu/devices/cpu"
323 
324 /*
325  * get_bit_mask - Get bit mask from given file
326  * @filename:	File containing the mask
327  * @mask:	The bit mask returned as unsigned long
328  *
329  * Return: = 0 on success, < 0 on failure.
330  */
331 static int get_bit_mask(const char *filename, unsigned long *mask)
332 {
333 	FILE *fp;
334 
335 	if (!filename || !mask)
336 		return -1;
337 
338 	fp = fopen(filename, "r");
339 	if (!fp) {
340 		ksft_print_msg("Failed to open bit mask file '%s': %s\n",
341 			       filename, strerror(errno));
342 		return -1;
343 	}
344 
345 	if (fscanf(fp, "%lx", mask) <= 0) {
346 		ksft_print_msg("Could not read bit mask file '%s': %s\n",
347 			       filename, strerror(errno));
348 		fclose(fp);
349 
350 		return -1;
351 	}
352 	fclose(fp);
353 
354 	return 0;
355 }
356 
357 /*
358  * resource_info_unsigned_get - Read an unsigned value from
359  * /sys/fs/resctrl/info/@resource/@filename
360  * @resource:	Resource name that matches directory name in
361  *		/sys/fs/resctrl/info
362  * @filename:	File in /sys/fs/resctrl/info/@resource
363  * @val:	Contains read value on success.
364  *
365  * Return: = 0 on success, < 0 on failure. On success the read
366  * value is saved into @val.
367  */
368 int resource_info_unsigned_get(const char *resource, const char *filename,
369 			       unsigned int *val)
370 {
371 	char file_path[PATH_MAX];
372 	FILE *fp;
373 
374 	snprintf(file_path, sizeof(file_path), "%s/%s/%s", INFO_PATH, resource,
375 		 filename);
376 
377 	fp = fopen(file_path, "r");
378 	if (!fp) {
379 		ksft_print_msg("Error opening %s: %m\n", file_path);
380 		return -1;
381 	}
382 
383 	if (fscanf(fp, "%u", val) <= 0) {
384 		ksft_print_msg("Could not get contents of %s: %m\n", file_path);
385 		fclose(fp);
386 		return -1;
387 	}
388 
389 	fclose(fp);
390 	return 0;
391 }
392 
393 /*
394  * create_bit_mask- Create bit mask from start, len pair
395  * @start:	LSB of the mask
396  * @len		Number of bits in the mask
397  */
398 unsigned long create_bit_mask(unsigned int start, unsigned int len)
399 {
400 	return ((1UL << len) - 1UL) << start;
401 }
402 
403 /*
404  * count_contiguous_bits - Returns the longest train of bits in a bit mask
405  * @val		A bit mask
406  * @start	The location of the least-significant bit of the longest train
407  *
408  * Return:	The length of the contiguous bits in the longest train of bits
409  */
410 unsigned int count_contiguous_bits(unsigned long val, unsigned int *start)
411 {
412 	unsigned long last_val;
413 	unsigned int count = 0;
414 
415 	while (val) {
416 		last_val = val;
417 		val &= (val >> 1);
418 		count++;
419 	}
420 
421 	if (start) {
422 		if (count)
423 			*start = ffsl(last_val) - 1;
424 		else
425 			*start = 0;
426 	}
427 
428 	return count;
429 }
430 
431 /*
432  * get_full_cbm - Get full Cache Bit Mask (CBM)
433  * @cache_type:	Cache type as "L2" or "L3"
434  * @mask:	Full cache bit mask representing the maximal portion of cache
435  *		available for allocation, returned as unsigned long.
436  *
437  * Return: = 0 on success, < 0 on failure.
438  */
439 int get_full_cbm(const char *cache_type, unsigned long *mask)
440 {
441 	char cbm_path[PATH_MAX];
442 	int ret;
443 
444 	if (!cache_type)
445 		return -1;
446 
447 	snprintf(cbm_path, sizeof(cbm_path), "%s/%s/cbm_mask",
448 		 INFO_PATH, cache_type);
449 
450 	ret = get_bit_mask(cbm_path, mask);
451 	if (ret || !*mask)
452 		return -1;
453 
454 	return 0;
455 }
456 
457 /*
458  * get_shareable_mask - Get shareable mask from shareable_bits
459  * @cache_type:		Cache type as "L2" or "L3"
460  * @shareable_mask:	Shareable mask returned as unsigned long
461  *
462  * Return: = 0 on success, < 0 on failure.
463  */
464 static int get_shareable_mask(const char *cache_type, unsigned long *shareable_mask)
465 {
466 	char mask_path[PATH_MAX];
467 
468 	if (!cache_type)
469 		return -1;
470 
471 	snprintf(mask_path, sizeof(mask_path), "%s/%s/shareable_bits",
472 		 INFO_PATH, cache_type);
473 
474 	return get_bit_mask(mask_path, shareable_mask);
475 }
476 
477 /*
478  * get_mask_no_shareable - Get Cache Bit Mask (CBM) without shareable bits
479  * @cache_type:		Cache type as "L2" or "L3"
480  * @mask:		The largest exclusive portion of the cache out of the
481  *			full CBM, returned as unsigned long
482  *
483  * Parts of a cache may be shared with other devices such as GPU. This function
484  * calculates the largest exclusive portion of the cache where no other devices
485  * besides CPU have access to the cache portion.
486  *
487  * Return: = 0 on success, < 0 on failure.
488  */
489 int get_mask_no_shareable(const char *cache_type, unsigned long *mask)
490 {
491 	unsigned long full_mask, shareable_mask;
492 	unsigned int start, len;
493 
494 	if (get_full_cbm(cache_type, &full_mask) < 0)
495 		return -1;
496 	if (get_shareable_mask(cache_type, &shareable_mask) < 0)
497 		return -1;
498 
499 	len = count_contiguous_bits(full_mask & ~shareable_mask, &start);
500 	if (!len)
501 		return -1;
502 
503 	*mask = create_bit_mask(start, len);
504 
505 	return 0;
506 }
507 
508 /*
509  * taskset_benchmark - Taskset PID (i.e. benchmark) to a specified cpu
510  * @bm_pid:		PID that should be binded
511  * @cpu_no:		CPU number at which the PID would be binded
512  * @old_affinity:	When not NULL, set to old CPU affinity
513  *
514  * Return: 0 on success, < 0 on error.
515  */
516 int taskset_benchmark(pid_t bm_pid, int cpu_no, cpu_set_t *old_affinity)
517 {
518 	cpu_set_t my_set;
519 
520 	if (old_affinity) {
521 		CPU_ZERO(old_affinity);
522 		if (sched_getaffinity(bm_pid, sizeof(*old_affinity),
523 				      old_affinity)) {
524 			ksft_perror("Unable to read CPU affinity");
525 			return -1;
526 		}
527 	}
528 
529 	CPU_ZERO(&my_set);
530 	CPU_SET(cpu_no, &my_set);
531 
532 	if (sched_setaffinity(bm_pid, sizeof(cpu_set_t), &my_set)) {
533 		ksft_perror("Unable to taskset benchmark");
534 
535 		return -1;
536 	}
537 
538 	return 0;
539 }
540 
541 /*
542  * taskset_restore - Taskset PID to the earlier CPU affinity
543  * @bm_pid:		PID that should be reset
544  * @old_affinity:	The old CPU affinity to restore
545  *
546  * Return: 0 on success, < 0 on error.
547  */
548 int taskset_restore(pid_t bm_pid, cpu_set_t *old_affinity)
549 {
550 	if (sched_setaffinity(bm_pid, sizeof(*old_affinity), old_affinity)) {
551 		ksft_perror("Unable to restore CPU affinity");
552 		return -1;
553 	}
554 
555 	return 0;
556 }
557 
558 /*
559  * create_grp - Create a group only if one doesn't exist
560  * @grp_name:	Name of the group
561  * @grp:	Full path and name of the group
562  * @parent_grp:	Full path and name of the parent group
563  *
564  * Creates a group @grp_name if it does not exist yet. If @grp_name is NULL,
565  * it is interpreted as the root group which always results in success.
566  *
567  * Return: 0 on success, < 0 on error.
568  */
569 static int create_grp(const char *grp_name, char *grp, const char *parent_grp)
570 {
571 	int found_grp = 0;
572 	struct dirent *ep;
573 	DIR *dp;
574 
575 	if (!grp_name)
576 		return 0;
577 
578 	/* Check if requested grp exists or not */
579 	dp = opendir(parent_grp);
580 	if (dp) {
581 		while ((ep = readdir(dp)) != NULL) {
582 			if (strcmp(ep->d_name, grp_name) == 0)
583 				found_grp = 1;
584 		}
585 		closedir(dp);
586 	} else {
587 		ksft_perror("Unable to open resctrl for group");
588 
589 		return -1;
590 	}
591 
592 	/* Requested grp doesn't exist, hence create it */
593 	if (found_grp == 0) {
594 		if (mkdir(grp, 0) == -1) {
595 			ksft_perror("Unable to create group");
596 
597 			return -1;
598 		}
599 	}
600 
601 	return 0;
602 }
603 
604 static int write_pid_to_tasks(char *tasks, pid_t pid)
605 {
606 	FILE *fp;
607 
608 	fp = fopen(tasks, "w");
609 	if (!fp) {
610 		ksft_perror("Failed to open tasks file");
611 
612 		return -1;
613 	}
614 	if (fprintf(fp, "%d\n", (int)pid) < 0) {
615 		ksft_print_msg("Failed to write pid to tasks file\n");
616 		fclose(fp);
617 
618 		return -1;
619 	}
620 	fclose(fp);
621 
622 	return 0;
623 }
624 
625 /*
626  * write_bm_pid_to_resctrl - Write a PID (i.e. benchmark) to resctrl FS
627  * @bm_pid:		PID that should be written
628  * @ctrlgrp:		Name of the control monitor group (con_mon grp)
629  * @mongrp:		Name of the monitor group (mon grp)
630  *
631  * If a con_mon grp is requested, create it and write pid to it, otherwise
632  * write pid to root con_mon grp.
633  * If a mon grp is requested, create it and write pid to it, otherwise
634  * pid is not written, this means that pid is in con_mon grp and hence
635  * should consult con_mon grp's mon_data directory for results.
636  *
637  * Return: 0 on success, < 0 on error.
638  */
639 int write_bm_pid_to_resctrl(pid_t bm_pid, const char *ctrlgrp, const char *mongrp)
640 {
641 	char controlgroup[128], monitorgroup[512], monitorgroup_p[256];
642 	char tasks[1024];
643 	int ret = 0;
644 
645 	if (ctrlgrp)
646 		sprintf(controlgroup, "%s/%s", RESCTRL_PATH, ctrlgrp);
647 	else
648 		sprintf(controlgroup, "%s", RESCTRL_PATH);
649 
650 	/* Create control and monitoring group and write pid into it */
651 	ret = create_grp(ctrlgrp, controlgroup, RESCTRL_PATH);
652 	if (ret)
653 		goto out;
654 	sprintf(tasks, "%s/tasks", controlgroup);
655 	ret = write_pid_to_tasks(tasks, bm_pid);
656 	if (ret)
657 		goto out;
658 
659 	/* Create monitor group and write pid into if it is used */
660 	if (mongrp) {
661 		sprintf(monitorgroup_p, "%s/mon_groups", controlgroup);
662 		sprintf(monitorgroup, "%s/%s", monitorgroup_p, mongrp);
663 		ret = create_grp(mongrp, monitorgroup, monitorgroup_p);
664 		if (ret)
665 			goto out;
666 
667 		sprintf(tasks, "%s/mon_groups/%s/tasks",
668 			controlgroup, mongrp);
669 		ret = write_pid_to_tasks(tasks, bm_pid);
670 		if (ret)
671 			goto out;
672 	}
673 
674 out:
675 	ksft_print_msg("Writing benchmark parameters to resctrl FS\n");
676 	if (ret)
677 		ksft_print_msg("Failed writing to resctrlfs\n");
678 
679 	return ret;
680 }
681 
682 /*
683  * write_schemata - Update schemata of a con_mon grp
684  * @ctrlgrp:		Name of the con_mon grp
685  * @schemata:		Schemata that should be updated to
686  * @cpu_no:		CPU number that the benchmark PID is binded to
687  * @resource:		Resctrl resource (Eg: MB, L3, L2, etc.)
688  *
689  * Update schemata of a con_mon grp *only* if requested resctrl resource is
690  * allocation type
691  *
692  * Return: 0 on success, < 0 on error.
693  */
694 int write_schemata(const char *ctrlgrp, char *schemata, int cpu_no,
695 		   const char *resource)
696 {
697 	char controlgroup[1024], reason[128], schema[1024] = {};
698 	int domain_id, fd, schema_len, ret = 0;
699 
700 	if (!schemata) {
701 		ksft_print_msg("Skipping empty schemata update\n");
702 
703 		return -1;
704 	}
705 
706 	if (get_domain_id(resource, cpu_no, &domain_id) < 0) {
707 		sprintf(reason, "Failed to get domain ID");
708 		ret = -1;
709 
710 		goto out;
711 	}
712 
713 	if (ctrlgrp)
714 		sprintf(controlgroup, "%s/%s/schemata", RESCTRL_PATH, ctrlgrp);
715 	else
716 		sprintf(controlgroup, "%s/schemata", RESCTRL_PATH);
717 
718 	schema_len = snprintf(schema, sizeof(schema), "%s:%d=%s\n",
719 			      resource, domain_id, schemata);
720 	if (schema_len < 0 || schema_len >= sizeof(schema)) {
721 		snprintf(reason, sizeof(reason),
722 			 "snprintf() failed with return value : %d", schema_len);
723 		ret = -1;
724 		goto out;
725 	}
726 
727 	fd = open(controlgroup, O_WRONLY);
728 	if (fd < 0) {
729 		snprintf(reason, sizeof(reason),
730 			 "open() failed : %s", strerror(errno));
731 		ret = -1;
732 
733 		goto err_schema_not_empty;
734 	}
735 	if (write(fd, schema, schema_len) < 0) {
736 		snprintf(reason, sizeof(reason),
737 			 "write() failed : %s", strerror(errno));
738 		close(fd);
739 		ret = -1;
740 
741 		goto err_schema_not_empty;
742 	}
743 	close(fd);
744 
745 err_schema_not_empty:
746 	schema[schema_len - 1] = 0;
747 out:
748 	ksft_print_msg("Write schema \"%s\" to resctrl FS%s%s\n",
749 		       schema, ret ? " # " : "",
750 		       ret ? reason : "");
751 
752 	return ret;
753 }
754 
755 bool check_resctrlfs_support(void)
756 {
757 	FILE *inf = fopen("/proc/filesystems", "r");
758 	DIR *dp;
759 	char *res;
760 	bool ret = false;
761 
762 	if (!inf)
763 		return false;
764 
765 	res = fgrep(inf, "nodev\tresctrl\n");
766 
767 	if (res) {
768 		ret = true;
769 		free(res);
770 	}
771 
772 	fclose(inf);
773 
774 	ksft_print_msg("%s Check kernel supports resctrl filesystem\n",
775 		       ret ? "Pass:" : "Fail:");
776 
777 	if (!ret)
778 		return ret;
779 
780 	dp = opendir(RESCTRL_PATH);
781 	ksft_print_msg("%s Check resctrl mountpoint \"%s\" exists\n",
782 		       dp ? "Pass:" : "Fail:", RESCTRL_PATH);
783 	if (dp)
784 		closedir(dp);
785 
786 	ksft_print_msg("resctrl filesystem %s mounted\n",
787 		       find_resctrl_mount(NULL) ? "not" : "is");
788 
789 	return ret;
790 }
791 
792 char *fgrep(FILE *inf, const char *str)
793 {
794 	char line[256];
795 	int slen = strlen(str);
796 
797 	while (!feof(inf)) {
798 		if (!fgets(line, 256, inf))
799 			break;
800 		if (strncmp(line, str, slen))
801 			continue;
802 
803 		return strdup(line);
804 	}
805 
806 	return NULL;
807 }
808 
809 /*
810  * resctrl_resource_exists - Check if a resource is supported.
811  * @resource:	Resctrl resource (e.g., MB, L3, L2, L3_MON, etc.)
812  *
813  * Return: True if the resource is supported, else false. False is
814  *         also returned if resctrl FS is not mounted.
815  */
816 bool resctrl_resource_exists(const char *resource)
817 {
818 	char res_path[PATH_MAX];
819 	struct stat statbuf;
820 	int ret;
821 
822 	if (!resource)
823 		return false;
824 
825 	ret = find_resctrl_mount(NULL);
826 	if (ret)
827 		return false;
828 
829 	snprintf(res_path, sizeof(res_path), "%s/%s", INFO_PATH, resource);
830 
831 	if (stat(res_path, &statbuf))
832 		return false;
833 
834 	return true;
835 }
836 
837 /*
838  * resctrl_mon_feature_exists - Check if requested monitoring feature is valid.
839  * @resource:	Resource that uses the mon_features file. Currently only L3_MON
840  *		is valid.
841  * @feature:	Required monitor feature (in mon_features file).
842  *
843  * Return: True if the feature is supported, else false.
844  */
845 bool resctrl_mon_feature_exists(const char *resource, const char *feature)
846 {
847 	char res_path[PATH_MAX];
848 	char *res;
849 	FILE *inf;
850 
851 	if (!feature || !resource)
852 		return false;
853 
854 	snprintf(res_path, sizeof(res_path), "%s/%s/mon_features", INFO_PATH, resource);
855 	inf = fopen(res_path, "r");
856 	if (!inf)
857 		return false;
858 
859 	res = fgrep(inf, feature);
860 	free(res);
861 	fclose(inf);
862 
863 	return !!res;
864 }
865 
866 /*
867  * resource_info_file_exists - Check if a file is present inside
868  * /sys/fs/resctrl/info/@resource.
869  * @resource:	Required resource (Eg: MB, L3, L2, etc.)
870  * @file:	Required file.
871  *
872  * Return: True if the /sys/fs/resctrl/info/@resource/@file exists, else false.
873  */
874 bool resource_info_file_exists(const char *resource, const char *file)
875 {
876 	char res_path[PATH_MAX];
877 	struct stat statbuf;
878 
879 	if (!file || !resource)
880 		return false;
881 
882 	snprintf(res_path, sizeof(res_path), "%s/%s/%s", INFO_PATH, resource,
883 		 file);
884 
885 	if (stat(res_path, &statbuf))
886 		return false;
887 
888 	return true;
889 }
890 
891 bool test_resource_feature_check(const struct resctrl_test *test)
892 {
893 	return resctrl_resource_exists(test->resource);
894 }
895 
896 int filter_dmesg(void)
897 {
898 	char line[1024];
899 	FILE *fp;
900 	int pipefds[2];
901 	pid_t pid;
902 	int ret;
903 
904 	ret = pipe(pipefds);
905 	if (ret) {
906 		ksft_perror("pipe");
907 		return ret;
908 	}
909 	fflush(stdout);
910 	pid = fork();
911 	if (pid == 0) {
912 		close(pipefds[0]);
913 		dup2(pipefds[1], STDOUT_FILENO);
914 		execlp("dmesg", "dmesg", NULL);
915 		ksft_perror("Executing dmesg");
916 		exit(1);
917 	}
918 	close(pipefds[1]);
919 	fp = fdopen(pipefds[0], "r");
920 	if (!fp) {
921 		ksft_perror("fdopen(pipe)");
922 		kill(pid, SIGTERM);
923 
924 		return -1;
925 	}
926 
927 	while (fgets(line, 1024, fp)) {
928 		if (strstr(line, "intel_rdt:"))
929 			ksft_print_msg("dmesg: %s", line);
930 		if (strstr(line, "resctrl:"))
931 			ksft_print_msg("dmesg: %s", line);
932 	}
933 	fclose(fp);
934 	waitpid(pid, NULL, 0);
935 
936 	return 0;
937 }
938 
939 int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
940 		    int group_fd, unsigned long flags)
941 {
942 	int ret;
943 
944 	ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
945 		      group_fd, flags);
946 	return ret;
947 }
948 
949 unsigned int count_bits(unsigned long n)
950 {
951 	unsigned int count = 0;
952 
953 	while (n) {
954 		count += n & 1;
955 		n >>= 1;
956 	}
957 
958 	return count;
959 }
960 
961 /**
962  * snc_kernel_support - Check for existence of mon_sub_L3_00 file that indicates
963  * SNC resctrl support on the kernel side.
964  *
965  * Return: 0 if not supported, 1 if SNC is disabled or SNC discovery is
966  * unreliable or SNC is both enabled and supported.
967  */
968 int snc_kernel_support(void)
969 {
970 	char node_path[PATH_MAX];
971 	struct stat statbuf;
972 	int ret;
973 
974 	ret = snc_nodes_per_l3_cache();
975 	/*
976 	 * If SNC is disabled then its kernel support isn't important. If SNC
977 	 * got disabled because the discovery process was unreliable the
978 	 * snc_unreliable variable was set. It can be used to verify the SNC
979 	 * discovery reliability elsewhere in the selftest.
980 	 */
981 	if (ret == 1)
982 		return ret;
983 
984 	snprintf(node_path, sizeof(node_path), "%s/%s", RESCTRL_PATH,
985 		 "mon_data/mon_L3_00/mon_sub_L3_00");
986 
987 	if (!stat(node_path, &statbuf))
988 		return 1;
989 
990 	return 0;
991 }
992