 1d037ca164
			
		
	
	
	1d037ca164
	
	
	
		
			
			perf defines both __used and __unused variables to use for marking
unused variables. The variable __used is defined to
__attribute__((__unused__)), which contradicts the kernel definition to
__attribute__((__used__)) for new gcc versions. On Android, __used is
also defined in system headers and this leads to warnings like: warning:
'__used__' attribute ignored
__unused is not defined in the kernel and is not a standard definition.
If __unused is included everywhere instead of __used, this leads to
conflicts with glibc headers, since glibc has a variables with this name
in its headers.
The best approach is to use __maybe_unused, the definition used in the
kernel for __attribute__((unused)). In this way there is only one
definition in perf sources (instead of 2 definitions that point to the
same thing: __used and __unused) and it works on both Linux and Android.
This patch simply replaces all instances of __used and __unused with
__maybe_unused.
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Pekka Enberg <penberg@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/1347315303-29906-7-git-send-email-irina.tirdea@intel.com
[ committer note: fixed up conflict with a116e05 in builtin-sched.c ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
		
	
			
		
			
				
	
	
		
			177 lines
		
	
	
	
		
			3.1 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
	
		
			3.1 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "util.h"
 | |
| #include "../perf.h"
 | |
| #include "parse-options.h"
 | |
| #include "evsel.h"
 | |
| #include "cgroup.h"
 | |
| #include "evlist.h"
 | |
| 
 | |
| int nr_cgroups;
 | |
| 
 | |
| static int
 | |
| cgroupfs_find_mountpoint(char *buf, size_t maxlen)
 | |
| {
 | |
| 	FILE *fp;
 | |
| 	char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1];
 | |
| 	char *token, *saved_ptr = NULL;
 | |
| 	int found = 0;
 | |
| 
 | |
| 	fp = fopen("/proc/mounts", "r");
 | |
| 	if (!fp)
 | |
| 		return -1;
 | |
| 
 | |
| 	/*
 | |
| 	 * in order to handle split hierarchy, we need to scan /proc/mounts
 | |
| 	 * and inspect every cgroupfs mount point to find one that has
 | |
| 	 * perf_event subsystem
 | |
| 	 */
 | |
| 	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")) {
 | |
| 
 | |
| 			token = strtok_r(tokens, ",", &saved_ptr);
 | |
| 
 | |
| 			while (token != NULL) {
 | |
| 				if (!strcmp(token, "perf_event")) {
 | |
| 					found = 1;
 | |
| 					break;
 | |
| 				}
 | |
| 				token = strtok_r(NULL, ",", &saved_ptr);
 | |
| 			}
 | |
| 		}
 | |
| 		if (found)
 | |
| 			break;
 | |
| 	}
 | |
| 	fclose(fp);
 | |
| 	if (!found)
 | |
| 		return -1;
 | |
| 
 | |
| 	if (strlen(mountpoint) < maxlen) {
 | |
| 		strcpy(buf, mountpoint);
 | |
| 		return 0;
 | |
| 	}
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| static int open_cgroup(char *name)
 | |
| {
 | |
| 	char path[PATH_MAX + 1];
 | |
| 	char mnt[PATH_MAX + 1];
 | |
| 	int fd;
 | |
| 
 | |
| 
 | |
| 	if (cgroupfs_find_mountpoint(mnt, PATH_MAX + 1))
 | |
| 		return -1;
 | |
| 
 | |
| 	snprintf(path, PATH_MAX, "%s/%s", mnt, name);
 | |
| 
 | |
| 	fd = open(path, O_RDONLY);
 | |
| 	if (fd == -1)
 | |
| 		fprintf(stderr, "no access to cgroup %s\n", path);
 | |
| 
 | |
| 	return fd;
 | |
| }
 | |
| 
 | |
| static int add_cgroup(struct perf_evlist *evlist, char *str)
 | |
| {
 | |
| 	struct perf_evsel *counter;
 | |
| 	struct cgroup_sel *cgrp = NULL;
 | |
| 	int n;
 | |
| 	/*
 | |
| 	 * check if cgrp is already defined, if so we reuse it
 | |
| 	 */
 | |
| 	list_for_each_entry(counter, &evlist->entries, node) {
 | |
| 		cgrp = counter->cgrp;
 | |
| 		if (!cgrp)
 | |
| 			continue;
 | |
| 		if (!strcmp(cgrp->name, str))
 | |
| 			break;
 | |
| 
 | |
| 		cgrp = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (!cgrp) {
 | |
| 		cgrp = zalloc(sizeof(*cgrp));
 | |
| 		if (!cgrp)
 | |
| 			return -1;
 | |
| 
 | |
| 		cgrp->name = str;
 | |
| 
 | |
| 		cgrp->fd = open_cgroup(str);
 | |
| 		if (cgrp->fd == -1) {
 | |
| 			free(cgrp);
 | |
| 			return -1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * find corresponding event
 | |
| 	 * if add cgroup N, then need to find event N
 | |
| 	 */
 | |
| 	n = 0;
 | |
| 	list_for_each_entry(counter, &evlist->entries, node) {
 | |
| 		if (n == nr_cgroups)
 | |
| 			goto found;
 | |
| 		n++;
 | |
| 	}
 | |
| 	if (cgrp->refcnt == 0)
 | |
| 		free(cgrp);
 | |
| 
 | |
| 	return -1;
 | |
| found:
 | |
| 	cgrp->refcnt++;
 | |
| 	counter->cgrp = cgrp;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| void close_cgroup(struct cgroup_sel *cgrp)
 | |
| {
 | |
| 	if (!cgrp)
 | |
| 		return;
 | |
| 
 | |
| 	/* XXX: not reentrant */
 | |
| 	if (--cgrp->refcnt == 0) {
 | |
| 		close(cgrp->fd);
 | |
| 		free(cgrp->name);
 | |
| 		free(cgrp);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int parse_cgroups(const struct option *opt __maybe_unused, const char *str,
 | |
| 		  int unset __maybe_unused)
 | |
| {
 | |
| 	struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
 | |
| 	const char *p, *e, *eos = str + strlen(str);
 | |
| 	char *s;
 | |
| 	int ret;
 | |
| 
 | |
| 	if (list_empty(&evlist->entries)) {
 | |
| 		fprintf(stderr, "must define events before cgroups\n");
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	for (;;) {
 | |
| 		p = strchr(str, ',');
 | |
| 		e = p ? p : eos;
 | |
| 
 | |
| 		/* allow empty cgroups, i.e., skip */
 | |
| 		if (e - str) {
 | |
| 			/* termination added */
 | |
| 			s = strndup(str, e - str);
 | |
| 			if (!s)
 | |
| 				return -1;
 | |
| 			ret = add_cgroup(evlist, s);
 | |
| 			if (ret) {
 | |
| 				free(s);
 | |
| 				return -1;
 | |
| 			}
 | |
| 		}
 | |
| 		/* nr_cgroups is increased een for empty cgroups */
 | |
| 		nr_cgroups++;
 | |
| 		if (!p)
 | |
| 			break;
 | |
| 		str = p+1;
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 |