Skip to content

Commit

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

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

 * 'perf trace' arg formatting improvements to allow masking arguments
   in syscalls such as futex and open, where the some arguments are
   ignored and thus should not be printed depending on other args.

 * Beautify futex open, openat, open_by_handle_at, lseek and futex syscalls.

 * Add dummy software event to use when wanting just to keep receiving
   PERF_RECORD_{MMAP,COMM,etc}, add test for it, from Adrian Hunter.

 * Fix symbol offset computation for some dsos in 'perf script', from David Ahern.

 * Skip unsupported hardware events in 'perf list', from Namhyung Kim.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed Sep 3, 2013
2 parents 7bfb7e6 + 31cd385 commit 61bf86a
Show file tree
Hide file tree
Showing 14 changed files with 424 additions and 18 deletions.
1 change: 1 addition & 0 deletions include/uapi/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ enum perf_sw_ids {
PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
PERF_COUNT_SW_EMULATION_FAULTS = 8,
PERF_COUNT_SW_DUMMY = 9,

PERF_COUNT_SW_MAX, /* non-ABI */
};
Expand Down
1 change: 1 addition & 0 deletions tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ endif # NO_LIBELF
ifndef NO_LIBUNWIND
LIB_OBJS += $(OUTPUT)util/unwind.o
endif
LIB_OBJS += $(OUTPUT)tests/keep-tracking.o

ifndef NO_LIBAUDIT
BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
Expand Down
180 changes: 167 additions & 13 deletions tools/perf/builtin-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,49 @@
#include <libaudit.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <linux/futex.h>

static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, unsigned long arg)
static size_t syscall_arg__scnprintf_hex(char *bf, size_t size,
unsigned long arg,
u8 arg_idx __maybe_unused,
u8 *arg_mask __maybe_unused)
{
return scnprintf(bf, size, "%#lx", arg);
}

#define SCA_HEX syscall_arg__scnprintf_hex

static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, unsigned long arg)
static size_t syscall_arg__scnprintf_whence(char *bf, size_t size,
unsigned long arg,
u8 arg_idx __maybe_unused,
u8 *arg_mask __maybe_unused)
{
int whence = arg;

switch (whence) {
#define P_WHENCE(n) case SEEK_##n: return scnprintf(bf, size, #n)
P_WHENCE(SET);
P_WHENCE(CUR);
P_WHENCE(END);
#ifdef SEEK_DATA
P_WHENCE(DATA);
#endif
#ifdef SEEK_HOLE
P_WHENCE(HOLE);
#endif
#undef P_WHENCE
default: break;
}

return scnprintf(bf, size, "%#x", whence);
}

#define SCA_WHENCE syscall_arg__scnprintf_whence

static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
unsigned long arg,
u8 arg_idx __maybe_unused,
u8 *arg_mask __maybe_unused)
{
int printed = 0, prot = arg;

Expand Down Expand Up @@ -52,7 +86,9 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, unsigned l

#define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot

static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, unsigned long arg)
static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
unsigned long arg, u8 arg_idx __maybe_unused,
u8 *arg_mask __maybe_unused)
{
int printed = 0, flags = arg;

Expand Down Expand Up @@ -92,7 +128,9 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, unsigned

#define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags

static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size, unsigned long arg)
static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
unsigned long arg, u8 arg_idx __maybe_unused,
u8 *arg_mask __maybe_unused)
{
int behavior = arg;

Expand Down Expand Up @@ -133,10 +171,111 @@ static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size, uns

#define SCA_MADV_BHV syscall_arg__scnprintf_madvise_behavior

static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, unsigned long arg,
u8 arg_idx __maybe_unused, u8 *arg_mask)
{
enum syscall_futex_args {
SCF_UADDR = (1 << 0),
SCF_OP = (1 << 1),
SCF_VAL = (1 << 2),
SCF_TIMEOUT = (1 << 3),
SCF_UADDR2 = (1 << 4),
SCF_VAL3 = (1 << 5),
};
int op = arg;
int cmd = op & FUTEX_CMD_MASK;
size_t printed = 0;

switch (cmd) {
#define P_FUTEX_OP(n) case FUTEX_##n: printed = scnprintf(bf, size, #n);
P_FUTEX_OP(WAIT); *arg_mask |= SCF_VAL3|SCF_UADDR2; break;
P_FUTEX_OP(WAKE); *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
P_FUTEX_OP(FD); *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
P_FUTEX_OP(REQUEUE); *arg_mask |= SCF_VAL3|SCF_TIMEOUT; break;
P_FUTEX_OP(CMP_REQUEUE); *arg_mask |= SCF_TIMEOUT; break;
P_FUTEX_OP(CMP_REQUEUE_PI); *arg_mask |= SCF_TIMEOUT; break;
P_FUTEX_OP(WAKE_OP); break;
P_FUTEX_OP(LOCK_PI); *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
P_FUTEX_OP(UNLOCK_PI); *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
P_FUTEX_OP(TRYLOCK_PI); *arg_mask |= SCF_VAL3|SCF_UADDR2; break;
P_FUTEX_OP(WAIT_BITSET); *arg_mask |= SCF_UADDR2; break;
P_FUTEX_OP(WAKE_BITSET); *arg_mask |= SCF_UADDR2; break;
P_FUTEX_OP(WAIT_REQUEUE_PI); break;
default: printed = scnprintf(bf, size, "%#x", cmd); break;
}

if (op & FUTEX_PRIVATE_FLAG)
printed += scnprintf(bf + printed, size - printed, "|PRIV");

if (op & FUTEX_CLOCK_REALTIME)
printed += scnprintf(bf + printed, size - printed, "|CLKRT");

return printed;
}

