Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo-4.20-20180905' of git://git.kernel.org…
Browse files Browse the repository at this point in the history
…/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo:

perf trace:

- Augment the payload of syscall entry/exit tracepoints with the contents
  of pointer arguments, such as the "filename" argument to the "open"
  syscall or the 'struct sockaddr *' argument to the 'connect' syscall.

  This is done using a BPF program that gets compiled and attached to
  various syscalls:sys_enter_NAME tracepoints, copying via a BPF map and
  "bpf-output" perf event the raw_syscalls:sys_enter tracepoint payload +
  the contents of pointer arguments using the "probe_read", "probe_read_str"
  and "perf_event_output" BPF functions.

  The 'perf trace' codebase now just processes these augmented tracepoints
  using the existing beautifiers that now check if there is more in the
  perf_sample->raw_data than what is expected for a normal syscall enter
  tracepoint (the common preamble, syscall id, up to six parameters),
  using that with hand crafted struct beautifiers.

  This is just to show how to augment the existing tracepoints, work will
  be done to use DWARF or BTF info to do the pretty-printing and to create
  the collectors.

  For now this is done using an example restricted C BPF program, but the
  end goal is to have this all autogenerated and done transparently.

  Its still useful to have this example as one can use it as an skeleton and
  write more involved filters, see the etcsnoop.c BPF example, for instance.

  E.g.:

  # cd tools/perf/examples/bpf/
  # perf trace -e augmented_syscalls.c ping -c 1 ::1
     0.000 ( 0.008 ms): openat(dfd: CWD, filename: /etc/ld.so.cache, flags: CLOEXEC) = 3
     0.020 ( 0.004 ms): openat(dfd: CWD, filename: /lib64/libcap.so.2, flags: CLOEXEC) = 3
     0.051 ( 0.004 ms): openat(dfd: CWD, filename: /lib64/libidn.so.11, flags: CLOEXEC) = 3
     0.076 ( 0.003 ms): openat(dfd: CWD, filename: /lib64/libcrypto.so.1.1, flags: CLOEXEC) = 3
     0.106 ( 0.003 ms): openat(dfd: CWD, filename: /lib64/libresolv.so.2, flags: CLOEXEC) = 3
     0.136 ( 0.004 ms): openat(dfd: CWD, filename: /lib64/libm.so.6, flags: CLOEXEC) = 3
     0.194 ( 0.004 ms): openat(dfd: CWD, filename: /lib64/libc.so.6, flags: CLOEXEC) = 3
     0.224 ( 0.003 ms): openat(dfd: CWD, filename: /lib64/libz.so.1, flags: CLOEXEC) = 3
     0.252 ( 0.004 ms): openat(dfd: CWD, filename: /lib64/libdl.so.2, flags: CLOEXEC) = 3
     0.275 ( 0.003 ms): openat(dfd: CWD, filename: /lib64/libpthread.so.0, flags: CLOEXEC) = 3
     0.730 ( 0.007 ms): open(filename: /usr/lib/locale/locale-archive, flags: CLOEXEC) = 3
  PING ::1(::1) 56 data bytes
     0.834 ( 0.008 ms): connect(fd: 5, uservaddr: { .family: INET6, port: 1025, addr: ::1 }, addrlen: 28) = 0
  64 bytes from ::1: icmp_seq=1 ttl=64 time=0.032 ms

  --- ::1 ping statistics ---
  1 packets transmitted, 1 received, 0% packet loss, time 0ms
  rtt min/avg/max/mdev = 0.032/0.032/0.032/0.000 ms
     0.914 ( 0.036 ms): sendto(fd: 4<socket:[843044]>, buff: 0x55b5e52e9720, len: 64, addr: { .family: INET6, port: 58, addr: ::1 }, addr_len: 28) = 64
  #

  Use 'perf trace -e augmented_syscalls.c,close ping -c 1 ::1' to see the
  'close' calls as well, as it is not one of the syscalls augmented in that .c
  file.

  (Arnaldo Carvalho de Melo)

