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

Commit d380eaae authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'perf/core' of...

Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
parents dda99116 ef1d1af2
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -73,6 +73,10 @@ OPTIONS
	(Only for --vars) Show external defined variables in addition to local
	variables.

-F::
--funcs::
	Show available functions in given module or kernel.

-f::
--force::
	Forcibly add events with existing name.
+4 −0
Original line number Diff line number Diff line
@@ -402,6 +402,7 @@ LIB_H += util/debug.h
LIB_H += util/debugfs.h
LIB_H += util/event.h
LIB_H += util/evsel.h
LIB_H += util/evlist.h
LIB_H += util/exec_cmd.h
LIB_H += util/types.h
LIB_H += util/levenshtein.h
@@ -425,6 +426,7 @@ LIB_H += util/values.h
LIB_H += util/sort.h
LIB_H += util/hist.h
LIB_H += util/thread.h
LIB_H += util/thread_map.h
LIB_H += util/trace-event.h
LIB_H += util/probe-finder.h
LIB_H += util/probe-event.h
@@ -440,6 +442,7 @@ LIB_OBJS += $(OUTPUT)util/ctype.o
LIB_OBJS += $(OUTPUT)util/debugfs.o
LIB_OBJS += $(OUTPUT)util/environment.o
LIB_OBJS += $(OUTPUT)util/event.o
LIB_OBJS += $(OUTPUT)util/evlist.o
LIB_OBJS += $(OUTPUT)util/evsel.o
LIB_OBJS += $(OUTPUT)util/exec_cmd.o
LIB_OBJS += $(OUTPUT)util/help.o
@@ -469,6 +472,7 @@ LIB_OBJS += $(OUTPUT)util/map.o
LIB_OBJS += $(OUTPUT)util/pstack.o
LIB_OBJS += $(OUTPUT)util/session.o
LIB_OBJS += $(OUTPUT)util/thread.o
LIB_OBJS += $(OUTPUT)util/thread_map.o
LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
LIB_OBJS += $(OUTPUT)util/trace-event-read.o
LIB_OBJS += $(OUTPUT)util/trace-event-info.o
+28 −1
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ static struct {
	bool show_lines;
	bool show_vars;
	bool show_ext_vars;
	bool show_funcs;
	bool mod_events;
	int nevents;
	struct perf_probe_event events[MAX_PROBES];
@@ -221,6 +222,8 @@ static const struct option options[] = {
	OPT__DRY_RUN(&probe_event_dry_run),
	OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
		 "Set how many probe points can be found for a probe."),
	OPT_BOOLEAN('F', "funcs", &params.show_funcs,
		    "Show potential probe-able functions."),
	OPT_END()
};

