Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56e52e85 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo
Browse files

perf evsel: Introduce perf_evsel__open_strerror method

That consolidates the error messages in 'record', 'stat' and 'top', that
now get a consistent set of messages and allow other tools to use the
new method to report problems using whatever UI toolkit.

Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-1cudb7wl996kz7ilz83ctvhr@git.kernel.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent c0a54341
Loading
Loading
Loading
Loading
+6 −48
Original line number Diff line number Diff line
@@ -224,7 +224,7 @@ static bool perf_evlist__equal(struct perf_evlist *evlist,

static int perf_record__open(struct perf_record *rec)
{
	char msg[128];
	char msg[512];
	struct perf_evsel *pos;
	struct perf_evlist *evlist = rec->evlist;
	struct perf_session *session = rec->session;
@@ -234,60 +234,18 @@ static int perf_record__open(struct perf_record *rec)
	perf_evlist__config(evlist, opts);

	list_for_each_entry(pos, &evlist->entries, node) {
		struct perf_event_attr *attr = &pos->attr;
try_again:
		if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) {
			int err = errno;

			if (err == EPERM || err == EACCES) {
				ui__error_paranoid();
				rc = -err;
				goto out;
			} else if (err ==  ENODEV && opts->target.cpu_list) {
				pr_err("No such device - did you specify"
				       " an out-of-range profile CPU?\n");
				rc = -err;
				goto out;
			}

			if (perf_evsel__fallback(pos, err, msg, sizeof(msg))) {
			if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
				if (verbose)
					ui__warning("%s\n", msg);
				goto try_again;
			}

			if (err == ENOENT) {
				ui__error("The %s event is not supported.\n",
					  perf_evsel__name(pos));
				rc = -err;
				goto out;
			} else if ((err == EOPNOTSUPP) && (attr->precise_ip)) {
				ui__error("\'precise\' request may not be supported. "
					  "Try removing 'p' modifier\n");
				rc = -err;
				goto out;
			}

			printf("\n");
			error("sys_perf_event_open() syscall returned with %d "
			      "(%s) for event %s. /bin/dmesg may provide "
			      "additional information.\n",
			      err, strerror(err), perf_evsel__name(pos));

#if defined(__i386__) || defined(__x86_64__)
			if (attr->type == PERF_TYPE_HARDWARE &&
			    err == EOPNOTSUPP) {
				pr_err("No hardware sampling interrupt available."
				       " No APIC? If so then you can boot the kernel"
				       " with the \"lapic\" boot parameter to"
				       " force-enable it.\n");
				rc = -err;
				goto out;
			}
#endif

			pr_err("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
			rc = -err;
			rc = -errno;
			perf_evsel__open_strerror(pos, &opts->target,
						  errno, msg, sizeof(msg));
			ui__error("%s\n", msg);
			goto out;
		}
	}
+5 −11
Original line number Diff line number Diff line
@@ -247,6 +247,7 @@ static int read_counter(struct perf_evsel *counter)

static int __run_perf_stat(int argc __maybe_unused, const char **argv)
{
	char msg[512];
	unsigned long long t0, t1;
	struct perf_evsel *counter;
	int status = 0;
@@ -324,20 +325,13 @@ static int __run_perf_stat(int argc __maybe_unused, const char **argv)
				continue;
			}

			if (errno == EPERM || errno == EACCES) {
				error("You may not have permission to collect %sstats.\n"
				      "\t Consider tweaking"
				      " /proc/sys/kernel/perf_event_paranoid or running as root.",
				      target.system_wide ? "system-wide " : "");
			} else {
				error("open_counter returned with %d (%s). "
				      "/bin/dmesg may provide additional information.\n",
				       errno, strerror(errno));
			}
			perf_evsel__open_strerror(counter, &target,
						  errno, msg, sizeof(msg));
			ui__error("%s\n", msg);

			if (child_pid != -1)
				kill(child_pid, SIGTERM);

			pr_err("Not all events could be opened.\n");
			return -1;
		}
		counter->supported = true;
+5 −29
Original line number Diff line number Diff line
@@ -892,7 +892,7 @@ static void perf_top__mmap_read(struct perf_top *top)

static void perf_top__start_counters(struct perf_top *top)
{
	char msg[128];
	char msg[512];
	struct perf_evsel *counter;
	struct perf_evlist *evlist = top->evlist;
	struct perf_record_opts *opts = &top->record_opts;
@@ -900,42 +900,18 @@ static void perf_top__start_counters(struct perf_top *top)
	perf_evlist__config(evlist, opts);

	list_for_each_entry(counter, &evlist->entries, node) {
		struct perf_event_attr *attr = &counter->attr;
try_again:
		if (perf_evsel__open(counter, top->evlist->cpus,
				     top->evlist->threads) < 0) {
			int err = errno;

			if (err == EPERM || err == EACCES) {
				ui__error_paranoid();
				goto out_err;
			}

			if (perf_evsel__fallback(counter, err, msg, sizeof(msg))) {
			if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
				if (verbose)
					ui__warning("%s\n", msg);
				goto try_again;
			}

			if (err == ENOENT) {
				ui__error("The %s event is not supported.\n",
					  perf_evsel__name(counter));
				goto out_err;
			} else if (err == EMFILE) {
				ui__error("Too many events are opened.\n"
					    "Try again after reducing the number of events\n");
				goto out_err;
			} else if ((err == EOPNOTSUPP) && (attr->precise_ip)) {
				ui__error("\'precise\' request may not be supported. "
					  "Try removing 'p' modifier\n");
				goto out_err;
			}

			ui__error("The sys_perf_event_open() syscall "
				    "returned with %d (%s).  /bin/dmesg "
				    "may provide additional information.\n"
				    "No CONFIG_PERF_EVENTS=y kernel support "
				    "configured?\n", err, strerror(err));
			perf_evsel__open_strerror(counter, &opts->target,
						  errno, msg, sizeof(msg));
			ui__error("%s\n", msg);
			goto out_err;
		}
	}
+0 −11
Original line number Diff line number Diff line
@@ -52,17 +52,6 @@ int ui__warning(const char *format, ...)
	return ret;
}

int ui__error_paranoid(void)
{
	return ui__error("Permission error - are you root?\n"
		    "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
		    " -1 - Not paranoid at all\n"
		    "  0 - Disallow raw tracepoint access for unpriv\n"
		    "  1 - Disallow cpu events for unpriv\n"
		    "  2 - Disallow kernel profiling for unpriv\n");
}


/**
 * perf_error__register - Register error logging functions
 * @eops: The pointer to error logging function struct
+0 −1
Original line number Diff line number Diff line
@@ -16,6 +16,5 @@ void trace_event(union perf_event *event);

int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2)));
int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
int ui__error_paranoid(void);

#endif	/* __PERF_DEBUG_H */
Loading