- Alias 'umount' to 'umount2' (Benjamin Peterson)

perf stat: (Jiri Olsa)

- Make many builtin-stat.c functions generic, moving display functions
  to a separate file, prep work for adding the ability to store/display
  stat data in perf record/top.

perf annotate: (Kim Phillips)

- Handle arm64 move instructions

perf report: (Thomas Richter):

- Create auxiliary trace data files for s390

libtraceevent: (Tzvetomir Stoyanov (VMware)):

- Split trace-seq related APIs in a separate header file.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Thomas Gleixner committed Sep 6, 2018
2 parents 60c1f89 + 1632936 commit bda58ee
Show file tree
Hide file tree
Showing 55 changed files with 2,543 additions and 1,573 deletions.
11 changes: 3 additions & 8 deletions kernel/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2867,16 +2867,11 @@ static int perf_event_modify_breakpoint(struct perf_event *bp,
_perf_event_disable(bp);

err = modify_user_hw_breakpoint_check(bp, attr, true);
if (err) {
if (!bp->attr.disabled)
_perf_event_enable(bp);

return err;
}

if (!attr->disabled)
if (!bp->attr.disabled)
_perf_event_enable(bp);
return 0;

return err;
}

static int perf_event_modify_attr(struct perf_event *event,
Expand Down
13 changes: 6 additions & 7 deletions kernel/events/hw_breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,8 @@ modify_user_hw_breakpoint_check(struct perf_event *bp, struct perf_event_attr *a
*/
int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr)
{
int err;

/*
* modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it
* will not be possible to raise IPIs that invoke __perf_event_disable.
Expand All @@ -520,15 +522,12 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att
else
perf_event_disable(bp);

if (!attr->disabled) {
int err = modify_user_hw_breakpoint_check(bp, attr, false);
err = modify_user_hw_breakpoint_check(bp, attr, false);

if (err)
return err;
if (!bp->attr.disabled)
perf_event_enable(bp);
bp->attr.disabled = 0;
}
return 0;

return err;
}
EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint);

Expand Down
1 change: 1 addition & 0 deletions tools/lib/traceevent/event-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <netinet/in.h>
#include "event-parse.h"
#include "event-utils.h"
#include "trace-seq.h"

static const char *input_buf;
static unsigned long long input_buf_ptr;
Expand Down
46 changes: 2 additions & 44 deletions tools/lib/traceevent/event-parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,12 @@
#include <regex.h>
#include <string.h>

#include "trace-seq.h"

#ifndef __maybe_unused
#define __maybe_unused __attribute__((unused))
#endif

/* ----------------------- trace_seq ----------------------- */


#ifndef TRACE_SEQ_BUF_SIZE
#define TRACE_SEQ_BUF_SIZE 4096
#endif

#ifndef DEBUG_RECORD
#define DEBUG_RECORD 0
#endif
Expand All @@ -59,43 +54,6 @@ struct tep_record {
#endif
};

enum trace_seq_fail {
TRACE_SEQ__GOOD,
TRACE_SEQ__BUFFER_POISONED,
TRACE_SEQ__MEM_ALLOC_FAILED,
};

/*
* Trace sequences are used to allow a function to call several other functions
* to create a string of data to use (up to a max of PAGE_SIZE).
*/

struct trace_seq {
char *buffer;
unsigned int buffer_size;
unsigned int len;
unsigned int readpos;
enum trace_seq_fail state;
};

void trace_seq_init(struct trace_seq *s);
void trace_seq_reset(struct trace_seq *s);
void trace_seq_destroy(struct trace_seq *s);

extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
extern int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
__attribute__ ((format (printf, 2, 0)));

extern int trace_seq_puts(struct trace_seq *s, const char *str);
extern int trace_seq_putc(struct trace_seq *s, unsigned char c);

extern void trace_seq_terminate(struct trace_seq *s);

extern int trace_seq_do_fprintf(struct trace_seq *s, FILE *fp);
extern int trace_seq_do_printf(struct trace_seq *s);


/* ----------------------- pevent ----------------------- */

struct tep_handle;
Expand Down
1 change: 1 addition & 0 deletions tools/lib/traceevent/event-plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <dirent.h>
#include "event-parse.h"
#include "event-utils.h"
#include "trace-seq.h"

#define LOCAL_PLUGIN_DIR ".traceevent/plugins"

Expand Down
1 change: 1 addition & 0 deletions tools/lib/traceevent/plugin_function.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "event-parse.h"
#include "event-utils.h"
#include "trace-seq.h"

static struct func_stack {
int size;
Expand Down
1 change: 1 addition & 0 deletions tools/lib/traceevent/plugin_hrtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <string.h>

#include "event-parse.h"
#include "trace-seq.h"

static int timer_expire_handler(struct trace_seq *s,
struct tep_record *record,
Expand Down
1 change: 1 addition & 0 deletions tools/lib/traceevent/plugin_jbd2.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <string.h>

#include "event-parse.h"
#include "trace-seq.h"

#define MINORBITS 20
#define MINORMASK ((1U << MINORBITS) - 1)
Expand Down
1 change: 1 addition & 0 deletions tools/lib/traceevent/plugin_kmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <string.h>

#include "event-parse.h"
#include "trace-seq.h"

static int call_site_handler(struct trace_seq *s, struct tep_record *record,
struct event_format *event, void *context)
Expand Down
1 change: 1 addition & 0 deletions tools/lib/traceevent/plugin_kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <stdint.h>

#include "event-parse.h"
#include "trace-seq.h"

#ifdef HAVE_UDIS86

Expand Down
1 change: 1 addition & 0 deletions tools/lib/traceevent/plugin_mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <string.h>

#include "event-parse.h"
#include "trace-seq.h"

#define INDENT 65

Expand Down
1 change: 1 addition & 0 deletions tools/lib/traceevent/plugin_sched_switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <string.h>

#include "event-parse.h"
#include "trace-seq.h"

static void write_state(struct trace_seq *s, int val)
{
Expand Down
1 change: 1 addition & 0 deletions tools/lib/traceevent/plugin_scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <string.h>
#include <inttypes.h>
#include "event-parse.h"
#include "trace-seq.h"

typedef unsigned long sector_t;
typedef uint64_t u64;
Expand Down
1 change: 1 addition & 0 deletions tools/lib/traceevent/plugin_xen.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include "event-parse.h"
#include "trace-seq.h"

#define __HYPERVISOR_set_trap_table 0
#define __HYPERVISOR_mmu_update 1
Expand Down
2 changes: 2 additions & 0 deletions tools/lib/traceevent/trace-seq.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
*/
#include "trace-seq.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down
55 changes: 55 additions & 0 deletions tools/lib/traceevent/trace-seq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: LGPL-2.1
/*
* Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
*/

#ifndef _TRACE_SEQ_H
#define _TRACE_SEQ_H

#include <stdarg.h>
#include <stdio.h>

/* ----------------------- trace_seq ----------------------- */

#ifndef TRACE_SEQ_BUF_SIZE
#define TRACE_SEQ_BUF_SIZE 4096
#endif

enum trace_seq_fail {
TRACE_SEQ__GOOD,
TRACE_SEQ__BUFFER_POISONED,
TRACE_SEQ__MEM_ALLOC_FAILED,
};

/*
* Trace sequences are used to allow a function to call several other functions
* to create a string of data to use (up to a max of PAGE_SIZE).
*/

struct trace_seq {
char *buffer;
unsigned int buffer_size;
unsigned int len;
unsigned int readpos;
enum trace_seq_fail state;
};

void trace_seq_init(struct trace_seq *s);
void trace_seq_reset(struct trace_seq *s);
void trace_seq_destroy(struct trace_seq *s);

extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
extern int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
__attribute__ ((format (printf, 2, 0)));

extern int trace_seq_puts(struct trace_seq *s, const char *str);
extern int trace_seq_putc(struct trace_seq *s, unsigned char c);

extern void trace_seq_terminate(struct trace_seq *s);

extern int trace_seq_do_fprintf(struct trace_seq *s, FILE *fp);
extern int trace_seq_do_printf(struct trace_seq *s);

#endif /* _TRACE_SEQ_H */
16 changes: 8 additions & 8 deletions tools/perf/Makefile.perf
Original file line number Diff line number Diff line change
Expand Up @@ -777,14 +777,14 @@ endif
$(call QUIET_INSTALL, libexec) \
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
ifndef NO_LIBBPF
$(call QUIET_INSTALL, lib) \
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'
$(call QUIET_INSTALL, include/bpf) \
$(INSTALL) include/bpf/*.h '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'
$(call QUIET_INSTALL, lib) \
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'
$(call QUIET_INSTALL, examples/bpf) \
$(INSTALL) examples/bpf/*.c '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'
$(call QUIET_INSTALL, bpf-headers) \
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf/linux'; \
$(INSTALL) include/bpf/*.h -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \
$(INSTALL) include/bpf/linux/*.h -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf/linux'
$(call QUIET_INSTALL, bpf-examples) \
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'; \
$(INSTALL) examples/bpf/*.c -t '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'
endif
$(call QUIET_INSTALL, perf-archive) \
$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
Expand Down
5 changes: 3 additions & 2 deletions tools/perf/arch/arm64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1

out := $(OUTPUT)arch/arm64/include/generated/asm
header := $(out)/syscalls.c
sysdef := $(srctree)/tools/include/uapi/asm-generic/unistd.h
incpath := $(srctree)/tools
sysdef := $(srctree)/tools/arch/arm64/include/uapi/asm/unistd.h
sysprf := $(srctree)/tools/perf/arch/arm64/entry/syscalls/
systbl := $(sysprf)/mksyscalltbl

# Create output directory if not already present
_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')

$(header): $(sysdef) $(systbl)
$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(sysdef) > $@
$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@

clean::
$(call QUIET_CLEAN, arm64) $(RM) $(header)
Expand Down
59 changes: 58 additions & 1 deletion tools/perf/arch/arm64/annotate/instructions.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,63 @@ struct arm64_annotate {
jump_insn;
};

static int arm64_mov__parse(struct arch *arch __maybe_unused,
struct ins_operands *ops,
struct map_symbol *ms __maybe_unused)
{
char *s = strchr(ops->raw, ','), *target, *endptr;

if (s == NULL)
return -1;

*s = '\0';
ops->source.raw = strdup(ops->raw);
*s = ',';

if (ops->source.raw == NULL)
return -1;

target = ++s;
ops->target.raw = strdup(target);
if (ops->target.raw == NULL)
goto out_free_source;

ops->target.addr = strtoull(target, &endptr, 16);
if (endptr == target)
goto out_free_target;

s = strchr(endptr, '<');
if (s == NULL)
goto out_free_target;
endptr = strchr(s + 1, '>');
if (endptr == NULL)
goto out_free_target;

*endptr = '\0';
*s = ' ';
ops->target.name = strdup(s);
*s = '<';
*endptr = '>';
if (ops->target.name == NULL)
goto out_free_target;

return 0;

out_free_target:
zfree(&ops->target.raw);
out_free_source:
zfree(&ops->source.raw);
return -1;
}

static int mov__scnprintf(struct ins *ins, char *bf, size_t size,
struct ins_operands *ops);

static struct ins_ops arm64_mov_ops = {
.parse = arm64_mov__parse,
.scnprintf = mov__scnprintf,
};

static struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const char *name)
{
struct arm64_annotate *arm = arch->priv;
Expand All @@ -21,7 +78,7 @@ static struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const
else if (!strcmp(name, "ret"))
ops = &ret_ops;
else
return NULL;
ops = &arm64_mov_ops;

arch__associate_ins_ops(arch, name, ops);
return ops;
Expand Down
Loading

0 comments on commit bda58ee

Please sign in to comment.