@@ -246,7 +249,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
		params.max_probe_points = MAX_PROBES;

	if ((!params.nevents && !params.dellist && !params.list_events &&
	     !params.show_lines))
	     !params.show_lines && !params.show_funcs))
		usage_with_options(probe_usage, options);

	/*
@@ -267,12 +270,36 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
			pr_err(" Error: Don't use --list with --vars.\n");
			usage_with_options(probe_usage, options);
		}
		if (params.show_funcs) {
			pr_err("  Error: Don't use --list with --funcs.\n");
			usage_with_options(probe_usage, options);
		}
		ret = show_perf_probe_events();
		if (ret < 0)
			pr_err("  Error: Failed to show event list. (%d)\n",
			       ret);
		return ret;
	}
	if (params.show_funcs) {
		if (params.nevents != 0 || params.dellist) {
			pr_err("  Error: Don't use --funcs with"
			       " --add/--del.\n");
			usage_with_options(probe_usage, options);
		}
		if (params.show_lines) {
			pr_err("  Error: Don't use --funcs with --line.\n");
			usage_with_options(probe_usage, options);
		}
		if (params.show_vars) {
			pr_err("  Error: Don't use --funcs with --vars.\n");
			usage_with_options(probe_usage, options);
		}
		ret = show_available_funcs(params.target_module);
		if (ret < 0)
			pr_err("  Error: Failed to show functions."
			       " (%d)\n", ret);
		return ret;
	}

#ifdef DWARF_SUPPORT
	if (params.show_lines) {
+134 −194
Original line number Diff line number Diff line
@@ -18,17 +18,20 @@

#include "util/header.h"
#include "util/event.h"
#include "util/evlist.h"
#include "util/evsel.h"
#include "util/debug.h"
#include "util/session.h"
#include "util/symbol.h"
#include "util/cpumap.h"
#include "util/thread_map.h"

#include <unistd.h>
#include <sched.h>
#include <sys/mman.h>

#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
#define SID(e, x, y) xyarray__entry(e->id, x, y)

enum write_mode_t {
	WRITE_FORCE,
@@ -46,7 +49,7 @@ static unsigned int user_freq = UINT_MAX;
static int			freq				=   1000;
static int			output;
static int			pipe_output			=      0;
static const char		*output_name			= "perf.data";
static const char		*output_name			= NULL;
static int			group				=      0;
static int			realtime_prio			=      0;
static bool			nodelay				=  false;
@@ -66,51 +69,17 @@ static bool sample_address = false;
static bool			sample_time			=  false;
static bool			no_buildid			=  false;
static bool			no_buildid_cache		=  false;
static struct perf_evlist	*evsel_list;

static long			samples				=      0;
static u64			bytes_written			=      0;

static struct pollfd		*event_array;

static int			nr_poll				=      0;
static int			nr_cpu				=      0;

static int			file_new			=      1;
static off_t			post_processing_offset;

static struct perf_session	*session;
static const char		*cpu_list;

struct mmap_data {
	void			*base;
	unsigned int		mask;
	unsigned int		prev;
};

static struct mmap_data		mmap_array[MAX_NR_CPUS];

static unsigned long mmap_read_head(struct mmap_data *md)
{
	struct perf_event_mmap_page *pc = md->base;
	long head;

	head = pc->data_head;
	rmb();

	return head;
}

static void mmap_write_tail(struct mmap_data *md, unsigned long tail)
{
	struct perf_event_mmap_page *pc = md->base;

	/*
	 * ensure all reads are done before we write the tail out.
	 */
	/* mb(); */
	pc->data_tail = tail;
}

static void advance_output(size_t size)
{
	bytes_written += size;
@@ -139,9 +108,9 @@ static int process_synthesized_event(event_t *event,
	return 0;
}

static void mmap_read(struct mmap_data *md)
static void mmap_read(struct perf_mmap *md)
{
	unsigned int head = mmap_read_head(md);
	unsigned int head = perf_mmap__read_head(md);
	unsigned int old = md->prev;
	unsigned char *data = md->base + page_size;
	unsigned long size;
@@ -185,7 +154,7 @@ static void mmap_read(struct mmap_data *md)
	write_output(buf, size);

	md->prev = old;
	mmap_write_tail(md, old);
	perf_mmap__write_tail(md, old);
}

static volatile int done = 0;
@@ -209,8 +178,6 @@ static void sig_atexit(void)
	kill(getpid(), signr);
}

static int group_fd;

