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

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

Merge tag 'perf-core-for-mingo' of...

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

 into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

 * Tidy up sample parsing validation, from Adrian Hunter.

 * Make events stream always parsable by adding a new sample_type bit:
   PERF_SAMPLE_IDENTIFIER, that when requested will be always aat a fixed
   position in all PERF_RECORD_ records, from Adrian Hunter.

 * Add a sample parsing test, from Adrian Hunter.

 * Add option to 'perf trace' to analyze events in a file versus live,
   so that one can do:

   [root@zoo ~]# perf record -a -e raw_syscalls:* sleep 1
   [ perf record: Woken up 0 times to write data ]
   [ perf record: Captured and wrote 25.150 MB perf.data (~1098836 samples) ]
   [root@zoo ~]# perf trace -i perf.data -e futex --duration 1
      17.799 ( 1.020 ms): 7127 futex(uaddr: 0x7fff3f6c6674, op: 393, val: 1, utime: 0x7fff3f6c6470, ua
     113.344 (95.429 ms): 7127 futex(uaddr: 0x7fff3f6c6674, op: 393, val: 1, utime: 0x7fff3f6c6470, uaddr2: 0x7fff3f6c6648, val3: 4294967
     133.778 ( 1.042 ms): 18004 futex(uaddr: 0x7fff3f6c6674, op: 393, val: 1, utime: 0x7fff3f6c6470, uaddr2: 0x7fff3f6c6648, val3: 429496
   [root@zoo ~]#

   From David Ahern.

 * Honor target pid / tid options in 'perf trace' when analyzing a file,
   from David Ahern.

 * Handle missing HUGEPAGE defines in the mmap beautifier in 'perf trace',
   from David Ahern.

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 00e4cb1c f2935f3e
Loading
Loading
Loading
Loading
+20 −7
Original line number Original line Diff line number Diff line
@@ -134,8 +134,9 @@ enum perf_event_sample_format {
	PERF_SAMPLE_STACK_USER			= 1U << 13,
	PERF_SAMPLE_STACK_USER			= 1U << 13,
	PERF_SAMPLE_WEIGHT			= 1U << 14,
	PERF_SAMPLE_WEIGHT			= 1U << 14,
	PERF_SAMPLE_DATA_SRC			= 1U << 15,
	PERF_SAMPLE_DATA_SRC			= 1U << 15,
	PERF_SAMPLE_IDENTIFIER			= 1U << 16,


	PERF_SAMPLE_MAX = 1U << 16,		/* non-ABI */
	PERF_SAMPLE_MAX = 1U << 17,		/* non-ABI */
};
};


/*
/*
@@ -492,12 +493,12 @@ enum perf_event_type {
	/*
	/*
	 * If perf_event_attr.sample_id_all is set then all event types will
	 * If perf_event_attr.sample_id_all is set then all event types will
	 * have the sample_type selected fields related to where/when
	 * have the sample_type selected fields related to where/when
	 * (identity) an event took place (TID, TIME, ID, CPU, STREAM_ID)
	 * (identity) an event took place (TID, TIME, ID, STREAM_ID, CPU,
	 * described in PERF_RECORD_SAMPLE below, it will be stashed just after
	 * IDENTIFIER) described in PERF_RECORD_SAMPLE below, it will be stashed
	 * the perf_event_header and the fields already present for the existing
	 * just after the perf_event_header and the fields already present for
	 * fields, i.e. at the end of the payload. That way a newer perf.data
	 * the existing fields, i.e. at the end of the payload. That way a newer
	 * file will be supported by older perf tools, with these new optional
	 * perf.data file will be supported by older perf tools, with these new
	 * fields being ignored.
	 * optional fields being ignored.
	 *
	 *
	 * struct sample_id {
	 * struct sample_id {
	 * 	{ u32			pid, tid; } && PERF_SAMPLE_TID
	 * 	{ u32			pid, tid; } && PERF_SAMPLE_TID
@@ -505,7 +506,12 @@ enum perf_event_type {
	 * 	{ u64			id;       } && PERF_SAMPLE_ID
	 * 	{ u64			id;       } && PERF_SAMPLE_ID
	 * 	{ u64			stream_id;} && PERF_SAMPLE_STREAM_ID
	 * 	{ u64			stream_id;} && PERF_SAMPLE_STREAM_ID
	 * 	{ u32			cpu, res; } && PERF_SAMPLE_CPU
	 * 	{ u32			cpu, res; } && PERF_SAMPLE_CPU
	 *	{ u64			id;	  } && PERF_SAMPLE_IDENTIFIER
	 * } && perf_event_attr::sample_id_all
	 * } && perf_event_attr::sample_id_all
	 *
	 * Note that PERF_SAMPLE_IDENTIFIER duplicates PERF_SAMPLE_ID.  The
	 * advantage of PERF_SAMPLE_IDENTIFIER is that its position is fixed
	 * relative to header.size.
	 */
	 */


	/*
	/*
@@ -594,6 +600,13 @@ enum perf_event_type {
	 * struct {
	 * struct {
	 *	struct perf_event_header	header;
	 *	struct perf_event_header	header;
	 *
	 *
	 *	#
	 *	# Note that PERF_SAMPLE_IDENTIFIER duplicates PERF_SAMPLE_ID.
	 *	# The advantage of PERF_SAMPLE_IDENTIFIER is that its position
	 *	# is fixed relative to header.
	 *	#
	 *
	 *	{ u64			id;	  } && PERF_SAMPLE_IDENTIFIER
	 *	{ u64			ip;	  } && PERF_SAMPLE_IP
	 *	{ u64			ip;	  } && PERF_SAMPLE_IP
	 *	{ u32			pid, tid; } && PERF_SAMPLE_TID
	 *	{ u32			pid, tid; } && PERF_SAMPLE_TID
	 *	{ u64			time;     } && PERF_SAMPLE_TIME
	 *	{ u64			time;     } && PERF_SAMPLE_TIME
+10 −1
Original line number Original line Diff line number Diff line
@@ -1213,6 +1213,9 @@ static void perf_event__id_header_size(struct perf_event *event)
	if (sample_type & PERF_SAMPLE_TIME)
	if (sample_type & PERF_SAMPLE_TIME)
		size += sizeof(data->time);
		size += sizeof(data->time);


	if (sample_type & PERF_SAMPLE_IDENTIFIER)
		size += sizeof(data->id);

	if (sample_type & PERF_SAMPLE_ID)
	if (sample_type & PERF_SAMPLE_ID)
		size += sizeof(data->id);
		size += sizeof(data->id);


@@ -4280,7 +4283,7 @@ static void __perf_event_header__init_id(struct perf_event_header *header,
	if (sample_type & PERF_SAMPLE_TIME)
	if (sample_type & PERF_SAMPLE_TIME)
		data->time = perf_clock();
		data->time = perf_clock();


	if (sample_type & PERF_SAMPLE_ID)
	if (sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER))
		data->id = primary_event_id(event);
		data->id = primary_event_id(event);


	if (sample_type & PERF_SAMPLE_STREAM_ID)
	if (sample_type & PERF_SAMPLE_STREAM_ID)
@@ -4319,6 +4322,9 @@ static void __perf_event__output_id_sample(struct perf_output_handle *handle,


	if (sample_type & PERF_SAMPLE_CPU)
	if (sample_type & PERF_SAMPLE_CPU)
		perf_output_put(handle, data->cpu_entry);
		perf_output_put(handle, data->cpu_entry);

	if (sample_type & PERF_SAMPLE_IDENTIFIER)
		perf_output_put(handle, data->id);
}
}


void perf_event__output_id_sample(struct perf_event *event,
void perf_event__output_id_sample(struct perf_event *event,
@@ -4432,6 +4438,9 @@ void perf_output_sample(struct perf_output_handle *handle,


	perf_output_put(handle, *header);
	perf_output_put(handle, *header);


	if (sample_type & PERF_SAMPLE_IDENTIFIER)
		perf_output_put(handle, data->id);

	if (sample_type & PERF_SAMPLE_IP)
	if (sample_type & PERF_SAMPLE_IP)
		perf_output_put(handle, data->ip);
		perf_output_put(handle, data->ip);


+4 −0
Original line number Original line Diff line number Diff line
@@ -74,6 +74,10 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
--sched:
--sched:
	Accrue thread runtime and provide a summary at the end of the session.
	Accrue thread runtime and provide a summary at the end of the session.


-i
--input
	Process events from a given perf data file.

SEE ALSO
SEE ALSO
--------
--------
linkperf:perf-record[1], linkperf:perf-script[1]
linkperf:perf-record[1], linkperf:perf-script[1]
+2 −0
Original line number Original line Diff line number Diff line
@@ -360,6 +360,7 @@ LIB_OBJS += $(OUTPUT)util/rblist.o
LIB_OBJS += $(OUTPUT)util/intlist.o
LIB_OBJS += $(OUTPUT)util/intlist.o
LIB_OBJS += $(OUTPUT)util/vdso.o
LIB_OBJS += $(OUTPUT)util/vdso.o
LIB_OBJS += $(OUTPUT)util/stat.o
LIB_OBJS += $(OUTPUT)util/stat.o
LIB_OBJS += $(OUTPUT)util/record.o


LIB_OBJS += $(OUTPUT)ui/setup.o
LIB_OBJS += $(OUTPUT)ui/setup.o
LIB_OBJS += $(OUTPUT)ui/helpline.o
LIB_OBJS += $(OUTPUT)ui/helpline.o
@@ -438,6 +439,7 @@ PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
ifneq ($(OUTPUT),)
ifneq ($(OUTPUT),)
  CFLAGS += -I$(OUTPUT)
  CFLAGS += -I$(OUTPUT)
endif
endif
LIB_OBJS += $(OUTPUT)tests/sample-parsing.o


ifdef NO_LIBELF
ifdef NO_LIBELF
EXTLIBS := $(filter-out -lelf,$(EXTLIBS))
EXTLIBS := $(filter-out -lelf,$(EXTLIBS))
+5 −3
Original line number Original line Diff line number Diff line
@@ -198,7 +198,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool,


	cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
	cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;


	thread = machine__findnew_thread(machine, event->ip.pid);
	thread = machine__findnew_thread(machine, sample->pid, sample->pid);
	if (thread == NULL) {
	if (thread == NULL) {
		pr_err("problem processing %d event, skipping it.\n",
		pr_err("problem processing %d event, skipping it.\n",
		       event->header.type);
		       event->header.type);
@@ -206,7 +206,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
	}
	}


	thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
	thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
			      event->ip.ip, &al);
			      sample->ip, &al);


	if (al.map != NULL) {
	if (al.map != NULL) {
		if (!al.map->dso->hit) {
		if (!al.map->dso->hit) {
@@ -301,7 +301,9 @@ static int perf_inject__sched_stat(struct perf_tool *tool,
	sample_sw.period = sample->period;
	sample_sw.period = sample->period;
	sample_sw.time	 = sample->time;
	sample_sw.time	 = sample->time;
	perf_event__synthesize_sample(event_sw, evsel->attr.sample_type,
	perf_event__synthesize_sample(event_sw, evsel->attr.sample_type,
				      &sample_sw, false);
				      evsel->attr.sample_regs_user,
				      evsel->attr.read_format, &sample_sw,
				      false);
	build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine);
	build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine);
	return perf_event__repipe(tool, event_sw, &sample_sw, machine);
	return perf_event__repipe(tool, event_sw, &sample_sw, machine);
}
}
Loading