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

Commit 47c1ded7 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'perf-urgent-for-mingo-4.12-20170608' of...

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

 into perf/urgent

Pull perf/urgent fixes from Arnaldo Carvalho de Melo:

 - Fixes for handling compressed kernel modules (Namhyung Kim)

 - Fix handling old style build-id cache ($HOME/.debug/) (Namhyung Kim)

 - 'perf script' python/perl documentation fixes: outdated comments,
   invalid code snippets, etc (SeongJae Park)

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents cc1582c2 b89fe63f
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -240,7 +240,11 @@ Add a probe on schedule() function 12th line with recording cpu local variable:
 or
 or
 ./perf probe --add='schedule:12 cpu'
 ./perf probe --add='schedule:12 cpu'


 this will add one or more probes which has the name start with "schedule".
Add one or more probes which has the name start with "schedule".

 ./perf probe schedule*
 or
 ./perf probe --add='schedule*'


Add probes on lines in schedule() function which calls update_rq_clock().
Add probes on lines in schedule() function which calls update_rq_clock().


+1 −1
Original line number Original line Diff line number Diff line
@@ -39,7 +39,7 @@ EVENT HANDLERS
When perf script is invoked using a trace script, a user-defined
When perf script is invoked using a trace script, a user-defined
'handler function' is called for each event in the trace.  If there's
'handler function' is called for each event in the trace.  If there's
no handler function defined for a given event type, the event is
no handler function defined for a given event type, the event is
ignored (or passed to a 'trace_handled' function, see below) and the
ignored (or passed to a 'trace_unhandled' function, see below) and the
next event is processed.
next event is processed.