static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int nr)
{
	struct perf_header_attr *h_attr;
@@ -234,28 +201,47 @@ static void create_counter(struct perf_evsel *evsel, int cpu)
	char *filter = evsel->filter;
	struct perf_event_attr *attr = &evsel->attr;
	struct perf_header_attr *h_attr;
	int track = !evsel->idx; /* only the first counter needs these */
	struct perf_sample_id *sid;
	int thread_index;
	int ret;
	struct {
		u64 count;
		u64 time_enabled;
		u64 time_running;
		u64 id;
	} read_data;
	/*
 	 * Check if parse_single_tracepoint_event has already asked for
 	 * PERF_SAMPLE_TIME.
 	 *
	 * XXX this is kludgy but short term fix for problems introduced by
	 * eac23d1c that broke 'perf script' by having different sample_types
	 * when using multiple tracepoint events when we use a perf binary
	 * that tries to use sample_id_all on an older kernel.
 	 *
 	 * We need to move counter creation to perf_session, support
 	 * different sample_types, etc.
 	 */
	bool time_needed = attr->sample_type & PERF_SAMPLE_TIME;

	for (thread_index = 0; thread_index < threads->nr; thread_index++) {
		h_attr = get_header_attr(attr, evsel->idx);
		if (h_attr == NULL)
			die("nomem\n");

		if (!file_new) {
			if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
				fprintf(stderr, "incompatible append\n");
				exit(-1);
			}
		}

		sid = SID(evsel, cpu, thread_index);
		if (perf_header_attr__add_id(h_attr, sid->id) < 0) {
			pr_warning("Not enough memory to add id\n");
			exit(-1);
		}

		if (filter != NULL) {
			ret = ioctl(FD(evsel, cpu, thread_index),
				    PERF_EVENT_IOC_SET_FILTER, filter);
			if (ret) {
				error("failed to set filter with %d (%s)\n", errno,
						strerror(errno));
				exit(-1);
			}
		}
	}

	if (!sample_type)
		sample_type = attr->sample_type;
}

static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist)
{
	struct perf_event_attr *attr = &evsel->attr;
	int track = !evsel->idx; /* only the first counter needs these */

	attr->read_format	= PERF_FORMAT_TOTAL_TIME_ENABLED |
				  PERF_FORMAT_TOTAL_TIME_RUNNING |
@@ -263,7 +249,7 @@ static void create_counter(struct perf_evsel *evsel, int cpu)

	attr->sample_type	|= PERF_SAMPLE_IP | PERF_SAMPLE_TID;

	if (nr_counters > 1)
	if (evlist->nr_entries > 1)
		attr->sample_type |= PERF_SAMPLE_ID;

	/*
@@ -315,19 +301,39 @@ static void create_counter(struct perf_evsel *evsel, int cpu)

	attr->mmap		= track;
	attr->comm		= track;
	attr->inherit		= !no_inherit;

	if (target_pid == -1 && target_tid == -1 && !system_wide) {
		attr->disabled = 1;
		attr->enable_on_exec = 1;
	}
}

static void open_counters(struct perf_evlist *evlist)
{
	struct perf_evsel *pos;
	int cpu;

	list_for_each_entry(pos, &evlist->entries, node) {
		struct perf_event_attr *attr = &pos->attr;
		/*
		 * Check if parse_single_tracepoint_event has already asked for
		 * PERF_SAMPLE_TIME.
		 *
		 * XXX this is kludgy but short term fix for problems introduced by
		 * eac23d1c that broke 'perf script' by having different sample_types
		 * when using multiple tracepoint events when we use a perf binary
		 * that tries to use sample_id_all on an older kernel.
		 *
		 * We need to move counter creation to perf_session, support
		 * different sample_types, etc.
		 */
		bool time_needed = attr->sample_type & PERF_SAMPLE_TIME;

		config_attr(pos, evlist);
retry_sample_id:
		attr->sample_id_all = sample_id_all_avail ? 1 : 0;

	for (thread_index = 0; thread_index < threads->nr; thread_index++) {
try_again:
		FD(evsel, nr_cpu, thread_index) = sys_perf_event_open(attr, threads->map[thread_index], cpu, group_fd, 0);

		if (FD(evsel, nr_cpu, thread_index) < 0) {
		if (perf_evsel__open(pos, cpus, threads, group, !no_inherit) < 0) {
			int err = errno;

			if (err == EPERM || err == EACCES)
@@ -364,7 +370,7 @@ try_again:
			}
			printf("\n");
			error("sys_perf_event_open() syscall returned with %d (%s).  /bin/dmesg may provide additional information.\n",
			      FD(evsel, nr_cpu, thread_index), strerror(err));
			      err, strerror(err));

#if defined(__i386__) || defined(__x86_64__)
			if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP)
@@ -375,90 +381,16 @@ try_again:
#endif

			die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
			exit(-1);
		}

		h_attr = get_header_attr(attr, evsel->idx);
		if (h_attr == NULL)
			die("nomem\n");

		if (!file_new) {
			if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
				fprintf(stderr, "incompatible append\n");
				exit(-1);
			}
		}

		if (read(FD(evsel, nr_cpu, thread_index), &read_data, sizeof(read_data)) == -1) {
			perror("Unable to read perf file descriptor");
			exit(-1);
		}

		if (perf_header_attr__add_id(h_attr, read_data.id) < 0) {
			pr_warning("Not enough memory to add id\n");
			exit(-1);
		}

		assert(FD(evsel, nr_cpu, thread_index) >= 0);
		fcntl(FD(evsel, nr_cpu, thread_index), F_SETFL, O_NONBLOCK);

		/*
		 * First counter acts as the group leader:
		 */
		if (group && group_fd == -1)
			group_fd = FD(evsel, nr_cpu, thread_index);

		if (evsel->idx || thread_index) {
			struct perf_evsel *first;
			first = list_entry(evsel_list.next, struct perf_evsel, node);
			ret = ioctl(FD(evsel, nr_cpu, thread_index),
				    PERF_EVENT_IOC_SET_OUTPUT,
				    FD(first, nr_cpu, 0));
			if (ret) {
				error("failed to set output: %d (%s)\n", errno,
						strerror(errno));
				exit(-1);
			}
		} else {
			mmap_array[nr_cpu].prev = 0;
			mmap_array[nr_cpu].mask = mmap_pages*page_size - 1;
			mmap_array[nr_cpu].base = mmap(NULL, (mmap_pages+1)*page_size,
				PROT_READ | PROT_WRITE, MAP_SHARED, FD(evsel, nr_cpu, thread_index), 0);
			if (mmap_array[nr_cpu].base == MAP_FAILED) {
				error("failed to mmap with %d (%s)\n", errno, strerror(errno));
				exit(-1);
			}

			event_array[nr_poll].fd = FD(evsel, nr_cpu, thread_index);
			event_array[nr_poll].events = POLLIN;
			nr_poll++;
		}

		if (filter != NULL) {
			ret = ioctl(FD(evsel, nr_cpu, thread_index),
				    PERF_EVENT_IOC_SET_FILTER, filter);
			if (ret) {
				error("failed to set filter with %d (%s)\n", errno,
						strerror(errno));
				exit(-1);
			}
		}
	}

	if (!sample_type)
		sample_type = attr->sample_type;
	}

