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

Commit fcd7476f authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf updates from Ingo Molnar:
 "A number of fixes:

   - Fix segfault on perf trace -i perf.data, from Namhyung Kim.

   - Fix segfault with --no-mmap-pages, from David Ahern.

   - Don't force a refresh during progress update in the TUI, greatly
     reducing startup costs, fix from Patrick Palka.

   - Fix sw clock event period test wrt not checking if using >
     max_sample_freq.

   - Handle throttle events in 'object code reading' test, fix from
     Adrian Hunter.

   - Prevent condition that all sort keys are elided, fix from Namhyung
     Kim.

   - Round mmap pages to power 2, from David Ahern.

  And a number of late arrival changes:

   - Add summary only option to 'perf trace', suppressing the decoding
     of events, from David Ahern

   - 'perf trace --summary' formatting simplifications, from Pekka
     Enberg.

   - Beautify fifth argument of mmap() as fd, in 'perf trace', from
     Namhyung Kim.

   - Add direct access to dynamic arrays in libtraceevent, from Steven
     Rostedt.

   - Synthesize non-exec MMAP records when --data used, allowing the
     resolution of data addresses to symbols (global variables, etc), by
     Arnaldo Carvalho de Melo.

   - Code cleanups by David Ahern and Adrian Hunter"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits)
  tools lib traceevent: Add direct access to dynamic arrays
  perf target: Shorten perf_target__ to target__
  perf tests: Handle throttle events in 'object code reading' test
  perf evlist: Refactor mmap_pages parsing
  perf evlist: Round mmap pages to power 2 - v2
  perf record: Fix segfault with --no-mmap-pages
  perf trace: Add summary only option
  perf trace: Simplify '--summary' output
  perf trace: Change syscall summary duration order
  perf tests: Compensate lower sample freq with longer test loop
  perf trace: Fix segfault on perf trace -i perf.data
  perf trace: Separate tp syscall field caching into init routine to be reused
  perf trace: Beautify fifth argument of mmap() as fd
  perf tests: Use lower sample_freq in sw clock event period test
  perf tests: Check return of perf_evlist__open sw clock event period test
  perf record: Move existing write_output into helper function
  perf record: Use correct return type for write()
  perf tools: Prevent condition that all sort keys are elided
  perf machine: Simplify synthesize_threads method
  perf machine: Introduce synthesize_threads method out of open coded equivalent
  ...
parents d320e203 d969135a
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -3435,6 +3435,19 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
			goto out_warning_op;
		}
		break;
	case PRINT_DYNAMIC_ARRAY:
		/* Without [], we pass the address to the dynamic data */
		offset = pevent_read_number(pevent,
					    data + arg->dynarray.field->offset,
					    arg->dynarray.field->size);
		/*
		 * The actual length of the dynamic array is stored
		 * in the top half of the field, and the offset
		 * is in the bottom half of the 32 bit field.
		 */
		offset &= 0xffff;
		val = (unsigned long long)(data + offset);
		break;
	default: /* not sure what to do there */
		return 0;
	}
+8 −2
Original line number Diff line number Diff line
@@ -93,9 +93,15 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
--comm::
        Show process COMM right beside its ID, on by default, disable with --no-comm.

-s::
--summary::
	Show a summary of syscalls by thread with min, max, and average times (in
    msec) and relative stddev.
	Show only a summary of syscalls by thread with min, max, and average times
    (in msec) and relative stddev.

-S::
--with-summary::
	Show all syscalls followed by a summary by thread with min, max, and
    average times (in msec) and relative stddev.

--tool_stats::
	Show tool stats such as number of times fd->pathname was discovered thru
+5 −15
Original line number Diff line number Diff line
@@ -1510,13 +1510,13 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
	/*
	 * target related setups
	 */
	err = perf_target__validate(&kvm->opts.target);
	err = target__validate(&kvm->opts.target);
	if (err) {
		perf_target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ);
		target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ);
		ui__warning("%s", errbuf);
	}

	if (perf_target__none(&kvm->opts.target))
	if (target__none(&kvm->opts.target))
		kvm->opts.target.system_wide = true;


@@ -1544,18 +1544,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
	}
	kvm->session->evlist = kvm->evlist;
	perf_session__set_id_hdr_size(kvm->session);


	if (perf_target__has_task(&kvm->opts.target))
		perf_event__synthesize_thread_map(&kvm->tool,
						  kvm->evlist->threads,
						  perf_event__process,
						  &kvm->session->machines.host);
	else
		perf_event__synthesize_threads(&kvm->tool, perf_event__process,
					       &kvm->session->machines.host);


	machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target,
				    kvm->evlist->threads, false);
	err = kvm_live_open_events(kvm);
	if (err)
		goto out;
+16 −19
Original line number Diff line number Diff line
@@ -76,12 +76,12 @@ struct perf_record {
	long			samples;
};