#define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op

static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size,
unsigned long arg,
u8 arg_idx, u8 *arg_mask)
{
int printed = 0, flags = arg;

if (!(flags & O_CREAT))
*arg_mask |= 1 << (arg_idx + 1); /* Mask the mode parm */

if (flags == 0)
return scnprintf(bf, size, "RDONLY");
#define P_FLAG(n) \
if (flags & O_##n) { \
printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
flags &= ~O_##n; \
}

P_FLAG(APPEND);
P_FLAG(ASYNC);
P_FLAG(CLOEXEC);
P_FLAG(CREAT);
P_FLAG(DIRECT);
P_FLAG(DIRECTORY);
P_FLAG(EXCL);
P_FLAG(LARGEFILE);
P_FLAG(NOATIME);
P_FLAG(NOCTTY);
#ifdef O_NONBLOCK
P_FLAG(NONBLOCK);
#elif O_NDELAY
P_FLAG(NDELAY);
#endif
#ifdef O_PATH
P_FLAG(PATH);
#endif
P_FLAG(RDWR);
#ifdef O_DSYNC
if ((flags & O_SYNC) == O_SYNC)
printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", "SYNC");
else {
P_FLAG(DSYNC);
}
#else
P_FLAG(SYNC);
#endif
P_FLAG(TRUNC);
P_FLAG(WRONLY);
#undef P_FLAG

if (flags)
printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);

return printed;
}

#define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags

static struct syscall_fmt {
const char *name;
const char *alias;
size_t (*arg_scnprintf[6])(char *bf, size_t size, unsigned long arg);
size_t (*arg_scnprintf[6])(char *bf, size_t size, unsigned long arg, u8 arg_idx, u8 *arg_mask);
bool errmsg;
bool timeout;
bool hexret;
Expand All @@ -149,9 +288,12 @@ static struct syscall_fmt {
{ .name = "connect", .errmsg = true, },
{ .name = "fstat", .errmsg = true, .alias = "newfstat", },
{ .name = "fstatat", .errmsg = true, .alias = "newfstatat", },
{ .name = "futex", .errmsg = true, },
{ .name = "futex", .errmsg = true,
.arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, },
{ .name = "ioctl", .errmsg = true,
.arg_scnprintf = { [2] = SCA_HEX, /* arg */ }, },
{ .name = "lseek", .errmsg = true,
.arg_scnprintf = { [2] = SCA_WHENCE, /* whence */ }, },
{ .name = "lstat", .errmsg = true, .alias = "newlstat", },
{ .name = "madvise", .errmsg = true,
.arg_scnprintf = { [0] = SCA_HEX, /* start */
Expand All @@ -168,7 +310,12 @@ static struct syscall_fmt {
[4] = SCA_HEX, /* new_addr */ }, },
{ .name = "munmap", .errmsg = true,
.arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
{ .name = "open", .errmsg = true, },
{ .name = "open", .errmsg = true,
.arg_scnprintf = { [1] = SCA_OPEN_FLAGS, /* flags */ }, },
{ .name = "open_by_handle_at", .errmsg = true,
.arg_scnprintf = { [2] = SCA_OPEN_FLAGS, /* flags */ }, },
{ .name = "openat", .errmsg = true,
.arg_scnprintf = { [2] = SCA_OPEN_FLAGS, /* flags */ }, },
{ .name = "poll", .errmsg = true, .timeout = true, },
{ .name = "ppoll", .errmsg = true, .timeout = true, },
{ .name = "pread", .errmsg = true, .alias = "pread64", },
Expand Down Expand Up @@ -198,7 +345,8 @@ struct syscall {
const char *name;
bool filtered;
struct syscall_fmt *fmt;
size_t (**arg_scnprintf)(char *bf, size_t size, unsigned long arg);
size_t (**arg_scnprintf)(char *bf, size_t size,
unsigned long arg, u8 arg_idx, u8 *args_mask);
};

static size_t fprintf_duration(unsigned long t, FILE *fp)
Expand Down Expand Up @@ -443,17 +591,23 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,

if (sc->tp_format != NULL) {
struct format_field *field;
u8 mask = 0, bit = 1;

for (field = sc->tp_format->format.fields->next; field;
field = field->next, ++i, bit <<= 1) {
if (mask & bit)
continue;

for (field = sc->tp_format->format.fields->next; field; field = field->next) {
printed += scnprintf(bf + printed, size - printed,
"%s%s: ", printed ? ", " : "", field->name);

if (sc->arg_scnprintf && sc->arg_scnprintf[i])
printed += sc->arg_scnprintf[i](bf + printed, size - printed, args[i]);
else
if (sc->arg_scnprintf && sc->arg_scnprintf[i]) {
printed += sc->arg_scnprintf[i](bf + printed, size - printed,
args[i], i, &mask);
} else {
printed += scnprintf(bf + printed, size - printed,
"%ld", args[i]);
++i;
}
}
} else {
while (i < 6) {
Expand Down
4 changes: 4 additions & 0 deletions tools/perf/tests/builtin-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ static struct test {
.desc = "Test sample parsing",
.func = test__sample_parsing,
},
{
.desc = "Test using a dummy software event to keep tracking",
.func = test__keep_tracking,
},
{
.func = NULL,
},
Expand Down
Loading

0 comments on commit 61bf86a

Please sign in to comment.