static void open_counters(int cpu)
{
	struct perf_evsel *pos;

	group_fd = -1;
	if (perf_evlist__mmap(evlist, cpus, threads, mmap_pages, false) < 0)
		die("failed to mmap with %d (%s)\n", errno, strerror(errno));

	list_for_each_entry(pos, &evsel_list, node)
	for (cpu = 0; cpu < cpus->nr; ++cpu) {
		list_for_each_entry(pos, &evlist->entries, node)
			create_counter(pos, cpu);

	nr_cpu++;
	}
}

static int process_buildids(void)
@@ -481,9 +413,9 @@ static void atexit_header(void)

		if (!no_buildid)
			process_buildids();
		perf_header__write(&session->header, output, true);
		perf_header__write(&session->header, evsel_list, output, true);
		perf_session__delete(session);
		perf_evsel_list__delete();
		perf_evlist__delete(evsel_list);
		symbol__exit();
	}
}
@@ -533,9 +465,9 @@ static void mmap_read_all(void)
{
	int i;

	for (i = 0; i < nr_cpu; i++) {
		if (mmap_array[i].base)
			mmap_read(&mmap_array[i]);
	for (i = 0; i < cpus->nr; i++) {
		if (evsel_list->mmap[i].base)
			mmap_read(&evsel_list->mmap[i]);
	}

	if (perf_header__has_feat(&session->header, HEADER_TRACE_INFO))
@@ -566,6 +498,13 @@ static int __cmd_record(int argc, const char **argv)
		exit(-1);
	}

	if (!output_name) {
		if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
			pipe_output = 1;
		else
			output_name = "perf.data";
	}
	if (output_name) {
		if (!strcmp(output_name, "-"))
			pipe_output = 1;
		else if (!stat(output_name, &st) && st.st_size) {
@@ -579,6 +518,7 @@ static int __cmd_record(int argc, const char **argv)
		} else if (write_mode == WRITE_APPEND) {
			write_mode = WRITE_FORCE;
		}
	}

	flags = O_CREAT|O_RDWR;
	if (write_mode == WRITE_APPEND)
@@ -611,7 +551,7 @@ static int __cmd_record(int argc, const char **argv)
			goto out_delete_session;
	}

	if (have_tracepoints(&evsel_list))
	if (have_tracepoints(&evsel_list->entries))
		perf_header__set_feat(&session->header, HEADER_TRACE_INFO);

	/*
@@ -673,12 +613,7 @@ static int __cmd_record(int argc, const char **argv)
		close(child_ready_pipe[0]);
	}

	if (!system_wide && no_inherit && !cpu_list) {
		open_counters(-1);
	} else {
		for (i = 0; i < cpus->nr; i++)
			open_counters(cpus->map[i]);
	}
	open_counters(evsel_list);

	perf_session__set_sample_type(session, sample_type);

@@ -687,7 +622,8 @@ static int __cmd_record(int argc, const char **argv)
		if (err < 0)
			return err;
	} else if (file_new) {
		err = perf_header__write(&session->header, output, false);
		err = perf_header__write(&session->header, evsel_list,
					 output, false);
		if (err < 0)
			return err;
	}
@@ -712,7 +648,7 @@ static int __cmd_record(int argc, const char **argv)
			return err;
		}

		if (have_tracepoints(&evsel_list)) {
		if (have_tracepoints(&evsel_list->entries)) {
			/*
			 * FIXME err <= 0 here actually means that
			 * there were no tracepoints so its not really
@@ -721,7 +657,7 @@ static int __cmd_record(int argc, const char **argv)
			 * return this more properly and also
			 * propagate errors that now are calling die()
			 */
			err = event__synthesize_tracing_data(output, &evsel_list,
			err = event__synthesize_tracing_data(output, evsel_list,
							     process_synthesized_event,
							     session);
			if (err <= 0) {
@@ -789,15 +725,15 @@ static int __cmd_record(int argc, const char **argv)
		if (hits == samples) {
			if (done)
				break;
			err = poll(event_array, nr_poll, -1);
			err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1);
			waking++;
		}

		if (done) {
			for (i = 0; i < nr_cpu; i++) {
			for (i = 0; i < cpus->nr; i++) {
				struct perf_evsel *pos;

				list_for_each_entry(pos, &evsel_list, node) {
				list_for_each_entry(pos, &evsel_list->entries, node) {
					for (thread = 0;
						thread < threads->nr;
						thread++)
@@ -838,10 +774,10 @@ static const char * const record_usage[] = {
static bool force, append_file;

const struct option record_options[] = {
	OPT_CALLBACK('e', "event", NULL, "event",
	OPT_CALLBACK('e', "event", &evsel_list, "event",
		     "event selector. use 'perf list' to list available events",
		     parse_events),
	OPT_CALLBACK(0, "filter", NULL, "filter",
	OPT_CALLBACK(0, "filter", &evsel_list, "filter",
		     "event filter", parse_filter),
	OPT_INTEGER('p', "pid", &target_pid,
		    "record events on existing process id"),
@@ -892,6 +828,10 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
	int err = -ENOMEM;
	struct perf_evsel *pos;

	evsel_list = perf_evlist__new();
	if (evsel_list == NULL)
		return -ENOMEM;

	argc = parse_options(argc, argv, record_options, record_usage,
			    PARSE_OPT_STOP_AT_NON_OPTION);
	if (!argc && target_pid == -1 && target_tid == -1 &&
@@ -913,7 +853,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
	if (no_buildid_cache || no_buildid)
		disable_buildid_cache();

	if (list_empty(&evsel_list) && perf_evsel_list__create_default() < 0) {
	if (evsel_list->nr_entries == 0 &&
	    perf_evlist__add_default(evsel_list) < 0) {
		pr_err("Not enough memory for event selector list\n");
		goto out_symbol_exit;
	}
@@ -927,21 +868,22 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
		usage_with_options(record_usage, record_options);
	}

	if (target_tid != -1)
		cpus = cpu_map__dummy_new();
	else
		cpus = cpu_map__new(cpu_list);
	if (cpus == NULL) {
		perror("failed to parse CPUs map");
		return -1;
	}

	list_for_each_entry(pos, &evsel_list, node) {
	if (cpus == NULL)
		usage_with_options(record_usage, record_options);

	list_for_each_entry(pos, &evsel_list->entries, node) {
		if (perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
			goto out_free_fd;
		if (perf_header__push_event(pos->attr.config, event_name(pos)))
			goto out_free_fd;
	}
	event_array = malloc((sizeof(struct pollfd) * MAX_NR_CPUS *
			      MAX_COUNTERS * threads->nr));
	if (!event_array)

	if (perf_evlist__alloc_pollfd(evsel_list, cpus->nr, threads->nr) < 0)
		goto out_free_fd;

	if (user_interval != ULLONG_MAX)
@@ -959,13 +901,11 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
	} else {
		fprintf(stderr, "frequency and count are zero, aborting\n");
		err = -EINVAL;
		goto out_free_event_array;
		goto out_free_fd;
	}

	err = __cmd_record(argc, argv);

out_free_event_array:
	free(event_array);
out_free_fd:
	thread_map__delete(threads);
	threads = NULL;
+14 −15
Original line number Diff line number Diff line
@@ -81,18 +81,17 @@ static int perf_session__add_hist_entry(struct perf_session *self,
					struct addr_location *al,
					struct sample_data *data)
{
	struct map_symbol *syms = NULL;
	struct symbol *parent = NULL;
	int err = -ENOMEM;
	int err = 0;
	struct hist_entry *he;
	struct hists *hists;
	struct perf_event_attr *attr;

	if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain) {
		syms = perf_session__resolve_callchain(self, al->thread,
		err = perf_session__resolve_callchain(self, al->thread,
						      data->callchain, &parent);
		if (syms == NULL)
			return -ENOMEM;
		if (err)
			return err;
	}

	attr = perf_header__find_attr(data->id, &self->header);
@@ -101,16 +100,17 @@ static int perf_session__add_hist_entry(struct perf_session *self,
	else
		hists = perf_session__hists_findnew(self, data->id, 0, 0);
	if (hists == NULL)
		goto out_free_syms;
		return -ENOMEM;

	he = __hists__add_entry(hists, al, parent, data->period);
	if (he == NULL)
		goto out_free_syms;
	err = 0;
		return -ENOMEM;

	if (symbol_conf.use_callchain) {
		err = callchain_append(he->callchain, data->callchain, syms,
		err = callchain_append(he->callchain, &self->callchain_cursor,
				       data->period);
		if (err)
			goto out_free_syms;
			return err;
	}
	/*
	 * Only in the newt browser we are doing integrated annotation,
@@ -119,8 +119,7 @@ static int perf_session__add_hist_entry(struct perf_session *self,
	 */
	if (use_browser > 0)
		err = hist_entry__inc_addr_samples(he, al->addr);
out_free_syms:
	free(syms);

	return err;
}

@@ -222,7 +221,7 @@ static int perf_session__setup_sample_type(struct perf_session *self)
	} else if (!dont_use_callchains && callchain_param.mode != CHAIN_NONE &&
		   !symbol_conf.use_callchain) {
			symbol_conf.use_callchain = true;
			if (register_callchain_param(&callchain_param) < 0) {
			if (callchain_register_param(&callchain_param) < 0) {
				fprintf(stderr, "Can't register callchain"
						" params\n");
				return -EINVAL;
@@ -424,7 +423,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
	if (tok2)
		callchain_param.print_limit = strtod(tok2, &endptr);
setup:
	if (register_callchain_param(&callchain_param) < 0) {
	if (callchain_register_param(&callchain_param) < 0) {
		fprintf(stderr, "Can't register callchain params\n");
		return -1;
	}
Loading