diff options
| -rw-r--r-- | Documentation/cgroup-v2.txt | 12 | ||||
| -rw-r--r-- | kernel/events/core.c | 6 | ||||
| -rw-r--r-- | tools/perf/util/cgroup.c | 26 | 
3 files changed, 37 insertions, 7 deletions
| diff --git a/Documentation/cgroup-v2.txt b/Documentation/cgroup-v2.txt index f6f54107fb4d..227ce4883720 100644 --- a/Documentation/cgroup-v2.txt +++ b/Documentation/cgroup-v2.txt @@ -49,6 +49,8 @@ CONTENTS      5-3-2. Writeback    5-4. PID      5-4-1. PID Interface Files +  5-5. Misc +    5-5-1. perf_event  6. Namespace    6-1. Basics    6-2. The Root and Views @@ -1160,6 +1162,16 @@ through fork() or clone(). These will return -EAGAIN if the creation  of a new process would cause a cgroup policy to be violated. +5-5. Misc + +5-5-1. perf_event + +perf_event controller, if not mounted on a legacy hierarchy, is +automatically enabled on the v2 hierarchy so that perf events can +always be filtered by cgroup v2 path.  The controller can still be +moved to a legacy hierarchy after v2 hierarchy is populated. + +  6. Namespace  6-1. Basics diff --git a/kernel/events/core.c b/kernel/events/core.c index ab15509fab8c..d72128dce1e0 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -10792,5 +10792,11 @@ struct cgroup_subsys perf_event_cgrp_subsys = {  	.css_alloc	= perf_cgroup_css_alloc,  	.css_free	= perf_cgroup_css_free,  	.attach		= perf_cgroup_attach, +	/* +	 * Implicitly enable on dfl hierarchy so that perf events can +	 * always be filtered by cgroup2 path as long as perf_event +	 * controller is not mounted on a legacy hierarchy. +	 */ +	.implicit_on_dfl = true,  };  #endif /* CONFIG_CGROUP_PERF */ diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 8fdee24725a7..eafbf11442b2 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -12,8 +12,8 @@ cgroupfs_find_mountpoint(char *buf, size_t maxlen)  {  	FILE *fp;  	char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1]; +	char path_v1[PATH_MAX + 1], path_v2[PATH_MAX + 2], *path;  	char *token, *saved_ptr = NULL; -	int found = 0;  	fp = fopen("/proc/mounts", "r");  	if (!fp) @@ -24,31 +24,43 @@ cgroupfs_find_mountpoint(char *buf, size_t maxlen)  	 * and inspect every cgroupfs mount point to find one that has  	 * perf_event subsystem  	 */ +	path_v1[0] = '\0'; +	path_v2[0] = '\0'; +  	while (fscanf(fp, "%*s %"STR(PATH_MAX)"s %"STR(PATH_MAX)"s %"  				STR(PATH_MAX)"s %*d %*d\n",  				mountpoint, type, tokens) == 3) { -		if (!strcmp(type, "cgroup")) { +		if (!path_v1[0] && !strcmp(type, "cgroup")) {  			token = strtok_r(tokens, ",", &saved_ptr);  			while (token != NULL) {  				if (!strcmp(token, "perf_event")) { -					found = 1; +					strcpy(path_v1, mountpoint);  					break;  				}  				token = strtok_r(NULL, ",", &saved_ptr);  			}  		} -		if (found) + +		if (!path_v2[0] && !strcmp(type, "cgroup2")) +			strcpy(path_v2, mountpoint); + +		if (path_v1[0] && path_v2[0])  			break;  	}  	fclose(fp); -	if (!found) + +	if (path_v1[0]) +		path = path_v1; +	else if (path_v2[0]) +		path = path_v2; +	else  		return -1; -	if (strlen(mountpoint) < maxlen) { -		strcpy(buf, mountpoint); +	if (strlen(path) < maxlen) { +		strcpy(buf, path);  		return 0;  	}  	return -1; | 