static int write_output(struct perf_record *rec, void *buf, size_t size)
static int do_write_output(struct perf_record *rec, void *buf, size_t size)
{
	struct perf_data_file *file = &rec->file;

	while (size) {
		int ret = write(file->fd, buf, size);
		ssize_t ret = write(file->fd, buf, size);

		if (ret < 0) {
			pr_err("failed to write perf data, error: %m\n");
@@ -97,6 +97,11 @@ static int write_output(struct perf_record *rec, void *buf, size_t size)
	return 0;
}

static int write_output(struct perf_record *rec, void *buf, size_t size)
{
	return do_write_output(rec, buf, size);
}

static int process_synthesized_event(struct perf_tool *tool,
				     union perf_event *event,
				     struct perf_sample *sample __maybe_unused,
@@ -480,16 +485,8 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
					 perf_event__synthesize_guest_os, tool);
	}

	if (perf_target__has_task(&opts->target))
		err = perf_event__synthesize_thread_map(tool, evsel_list->threads,
						  process_synthesized_event,
						  machine);
	else if (perf_target__has_cpu(&opts->target))
		err = perf_event__synthesize_threads(tool, process_synthesized_event,
					       machine);
	else /* command specified */
		err = 0;

	err = __machine__synthesize_threads(machine, tool, &opts->target, evsel_list->threads,
					    process_synthesized_event, opts->sample_address);
	if (err != 0)
		goto out_delete_session;

@@ -509,7 +506,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
	 * (apart from group members) have enable_on_exec=1 set,
	 * so don't spoil it by prematurely enabling them.
	 */
	if (!perf_target__none(&opts->target))
	if (!target__none(&opts->target))
		perf_evlist__enable(evsel_list);

	/*
@@ -538,7 +535,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
		 * die with the process and we wait for that. Thus no need to
		 * disable events in this case.
		 */
		if (done && !disabled && !perf_target__none(&opts->target)) {
		if (done && !disabled && !target__none(&opts->target)) {
			perf_evlist__disable(evsel_list);
			disabled = true;
		}
@@ -909,7 +906,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)

	argc = parse_options(argc, argv, record_options, record_usage,
			    PARSE_OPT_STOP_AT_NON_OPTION);
	if (!argc && perf_target__none(&rec->opts.target))
	if (!argc && target__none(&rec->opts.target))
		usage_with_options(record_usage, record_options);

	if (nr_cgroups && !rec->opts.target.system_wide) {
@@ -939,17 +936,17 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
		goto out_symbol_exit;
	}

	err = perf_target__validate(&rec->opts.target);
	err = target__validate(&rec->opts.target);
	if (err) {
		perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
		target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
		ui__warning("%s", errbuf);
	}

	err = perf_target__parse_uid(&rec->opts.target);
	err = target__parse_uid(&rec->opts.target);
	if (err) {
		int saved_errno = errno;

		perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
		target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
		ui__error("%s", errbuf);

		err = -saved_errno;
+10 −11
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ enum {

static struct perf_evlist	*evsel_list;

static struct perf_target	target = {
static struct target target = {
	.uid	= UINT_MAX,
};

@@ -294,11 +294,10 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)

	attr->inherit = !no_inherit;

	if (perf_target__has_cpu(&target))
	if (target__has_cpu(&target))
		return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));

	if (!perf_target__has_task(&target) &&
	    perf_evsel__is_group_leader(evsel)) {
	if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) {
		attr->disabled = 1;
		if (!initial_delay)
			attr->enable_on_exec = 1;
@@ -1236,7 +1235,7 @@ static void print_stat(int argc, const char **argv)
			fprintf(output, "\'system wide");
		else if (target.cpu_list)
			fprintf(output, "\'CPU(s) %s", target.cpu_list);
		else if (!perf_target__has_task(&target)) {
		else if (!target__has_task(&target)) {
			fprintf(output, "\'%s", argv[0]);
			for (i = 1; i < argc; i++)
				fprintf(output, " %s", argv[i]);
@@ -1667,7 +1666,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
	} else if (big_num_opt == 0) /* User passed --no-big-num */
		big_num = false;

	if (!argc && perf_target__none(&target))
	if (!argc && target__none(&target))
		usage_with_options(stat_usage, options);

	if (run_count < 0) {
@@ -1680,8 +1679,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
	}

	/* no_aggr, cgroup are for system-wide only */
	if ((aggr_mode != AGGR_GLOBAL || nr_cgroups)
	     && !perf_target__has_cpu(&target)) {
	if ((aggr_mode != AGGR_GLOBAL || nr_cgroups) &&
	    !target__has_cpu(&target)) {
		fprintf(stderr, "both cgroup and no-aggregation "
			"modes only available in system-wide mode\n");

@@ -1694,14 +1693,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
	if (add_default_attributes())
		goto out;

	perf_target__validate(&target);
	target__validate(&target);

	if (perf_evlist__create_maps(evsel_list, &target) < 0) {
		if (perf_target__has_task(&target)) {
		if (target__has_task(&target)) {
			pr_err("Problems finding threads of monitor\n");
			parse_options_usage(stat_usage, options, "p", 1);
			parse_options_usage(NULL, options, "t", 1);
		} else if (perf_target__has_cpu(&target)) {
		} else if (target__has_cpu(&target)) {
			perror("failed to parse CPUs map");
			parse_options_usage(stat_usage, options, "C", 1);
			parse_options_usage(NULL, options, "a", 1);
Loading