Commit e0e6a6ca authored by Andi Kleen's avatar Andi Kleen Committed by Arnaldo Carvalho de Melo
Browse files

perf stat: Factor out open error handling



Factor out the open error handling into a separate function.  This is
useful for followon patches who need to duplicate this.

No behavior change intended.

Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Link: http://lore.kernel.org/lkml/20191121001522.180827-9-andi@firstfloor.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 7736627b
Loading
Loading
Loading
Loading
+60 −40
Original line number Diff line number Diff line
@@ -420,6 +420,57 @@ static bool is_target_alive(struct target *_target,
	return false;
}

enum counter_recovery {
	COUNTER_SKIP,
	COUNTER_RETRY,
	COUNTER_FATAL,
};

static enum counter_recovery stat_handle_error(struct evsel *counter)
{
	char msg[BUFSIZ];
	/*
	 * PPC returns ENXIO for HW counters until 2.6.37
	 * (behavior changed with commit b0a873e).
	 */
	if (errno == EINVAL || errno == ENOSYS ||
	    errno == ENOENT || errno == EOPNOTSUPP ||
	    errno == ENXIO) {
		if (verbose > 0)
			ui__warning("%s event is not supported by the kernel.\n",
				    perf_evsel__name(counter));
		counter->supported = false;

		if ((counter->leader != counter) ||
		    !(counter->leader->core.nr_members > 1))
			return COUNTER_SKIP;
	} else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
		if (verbose > 0)
			ui__warning("%s\n", msg);
		return COUNTER_RETRY;
	} else if (target__has_per_thread(&target) &&
		   evsel_list->core.threads &&
		   evsel_list->core.threads->err_thread != -1) {
		/*
		 * For global --per-thread case, skip current
		 * error thread.
		 */
		if (!thread_map__remove(evsel_list->core.threads,
					evsel_list->core.threads->err_thread)) {
			evsel_list->core.threads->err_thread = -1;
			return COUNTER_RETRY;
		}
	}

	perf_evsel__open_strerror(counter, &target,
				  errno, msg, sizeof(msg));
	ui__error("%s\n", msg);

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

static int __run_perf_stat(int argc, const char **argv, int run_idx)
{
	int interval = stat_config.interval;
@@ -469,48 +520,17 @@ try_again:
				goto try_again;
			}

			/*
			 * PPC returns ENXIO for HW counters until 2.6.37
			 * (behavior changed with commit b0a873e).
			 */
			if (errno == EINVAL || errno == ENOSYS ||
			    errno == ENOENT || errno == EOPNOTSUPP ||
			    errno == ENXIO) {
				if (verbose > 0)
					ui__warning("%s event is not supported by the kernel.\n",
						    perf_evsel__name(counter));
				counter->supported = false;

				if ((counter->leader != counter) ||
				    !(counter->leader->core.nr_members > 1))
					continue;
			} else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
                                if (verbose > 0)
                                        ui__warning("%s\n", msg);
                                goto try_again;
			} else if (target__has_per_thread(&target) &&
				   evsel_list->core.threads &&
				   evsel_list->core.threads->err_thread != -1) {
				/*
				 * For global --per-thread case, skip current
				 * error thread.
				 */
				if (!thread_map__remove(evsel_list->core.threads,
							evsel_list->core.threads->err_thread)) {
					evsel_list->core.threads->err_thread = -1;
			switch (stat_handle_error(counter)) {
			case COUNTER_FATAL:
				return -1;
			case COUNTER_RETRY:
				goto try_again;
			case COUNTER_SKIP:
				continue;
			default:
				break;
			}
		}

			perf_evsel__open_strerror(counter, &target,
						  errno, msg, sizeof(msg));
			ui__error("%s\n", msg);

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

			return -1;
		}
		counter->supported = true;

		l = strlen(counter->unit);