Most of the event's field values are passed as arguments to the
Most of the event's field values are passed as arguments to the
+9 −14
Original line number Original line Diff line number Diff line
@@ -149,10 +149,8 @@ def raw_syscalls__sys_enter(event_name, context, common_cpu,
		print "id=%d, args=%s\n" % \
		print "id=%d, args=%s\n" % \
		(id, args),
		(id, args),


def trace_unhandled(event_name, context, common_cpu, common_secs, common_nsecs,
def trace_unhandled(event_name, context, event_fields_dict):
		common_pid, common_comm):
		print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
		print_header(event_name, common_cpu, common_secs, common_nsecs,
		common_pid, common_comm)


def print_header(event_name, cpu, secs, nsecs, pid, comm):
def print_header(event_name, cpu, secs, nsecs, pid, comm):
	print "%-20s %5u %05u.%09u %8u %-20s " % \
	print "%-20s %5u %05u.%09u %8u %-20s " % \
@@ -321,7 +319,7 @@ So those are the essential steps in writing and running a script. The
process can be generalized to any tracepoint or set of tracepoints
process can be generalized to any tracepoint or set of tracepoints
you're interested in - basically find the tracepoint(s) you're
you're interested in - basically find the tracepoint(s) you're
interested in by looking at the list of available events shown by
interested in by looking at the list of available events shown by
'perf list' and/or look in /sys/kernel/debug/tracing events for
'perf list' and/or look in /sys/kernel/debug/tracing/events/ for
detailed event and field info, record the corresponding trace data
detailed event and field info, record the corresponding trace data
using 'perf record', passing it the list of interesting events,
using 'perf record', passing it the list of interesting events,
generate a skeleton script using 'perf script -g python' and modify the
generate a skeleton script using 'perf script -g python' and modify the
@@ -334,7 +332,7 @@ right place, you can have your script listed alongside the other
scripts listed by the 'perf script -l' command e.g.:
scripts listed by the 'perf script -l' command e.g.:


----
----
root@tropicana:~# perf script -l
# perf script -l
List of available trace scripts:
List of available trace scripts:
  wakeup-latency                       system-wide min/max/avg wakeup latency
  wakeup-latency                       system-wide min/max/avg wakeup latency
  rw-by-file <comm>                    r/w activity for a program, by file
  rw-by-file <comm>                    r/w activity for a program, by file
@@ -383,8 +381,6 @@ source tree:


----
----
# ls -al kernel-source/tools/perf/scripts/python
# ls -al kernel-source/tools/perf/scripts/python

root@tropicana:/home/trz/src/tip# ls -al tools/perf/scripts/python
total 32
total 32
drwxr-xr-x 4 trz trz 4096 2010-01-26 22:30 .
drwxr-xr-x 4 trz trz 4096 2010-01-26 22:30 .
drwxr-xr-x 4 trz trz 4096 2010-01-26 22:29 ..
drwxr-xr-x 4 trz trz 4096 2010-01-26 22:29 ..
@@ -399,7 +395,7 @@ otherwise your script won't show up at run-time), 'perf script -l'
should show a new entry for your script:
should show a new entry for your script:


----
----
root@tropicana:~# perf script -l
# perf script -l
List of available trace scripts:
List of available trace scripts:
  wakeup-latency                       system-wide min/max/avg wakeup latency
  wakeup-latency                       system-wide min/max/avg wakeup latency
  rw-by-file <comm>                    r/w activity for a program, by file
  rw-by-file <comm>                    r/w activity for a program, by file
@@ -437,7 +433,7 @@ EVENT HANDLERS
When perf script is invoked using a trace script, a user-defined
When perf script is invoked using a trace script, a user-defined
'handler function' is called for each event in the trace.  If there's
'handler function' is called for each event in the trace.  If there's
no handler function defined for a given event type, the event is
no handler function defined for a given event type, the event is
ignored (or passed to a 'trace_handled' function, see below) and the
ignored (or passed to a 'trace_unhandled' function, see below) and the
next event is processed.
next event is processed.


Most of the event's field values are passed as arguments to the
Most of the event's field values are passed as arguments to the
@@ -532,7 +528,7 @@ can implement a set of optional functions:
gives scripts a chance to do setup tasks:
gives scripts a chance to do setup tasks:


----
----
def trace_begin:
def trace_begin():
    pass
    pass
----
----


@@ -541,7 +537,7 @@ def trace_begin:
 as display results:
 as display results:


----
----
def trace_end:
def trace_end():
    pass
    pass
----
----


@@ -550,8 +546,7 @@ def trace_end:
 of common arguments are passed into it:
 of common arguments are passed into it:


----
----
def trace_unhandled(event_name, context, common_cpu, common_secs,
def trace_unhandled(event_name, context, event_fields_dict):
        common_nsecs, common_pid, common_comm):
    pass
    pass
----
----


+19 −1
Original line number Original line Diff line number Diff line
@@ -229,6 +229,8 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
	unsigned char buf2[BUFSZ];
	unsigned char buf2[BUFSZ];
	size_t ret_len;
	size_t ret_len;
	u64 objdump_addr;
	u64 objdump_addr;
	const char *objdump_name;
	char decomp_name[KMOD_DECOMP_LEN];
	int ret;
	int ret;


	pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
	pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
@@ -289,9 +291,25 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
		state->done[state->done_cnt++] = al.map->start;
		state->done[state->done_cnt++] = al.map->start;
	}
	}


	objdump_name = al.map->dso->long_name;
	if (dso__needs_decompress(al.map->dso)) {
		if (dso__decompress_kmodule_path(al.map->dso, objdump_name,
						 decomp_name,
						 sizeof(decomp_name)) < 0) {
			pr_debug("decompression failed\n");
			return -1;
		}

		objdump_name = decomp_name;
	}

	/* Read the object code using objdump */
	/* Read the object code using objdump */
	objdump_addr = map__rip_2objdump(al.map, al.addr);
	objdump_addr = map__rip_2objdump(al.map, al.addr);
	ret = read_via_objdump(al.map->dso->long_name, objdump_addr, buf2, len);
	ret = read_via_objdump(objdump_name, objdump_addr, buf2, len);

	if (dso__needs_decompress(al.map->dso))
		unlink(objdump_name);

	if (ret > 0) {
	if (ret > 0) {
		/*
		/*
		 * The kernel maps are inaccurate - assume objdump is right in
		 * The kernel maps are inaccurate - assume objdump is right in
+12 −25
Original line number Original line Diff line number Diff line
@@ -1321,6 +1321,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
	char linkname[PATH_MAX];
	char linkname[PATH_MAX];
	char *build_id_filename;
	char *build_id_filename;
	char *build_id_path = NULL;
	char *build_id_path = NULL;
	char *pos;


	if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
	if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
	    !dso__is_kcore(dso))
	    !dso__is_kcore(dso))
@@ -1340,6 +1341,13 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
	if (!build_id_path)
	if (!build_id_path)
		return -1;
		return -1;


	/*
	 * old style build-id cache has name of XX/XXXXXXX.. while
	 * new style has XX/XXXXXXX../{elf,kallsyms,vdso}.
	 * extract the build-id part of dirname in the new style only.
	 */
	pos = strrchr(build_id_path, '/');
	if (pos && strlen(pos) < SBUILD_ID_SIZE - 2)
		dirname(build_id_path);
		dirname(build_id_path);


	if (dso__is_kcore(dso) ||
	if (dso__is_kcore(dso) ||
@@ -1423,31 +1431,10 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
				sizeof(symfs_filename));
				sizeof(symfs_filename));
		}
		}
	} else if (dso__needs_decompress(dso)) {
	} else if (dso__needs_decompress(dso)) {
		char tmp[PATH_MAX];
		char tmp[KMOD_DECOMP_LEN];
		struct kmod_path m;
		int fd;
		bool ret;

		if (kmod_path__parse_ext(&m, symfs_filename))
			goto out;

		snprintf(tmp, PATH_MAX, "/tmp/perf-kmod-XXXXXX");

		fd = mkstemp(tmp);
		if (fd < 0) {
			free(m.ext);
			goto out;
		}

		ret = decompress_to_file(m.ext, symfs_filename, fd);

		if (ret)
			pr_err("Cannot decompress %s %s\n", m.ext, symfs_filename);

		free(m.ext);
		close(fd);


		if (!ret)
		if (dso__decompress_kmodule_path(dso, symfs_filename,
						 tmp, sizeof(tmp)) < 0)
			goto out;
			goto out;


		strcpy(symfs_filename, tmp);
		strcpy(symfs_filename, tmp);
Loading