From 69fb09f6ccdb2f070557fd1f4c56c4d646694c8e Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Fri, 7 Jul 2017 13:06:34 +0800 Subject: perf annotate: Check for fused instructions Macro fusion merges two instructions to a single micro-op. Intel core platform performs this hardware optimization under limited circumstances. For example, CMP + JCC can be "fused" and executed /retired together. While with sampling this can result in the sample sometimes being on the JCC and sometimes on the CMP. So for the fused instruction pair, they could be considered together. On Nehalem, fused instruction pairs: cmp/test + jcc. On other new CPU: cmp/test/add/sub/and/inc/dec + jcc. This patch adds an x86-specific function which checks if 2 instructions are in a "fused" pair. For non-x86 arch, the function is just NULL. Changelog: v4: Move the CPU model checking to symbol__disassemble and save the CPU family/model in arch structure. It avoids checking every time when jump arrow printed. v3: Add checking for Nehalem (CMP, TEST). For other newer Intel CPUs just check it by default (CMP, TEST, ADD, SUB, AND, INC, DEC). v2: Remove the original weak function. Arnaldo points out that doing it as a weak function that will be overridden by the host arch doesn't work. So now it's implemented as an arch-specific function. Committer fix: Do not access evsel->evlist->env->cpuid, ->env can be null, introduce perf_evsel__env_cpuid(), just like perf_evsel__env_arch(), also used in this function call. The original patch was segfaulting 'perf top' + annotation. But this essentially disables this fused instructions augmentation in 'perf top', the right thing is to get the cpuid from the running kernel, left for a later patch tho. Signed-off-by: Yao Jin Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1499403995-19857-2-git-send-email-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/annotate/instructions.c | 46 +++++++++++++++++++++++++++++ tools/perf/builtin-top.c | 2 +- tools/perf/ui/browsers/annotate.c | 4 ++- tools/perf/ui/gtk/annotate.c | 2 +- tools/perf/util/annotate.c | 22 ++++++++++++-- tools/perf/util/annotate.h | 3 +- tools/perf/util/evsel.c | 7 +++++ tools/perf/util/evsel.h | 1 + 8 files changed, 81 insertions(+), 6 deletions(-) diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/x86/annotate/instructions.c index c1625f256df3..d84b72063a30 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/arch/x86/annotate/instructions.c @@ -76,3 +76,49 @@ static struct ins x86__instructions[] = { { .name = "xbeginq", .ops = &jump_ops, }, { .name = "retq", .ops = &ret_ops, }, }; + +static bool x86__ins_is_fused(struct arch *arch, const char *ins1, + const char *ins2) +{ + if (arch->family != 6 || arch->model < 0x1e || strstr(ins2, "jmp")) + return false; + + if (arch->model == 0x1e) { + /* Nehalem */ + if ((strstr(ins1, "cmp") && !strstr(ins1, "xchg")) || + strstr(ins1, "test")) { + return true; + } + } else { + /* Newer platform */ + if ((strstr(ins1, "cmp") && !strstr(ins1, "xchg")) || + strstr(ins1, "test") || + strstr(ins1, "add") || + strstr(ins1, "sub") || + strstr(ins1, "and") || + strstr(ins1, "inc") || + strstr(ins1, "dec")) { + return true; + } + } + + return false; +} + +static int x86__cpuid_parse(struct arch *arch, char *cpuid) +{ + unsigned int family, model, stepping; + int ret; + + /* + * cpuid = "GenuineIntel,family,model,stepping" + */ + ret = sscanf(cpuid, "%*[^,],%u,%u,%u", &family, &model, &stepping); + if (ret == 3) { + arch->family = family; + arch->model = model; + return 0; + } + + return -1; +} diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 6052376634c0..022486dc67f5 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -134,7 +134,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) return err; } - err = symbol__disassemble(sym, map, NULL, 0, NULL); + err = symbol__disassemble(sym, map, NULL, 0, NULL, NULL); if (err == 0) { out_assign: top->sym_filter_entry = he; diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 27f41f28dcb4..c4336138b673 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -9,6 +9,7 @@ #include "../../util/symbol.h" #include "../../util/evsel.h" #include "../../util/config.h" +#include "../../util/evlist.h" #include #include #include @@ -1074,7 +1075,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, } err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), - sizeof_bdl, &browser.arch); + sizeof_bdl, &browser.arch, + perf_evsel__env_cpuid(evsel)); if (err) { char msg[BUFSIZ]; symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index d903fd493416..87e3760624f2 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -169,7 +169,7 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map, return -1; err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), - 0, NULL); + 0, NULL, NULL); if (err) { char msg[BUFSIZ]; symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index be1caabb9290..8748ebb3f932 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -47,7 +47,12 @@ struct arch { bool sorted_instructions; bool initialized; void *priv; + unsigned int model; + unsigned int family; int (*init)(struct arch *arch); + bool (*ins_is_fused)(struct arch *arch, const char *ins1, + const char *ins2); + int (*cpuid_parse)(struct arch *arch, char *cpuid); struct { char comment_char; char skip_functions_char; @@ -129,6 +134,8 @@ static struct arch architectures[] = { .name = "x86", .instructions = x86__instructions, .nr_instructions = ARRAY_SIZE(x86__instructions), + .ins_is_fused = x86__ins_is_fused, + .cpuid_parse = x86__cpuid_parse, .objdump = { .comment_char = '#', }, @@ -171,6 +178,14 @@ int ins__scnprintf(struct ins *ins, char *bf, size_t size, return ins__raw_scnprintf(ins, bf, size, ops); } +bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) +{ + if (!arch || !arch->ins_is_fused) + return false; + + return arch->ins_is_fused(arch, ins1, ins2); +} + static int call__parse(struct arch *arch, struct ins_operands *ops, struct map *map) { char *endptr, *tok, *name; @@ -1381,7 +1396,7 @@ static const char *annotate__norm_arch(const char *arch_name) int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize, - struct arch **parch) + struct arch **parch, char *cpuid) { struct dso *dso = map->dso; char command[PATH_MAX * 2]; @@ -1418,6 +1433,9 @@ int symbol__disassemble(struct symbol *sym, struct map *map, } } + if (arch->cpuid_parse && cpuid) + arch->cpuid_parse(arch, cpuid); + pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, symfs_filename, sym->name, map->unmap_ip(map, sym->start), map->unmap_ip(map, sym->end)); @@ -1907,7 +1925,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, u64 len; if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), - 0, NULL) < 0) + 0, NULL, NULL) < 0) return -1; len = symbol__size(sym); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 21055034aedd..72d72728a0fc 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -53,6 +53,7 @@ bool ins__is_jump(const struct ins *ins); bool ins__is_call(const struct ins *ins); bool ins__is_ret(const struct ins *ins); int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops); +bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2); struct annotation; @@ -160,7 +161,7 @@ void symbol__annotate_zero_histograms(struct symbol *sym); int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize, - struct arch **parch); + struct arch **parch, char *cpuid); enum symbol_disassemble_errno { SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0, diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 413f74df08de..0e4cd6092564 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2610,3 +2610,10 @@ char *perf_evsel__env_arch(struct perf_evsel *evsel) return evsel->evlist->env->arch; return NULL; } + +char *perf_evsel__env_cpuid(struct perf_evsel *evsel) +{ + if (evsel && evsel->evlist && evsel->evlist->env) + return evsel->evlist->env->cpuid; + return NULL; +} diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index d101695c482c..219ad0cdb9f4 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -436,5 +436,6 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, attr__fprintf_f attr__fprintf, void *priv); char *perf_evsel__env_arch(struct perf_evsel *evsel); +char *perf_evsel__env_cpuid(struct perf_evsel *evsel); #endif /* __PERF_EVSEL_H */ -- cgit v1.2.3 From 7e63a13a266da652f82731b845b5c35dd866ec7e Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Fri, 7 Jul 2017 13:06:35 +0800 Subject: perf annotate: Implement visual marker for macro fusion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For marking fused instructions clearly this patch adds a line before the first instruction of pair and joins it with the arrow of the jump to its target. For example, when "je" is selected in annotate view, the line before cmpl is displayed and joins the arrow of "je". │ ┌──cmpl $0x0,argp_program_version_hook 81.93 │ ├──je 20 │ │ lock cmpxchg %esi,0x38a9a4(%rip) │ │↓ jne 29 │ │↓ jmp 43 11.47 │20:└─→cmpxch %esi,0x38a999(%rip) That means the cmpl+je is a fused instruction pair and they should be considered together. Changelog: v3: Use Arnaldo's fix to improve the arrow origin rendering. To get the evsel->evlist->env->cpuid, save the evsel in annotate_browser. v2: new function "ins__is_fused" to check if the instructions are fused. Signed-off-by: Yao Jin Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1499403995-19857-3-git-send-email-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browser.c | 29 +++++++++++++++++++++++++++++ tools/perf/ui/browser.h | 2 ++ tools/perf/ui/browsers/annotate.c | 26 ++++++++++++++++++++++++++ tools/perf/util/annotate.c | 5 +++++ tools/perf/util/annotate.h | 1 + 5 files changed, 63 insertions(+) diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 83874b0e266c..f73f3f13e01d 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -738,6 +738,35 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, __ui_browser__line_arrow_down(browser, column, start, end); } +void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column, + unsigned int row, bool arrow_down) +{ + unsigned int end_row; + + if (row >= browser->top_idx) + end_row = row - browser->top_idx; + else + return; + + SLsmg_set_char_set(1); + + if (arrow_down) { + ui_browser__gotorc(browser, end_row, column - 1); + SLsmg_write_char(SLSMG_ULCORN_CHAR); + ui_browser__gotorc(browser, end_row, column); + SLsmg_draw_hline(2); + ui_browser__gotorc(browser, end_row + 1, column - 1); + SLsmg_write_char(SLSMG_LTEE_CHAR); + } else { + ui_browser__gotorc(browser, end_row, column - 1); + SLsmg_write_char(SLSMG_LTEE_CHAR); + ui_browser__gotorc(browser, end_row, column); + SLsmg_draw_hline(2); + } + + SLsmg_set_char_set(0); +} + void ui_browser__init(void) { int i = 0; diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index be3b70eb5fca..a12eff75638b 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h @@ -43,6 +43,8 @@ void ui_browser__printf(struct ui_browser *browser, const char *fmt, ...); void ui_browser__write_graph(struct ui_browser *browser, int graph); void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, u64 start, u64 end); +void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column, + unsigned int row, bool arrow_down); void __ui_browser__show_title(struct ui_browser *browser, const char *title); void ui_browser__show_title(struct ui_browser *browser, const char *title); int ui_browser__show(struct ui_browser *browser, const char *title, diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index c4336138b673..8d3f6f53c122 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -273,6 +273,25 @@ static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sy return true; } +static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) +{ + struct disasm_line *pos = list_prev_entry(cursor, node); + const char *name; + + if (!pos) + return false; + + if (ins__is_lock(&pos->ins)) + name = pos->ops.locked.ins.name; + else + name = pos->ins.name; + + if (!name || !cursor->ins.name) + return false; + + return ins__is_fused(ab->arch, name, cursor->ins.name); +} + static void annotate_browser__draw_current_jump(struct ui_browser *browser) { struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); @@ -308,6 +327,13 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS); __ui_browser__line_arrow(browser, pcnt_width + 2 + ab->addr_width, from, to); + + if (is_fused(ab, cursor)) { + ui_browser__mark_fused(browser, + pcnt_width + 3 + ab->addr_width, + from - 1, + to > from ? true : false); + } } static unsigned int annotate_browser__refresh(struct ui_browser *browser) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 8748ebb3f932..ef434b53d849 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -517,6 +517,11 @@ bool ins__is_ret(const struct ins *ins) return ins->ops == &ret_ops; } +bool ins__is_lock(const struct ins *ins) +{ + return ins->ops == &lock_ops; +} + static int ins__key_cmp(const void *name, const void *insp) { const struct ins *ins = insp; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 72d72728a0fc..bac698d7cc6a 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -52,6 +52,7 @@ struct ins_ops { bool ins__is_jump(const struct ins *ins); bool ins__is_call(const struct ins *ins); bool ins__is_ret(const struct ins *ins); +bool ins__is_lock(const struct ins *ins); int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops); bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2); -- cgit v1.2.3 From e000e5e33f92f6bb2d24ba2cda143cb6bb872495 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 13 Jul 2017 13:07:00 -0300 Subject: perf trace: Remove F_ from some of the fcntl command strings The initial ones already had that "F_" prefix stripped to make things shorter, some hadn't, do it now. We do this to make the 'perf trace' output more compact. At some point perhaps the best thing to do is to have the tool do this stripping automatically, letting the user also decide if this is to be done or not. For now, be consistent. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-2iot106xkl8rgb0hb8zm3gq5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 4b2a5d298197..cfe1858ed074 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -407,9 +407,9 @@ static DEFINE_STRARRAY(whences); static const char *fcntl_cmds[] = { "DUPFD", "GETFD", "SETFD", "GETFL", "SETFL", "GETLK", "SETLK", - "SETLKW", "SETOWN", "GETOWN", "SETSIG", "GETSIG", "F_GETLK64", - "F_SETLK64", "F_SETLKW64", "F_SETOWN_EX", "F_GETOWN_EX", - "F_GETOWNER_UIDS", + "SETLKW", "SETOWN", "GETOWN", "SETSIG", "GETSIG", "GETLK64", + "SETLK64", "SETLKW64", "SETOWN_EX", "GETOWN_EX", + "GETOWNER_UIDS", }; static DEFINE_STRARRAY(fcntl_cmds); -- cgit v1.2.3 From 83a516943136456b9983a0cc8ab4fa5a59860898 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 13 Jul 2017 17:14:11 -0300 Subject: perf trace: Beautify linux specific fcntl commands We were only beautifying (transforming from an integer to its name) the non-linux specific fcntl syscall cmd args, fix it: Before: # perf trace -e fcntl -p 2472 0.000 ( 0.017 ms): gnome-terminal/2472 fcntl(fd: 55, cmd: 1030) = 56 ^C# After: # trace -e fcntl -p 2472 0.000 ( 0.015 ms): gnome-terminal/2472 fcntl(fd: 55, cmd: DUPFD_CLOEXEC) = 56 ^C# Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-zigsxruk4wbfn8iylboy9wzo@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 57 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index cfe1858ed074..431ef70067ed 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -64,6 +64,10 @@ # define O_CLOEXEC 02000000 #endif +#ifndef F_LINUX_SPECIFIC_BASE +# define F_LINUX_SPECIFIC_BASE 1024 +#endif + struct trace { struct perf_tool tool; struct syscalltbl *sctbl; @@ -317,6 +321,38 @@ static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, #define SCA_STRARRAY syscall_arg__scnprintf_strarray +struct strarrays { + int nr_entries; + struct strarray **entries; +}; + +#define DEFINE_STRARRAYS(array) struct strarrays strarrays__##array = { \ + .nr_entries = ARRAY_SIZE(array), \ + .entries = array, \ +} + +static size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, + struct syscall_arg *arg) +{ + struct strarrays *sas = arg->parm; + int i; + + for (i = 0; i < sas->nr_entries; ++i) { + struct strarray *sa = sas->entries[i]; + int idx = arg->val - sa->offset; + + if (idx >= 0 && idx < sa->nr_entries) { + if (sa->entries[idx] == NULL) + break; + return scnprintf(bf, size, "%s", sa->entries[idx]); + } + } + + return scnprintf(bf, size, "%d", arg->val); +} + +#define SCA_STRARRAYS syscall_arg__scnprintf_strarrays + #if defined(__i386__) || defined(__x86_64__) /* * FIXME: Make this available to all arches as soon as the ioctl beautifier @@ -413,6 +449,20 @@ static const char *fcntl_cmds[] = { }; static DEFINE_STRARRAY(fcntl_cmds); +static const char *fcntl_linux_specific_cmds[] = { + "SETLEASE", "GETLEASE", "NOTIFY", [5] = "CANCELLK", "DUPFD_CLOEXEC", + "SETPIPE_SZ", "GETPIPE_SZ", "ADD_SEALS", "GET_SEALS", +}; + +static DEFINE_STRARRAY_OFFSET(fcntl_linux_specific_cmds, F_LINUX_SPECIFIC_BASE); + +static struct strarray *fcntl_cmds_arrays[] = { + &strarray__fcntl_cmds, + &strarray__fcntl_linux_specific_cmds, +}; + +static DEFINE_STRARRAYS(fcntl_cmds_arrays); + static const char *rlimit_resources[] = { "CPU", "FSIZE", "DATA", "STACK", "CORE", "RSS", "NPROC", "NOFILE", "MEMLOCK", "AS", "LOCKS", "SIGPENDING", "MSGQUEUE", "NICE", "RTPRIO", @@ -613,8 +663,8 @@ static struct syscall_fmt { { .name = "fchownat", .errmsg = true, .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, { .name = "fcntl", .errmsg = true, - .arg_scnprintf = { [1] = SCA_STRARRAY, /* cmd */ }, - .arg_parm = { [1] = &strarray__fcntl_cmds, /* cmd */ }, }, + .arg_scnprintf = { [1] = SCA_STRARRAYS, /* cmd */ }, + .arg_parm = { [1] = &strarrays__fcntl_cmds_arrays, /* cmd */ }, }, { .name = "fdatasync", .errmsg = true, }, { .name = "flock", .errmsg = true, .arg_scnprintf = { [1] = SCA_FLOCK, /* cmd */ }, }, @@ -1356,7 +1406,8 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, */ if (val == 0 && !(sc->arg_scnprintf && - sc->arg_scnprintf[arg.idx] == SCA_STRARRAY && + (sc->arg_scnprintf[arg.idx] == SCA_STRARRAY || + sc->arg_scnprintf[arg.idx] == SCA_STRARRAYS) && sc->arg_parm[arg.idx])) continue; -- cgit v1.2.3 From ca3cf049d2430ac83eff5c32af7b86bb2d1285bf Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 13 Jul 2017 17:15:24 -0300 Subject: tools: Update include/uapi/linux/fcntl.h copy from the kernel To get the changes in the commit c75b1d9421f8 ("fs: add fcntl() interface for setting/getting write life time hints"). Silencing this perf build warning: Warning: include/uapi/linux/fcntl.h differs from kernel We already beautify the fcntl cmd argument, so an upcoming cset will update the 'cmd' strarray to cover these new commands. The hints are in the 3rd arg, a pointer, so not yet supported in 'perf trace', for that we need to copy it somehow, probably using eBPF, a new attempt at doing that is planned. Cc: Adrian Hunter Cc: David Ahern Cc: Jens Axboe Cc: Jiri Olsa Cc: Martin K. Petersen Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-al471wzs3x48alql0tm3mnfa@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/fcntl.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tools/include/uapi/linux/fcntl.h b/tools/include/uapi/linux/fcntl.h index 813afd6eee71..ec69d55bcec7 100644 --- a/tools/include/uapi/linux/fcntl.h +++ b/tools/include/uapi/linux/fcntl.h @@ -42,6 +42,27 @@ #define F_SEAL_WRITE 0x0008 /* prevent writes */ /* (1U << 31) is reserved for signed error codes */ +/* + * Set/Get write life time hints. {GET,SET}_RW_HINT operate on the + * underlying inode, while {GET,SET}_FILE_RW_HINT operate only on + * the specific file. + */ +#define F_GET_RW_HINT (F_LINUX_SPECIFIC_BASE + 11) +#define F_SET_RW_HINT (F_LINUX_SPECIFIC_BASE + 12) +#define F_GET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 13) +#define F_SET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 14) + +/* + * Valid hint values for F_{GET,SET}_RW_HINT. 0 is "not set", or can be + * used to clear any hints previously set. + */ +#define RWF_WRITE_LIFE_NOT_SET 0 +#define RWH_WRITE_LIFE_NONE 1 +#define RWH_WRITE_LIFE_SHORT 2 +#define RWH_WRITE_LIFE_MEDIUM 3 +#define RWH_WRITE_LIFE_LONG 4 +#define RWH_WRITE_LIFE_EXTREME 5 + /* * Types of directory notifications that may be requested. */ -- cgit v1.2.3 From 274e86fdd379992f90f37fab8df3f640c50fd2cb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 09:38:38 -0300 Subject: perf trace beauty: Export the strarrays scnprintf method As we'll call it from the fcntl cmd scnprintf method, that needs to look at the cmd to mask the next fcntl argument when it is ignored. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-fzlvkhew5vbxefneuciihgbc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 6 ++---- tools/perf/trace/beauty/beauty.h | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 431ef70067ed..ef1b1d4ea007 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -331,8 +331,8 @@ struct strarrays { .entries = array, \ } -static size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, - struct syscall_arg *arg) +size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, + struct syscall_arg *arg) { struct strarrays *sas = arg->parm; int i; @@ -351,8 +351,6 @@ static size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, return scnprintf(bf, size, "%d", arg->val); } -#define SCA_STRARRAYS syscall_arg__scnprintf_strarrays - #if defined(__i386__) || defined(__x86_64__) /* * FIXME: Make this available to all arches as soon as the ioctl beautifier diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index cf50be3f17a4..a6348073a6e9 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -15,6 +15,9 @@ struct syscall_arg { u8 mask; }; +size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_STRARRAYS syscall_arg__scnprintf_strarrays + size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags -- cgit v1.2.3 From 5ca55ab6def81f8cd19a8b88f2ba4abe1aed34cc Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 16:25:35 -0300 Subject: perf trace: Only build tools/perf/trace/beauty/ when building 'perf trace' As it calls functions in builtin-trace.c. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-bt3lhw1rvy3jzbsp2fvvegb0@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Build b/tools/perf/Build index bd8eeb60533c..b48ca40fccf9 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -50,6 +50,6 @@ libperf-y += util/ libperf-y += arch/ libperf-y += ui/ libperf-y += scripts/ -libperf-y += trace/beauty/ +libperf-$(CONFIG_AUDIT) += trace/beauty/ gtk-y += ui/gtk/ -- cgit v1.2.3 From 9cb7cf86440229fd6e6ad1718712742c344653d8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 09:44:50 -0300 Subject: perf trace beauty: Mask ignored fcntl 'arg' parameter A series of fcntl cmds ignore the third argument, so mask it. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-6vtl3zq1tauamrhm8o380ptn@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 2 +- tools/perf/trace/beauty/Build | 1 + tools/perf/trace/beauty/beauty.h | 3 +++ tools/perf/trace/beauty/fcntl.c | 23 +++++++++++++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tools/perf/trace/beauty/fcntl.c diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index ef1b1d4ea007..b7f79dea3c44 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -661,7 +661,7 @@ static struct syscall_fmt { { .name = "fchownat", .errmsg = true, .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, { .name = "fcntl", .errmsg = true, - .arg_scnprintf = { [1] = SCA_STRARRAYS, /* cmd */ }, + .arg_scnprintf = { [1] = SCA_FCNTL_CMD, /* cmd */ }, .arg_parm = { [1] = &strarrays__fcntl_cmds_arrays, /* cmd */ }, }, { .name = "fdatasync", .errmsg = true, }, { .name = "flock", .errmsg = true, diff --git a/tools/perf/trace/beauty/Build b/tools/perf/trace/beauty/Build index be95ac6ce845..c9e215b806f1 100644 --- a/tools/perf/trace/beauty/Build +++ b/tools/perf/trace/beauty/Build @@ -1 +1,2 @@ +libperf-y += fcntl.o libperf-y += statx.o diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index a6348073a6e9..ce01079d8422 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -18,6 +18,9 @@ struct syscall_arg { size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STRARRAYS syscall_arg__scnprintf_strarrays +size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_FCNTL_CMD syscall_arg__scnprintf_fcntl_cmd + size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags diff --git a/tools/perf/trace/beauty/fcntl.c b/tools/perf/trace/beauty/fcntl.c new file mode 100644 index 000000000000..7e4582c9308e --- /dev/null +++ b/tools/perf/trace/beauty/fcntl.c @@ -0,0 +1,23 @@ +/* + * trace/beauty/fcntl.c + * + * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo + * + * Released under the GPL v2. (and only v2, not any later version) + */ + +#include "trace/beauty/beauty.h" +#include + +size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg) +{ + /* + * Some commands ignore the third fcntl argument, "arg", so mask it + */ + if (arg->val == F_GETFD || arg->val == F_GETFL || + arg->val == F_GETOWN || arg->val == F_GET_SEALS || + arg->val == F_GETLEASE || arg->val == F_GETSIG) + arg->mask |= (1 << 2); + + return syscall_arg__scnprintf_strarrays(bf, size, arg); +} -- cgit v1.2.3 From f9f83b3344f9ed6e1d33a87810f38eca5ed6a14f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 10:13:56 -0300 Subject: perf trace beauty: Allow accessing syscall args values in a syscall arg formatter For instance, fcntl's upcoming 'arg' formatter needs to look at the 'cmd' value to decide how to format its value, sometimes it is a file flags, sometimes an fd, a pointer to a structure, etc. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-2tw2jfaqm48dtw8a4addghze@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 23 ++++++++++++++++------- tools/perf/trace/beauty/beauty.h | 13 +++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index b7f79dea3c44..40bc0a326096 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1369,19 +1369,32 @@ out: * variable to read it. Most notably this avoids extended load instructions * on unaligned addresses */ +static unsigned long __syscall_arg__val(unsigned char *args, u8 idx) +{ + unsigned long val; + unsigned char *p = args + sizeof(unsigned long) * idx; + + memcpy(&val, p, sizeof(val)); + return val; +} + +unsigned long syscall_arg__val(struct syscall_arg *arg, u8 idx) +{ + return __syscall_arg__val(arg->args, idx); +} static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, unsigned char *args, struct trace *trace, struct thread *thread) { size_t printed = 0; - unsigned char *p; unsigned long val; if (sc->args != NULL) { struct format_field *field; u8 bit = 1; struct syscall_arg arg = { + .args = args, .idx = 0, .mask = 0, .trace = trace, @@ -1393,9 +1406,7 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, if (arg.mask & bit) continue; - /* special care for unaligned accesses */ - p = args + sizeof(unsigned long) * arg.idx; - memcpy(&val, p, sizeof(val)); + val = syscall_arg__val(&arg, arg.idx); /* * Suppress this argument if its value is zero and @@ -1431,9 +1442,7 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, int i = 0; while (i < 6) { - /* special care for unaligned accesses */ - p = args + sizeof(unsigned long) * i; - memcpy(&val, p, sizeof(val)); + val = __syscall_arg__val(args, i); printed += scnprintf(bf + printed, size - printed, "%sarg%d: %ld", printed ? ", " : "", i, val); diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index ce01079d8422..6fbac0c8120d 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -6,8 +6,19 @@ struct trace; struct thread; +/** + * @val: value of syscall argument being formatted + * @args: All the args, use syscall_args__val(arg, nth) to access one + * @thread: tid state (maps, pid, tid, etc) + * @trace: 'perf trace' internals: all threads, etc + * @parm: private area, may be an strarray, for instance + * @idx: syscall arg idx (is this the first?) + * @mask: a syscall arg may mask another arg, see syscall_arg__scnprintf_futex_op + */ + struct syscall_arg { unsigned long val; + unsigned char *args; struct thread *thread; struct trace *trace; void *parm; @@ -15,6 +26,8 @@ struct syscall_arg { u8 mask; }; +unsigned long syscall_arg__val(struct syscall_arg *arg, u8 idx); + size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STRARRAYS syscall_arg__scnprintf_strarrays -- cgit v1.2.3 From 2c2b1623d46ce1f9c0ef5d21ff64a2c3f960e489 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 10:19:18 -0300 Subject: perf trace beauty: Export the "int" and "hex" syscall arg formatters The most basic ones, for pointers, unaugmented fds, etc, to be used in the initial fcntl 'arg' beautifier. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-g0lugj4vv6p4jtge32hid6q6@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 10 ++-------- tools/perf/trace/beauty/beauty.h | 6 ++++++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 40bc0a326096..9e171401b664 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -392,22 +392,16 @@ static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, #define SCA_CLOSE_FD syscall_arg__scnprintf_close_fd -static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, - struct syscall_arg *arg) +size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg) { return scnprintf(bf, size, "%#lx", arg->val); } -#define SCA_HEX syscall_arg__scnprintf_hex - -static size_t syscall_arg__scnprintf_int(char *bf, size_t size, - struct syscall_arg *arg) +size_t syscall_arg__scnprintf_int(char *bf, size_t size, struct syscall_arg *arg) { return scnprintf(bf, size, "%d", arg->val); } -#define SCA_INT syscall_arg__scnprintf_int - static const char *bpf_cmd[] = { "MAP_CREATE", "MAP_LOOKUP_ELEM", "MAP_UPDATE_ELEM", "MAP_DELETE_ELEM", "MAP_GET_NEXT_KEY", "PROG_LOAD", diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index 6fbac0c8120d..d085aacecd49 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -31,6 +31,12 @@ unsigned long syscall_arg__val(struct syscall_arg *arg, u8 idx); size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STRARRAYS syscall_arg__scnprintf_strarrays +size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_HEX syscall_arg__scnprintf_hex + +size_t syscall_arg__scnprintf_int(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_INT syscall_arg__scnprintf_int + size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg); #define SCA_FCNTL_CMD syscall_arg__scnprintf_fcntl_cmd -- cgit v1.2.3 From 5dde91edbf6776daba0981c5bc47f1240427e05c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 10:34:16 -0300 Subject: perf trace beauty: Introduce syscall arg beautifier for long integers Will be used in the fcntl arg beautifier, that nowadays formats as '%ld' because there is no explicit arg beautifier attached, but as we will have to first decide what beautifier to use (i.e. it may be a pointer, etc) then we need to have this exported as a separate beautifier to be called from there. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-d7bfs3m8m70j3zckeam0kk5d@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 5 +++++ tools/perf/trace/beauty/beauty.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 9e171401b664..a323736043e1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -402,6 +402,11 @@ size_t syscall_arg__scnprintf_int(char *bf, size_t size, struct syscall_arg *arg return scnprintf(bf, size, "%d", arg->val); } +size_t syscall_arg__scnprintf_long(char *bf, size_t size, struct syscall_arg *arg) +{ + return scnprintf(bf, size, "%ld", arg->val); +} + static const char *bpf_cmd[] = { "MAP_CREATE", "MAP_LOOKUP_ELEM", "MAP_UPDATE_ELEM", "MAP_DELETE_ELEM", "MAP_GET_NEXT_KEY", "PROG_LOAD", diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index d085aacecd49..61aec19e55ec 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -37,6 +37,9 @@ size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg size_t syscall_arg__scnprintf_int(char *bf, size_t size, struct syscall_arg *arg); #define SCA_INT syscall_arg__scnprintf_int +size_t syscall_arg__scnprintf_long(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_LONG syscall_arg__scnprintf_long + size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg); #define SCA_FCNTL_CMD syscall_arg__scnprintf_fcntl_cmd -- cgit v1.2.3 From 84d1d8a12df33a3e707866b9a1f9872058c3d1fb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 18 Jul 2017 17:09:21 -0300 Subject: tools include uapi asm-generic: Grab a copy of fcntl.h We'll need defines for beautifying fcntl arguments that are not available in older distros, these: trace/beauty/fcntl.c: In function 'syscall_arg__scnprintf_fcntl_arg': trace/beauty/fcntl.c:93: error: 'F_OFD_SETLK' undeclared (first use in this function) trace/beauty/fcntl.c:93: error: (Each undeclared identifier is reported only once trace/beauty/fcntl.c:93: error: for each function it appears in.) trace/beauty/fcntl.c:93: error: 'F_OFD_SETLKW' undeclared (first use in this function) trace/beauty/fcntl.c:93: error: 'F_OFD_GETLK' undeclared (first use in this function) trace/beauty/fcntl.c:94: error: 'F_GETOWN_EX' undeclared (first use in this function) trace/beauty/fcntl.c:94: error: 'F_SETOWN_EX' undeclared (first use in this function) Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-gvlw67a47e9z65jdunj4je5s@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/asm-generic/fcntl.h | 220 +++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 tools/include/uapi/asm-generic/fcntl.h diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h new file mode 100644 index 000000000000..ac190958c981 --- /dev/null +++ b/tools/include/uapi/asm-generic/fcntl.h @@ -0,0 +1,220 @@ +#ifndef _ASM_GENERIC_FCNTL_H +#define _ASM_GENERIC_FCNTL_H + +#include + +/* + * FMODE_EXEC is 0x20 + * FMODE_NONOTIFY is 0x4000000 + * These cannot be used by userspace O_* until internal and external open + * flags are split. + * -Eric Paris + */ + +/* + * When introducing new O_* bits, please check its uniqueness in fcntl_init(). + */ + +#define O_ACCMODE 00000003 +#define O_RDONLY 00000000 +#define O_WRONLY 00000001 +#define O_RDWR 00000002 +#ifndef O_CREAT +#define O_CREAT 00000100 /* not fcntl */ +#endif +#ifndef O_EXCL +#define O_EXCL 00000200 /* not fcntl */ +#endif +#ifndef O_NOCTTY +#define O_NOCTTY 00000400 /* not fcntl */ +#endif +#ifndef O_TRUNC +#define O_TRUNC 00001000 /* not fcntl */ +#endif +#ifndef O_APPEND +#define O_APPEND 00002000 +#endif +#ifndef O_NONBLOCK +#define O_NONBLOCK 00004000 +#endif +#ifndef O_DSYNC +#define O_DSYNC 00010000 /* used to be O_SYNC, see below */ +#endif +#ifndef FASYNC +#define FASYNC 00020000 /* fcntl, for BSD compatibility */ +#endif +#ifndef O_DIRECT +#define O_DIRECT 00040000 /* direct disk access hint */ +#endif +#ifndef O_LARGEFILE +#define O_LARGEFILE 00100000 +#endif +#ifndef O_DIRECTORY +#define O_DIRECTORY 00200000 /* must be a directory */ +#endif +#ifndef O_NOFOLLOW +#define O_NOFOLLOW 00400000 /* don't follow links */ +#endif +#ifndef O_NOATIME +#define O_NOATIME 01000000 +#endif +#ifndef O_CLOEXEC +#define O_CLOEXEC 02000000 /* set close_on_exec */ +#endif + +/* + * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using + * the O_SYNC flag. We continue to use the existing numerical value + * for O_DSYNC semantics now, but using the correct symbolic name for it. + * This new value is used to request true Posix O_SYNC semantics. It is + * defined in this strange way to make sure applications compiled against + * new headers get at least O_DSYNC semantics on older kernels. + * + * This has the nice side-effect that we can simply test for O_DSYNC + * wherever we do not care if O_DSYNC or O_SYNC is used. + * + * Note: __O_SYNC must never be used directly. + */ +#ifndef O_SYNC +#define __O_SYNC 04000000 +#define O_SYNC (__O_SYNC|O_DSYNC) +#endif + +#ifndef O_PATH +#define O_PATH 010000000 +#endif + +#ifndef __O_TMPFILE +#define __O_TMPFILE 020000000 +#endif + +/* a horrid kludge trying to make sure that this will fail on old kernels */ +#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) +#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT) + +#ifndef O_NDELAY +#define O_NDELAY O_NONBLOCK +#endif + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get close_on_exec */ +#define F_SETFD 2 /* set/clear close_on_exec */ +#define F_GETFL 3 /* get file->f_flags */ +#define F_SETFL 4 /* set file->f_flags */ +#ifndef F_GETLK +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 +#endif +#ifndef F_SETOWN +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ +#endif +#ifndef F_SETSIG +#define F_SETSIG 10 /* for sockets. */ +#define F_GETSIG 11 /* for sockets. */ +#endif + +#ifndef CONFIG_64BIT +#ifndef F_GETLK64 +#define F_GETLK64 12 /* using 'struct flock64' */ +#define F_SETLK64 13 +#define F_SETLKW64 14 +#endif +#endif + +#ifndef F_SETOWN_EX +#define F_SETOWN_EX 15 +#define F_GETOWN_EX 16 +#endif + +#ifndef F_GETOWNER_UIDS +#define F_GETOWNER_UIDS 17 +#endif + +/* + * Open File Description Locks + * + * Usually record locks held by a process are released on *any* close and are + * not inherited across a fork(). + * + * These cmd values will set locks that conflict with process-associated + * record locks, but are "owned" by the open file description, not the + * process. This means that they are inherited across fork() like BSD (flock) + * locks, and they are only released automatically when the last reference to + * the the open file against which they were acquired is put. + */ +#define F_OFD_GETLK 36 +#define F_OFD_SETLK 37 +#define F_OFD_SETLKW 38 + +#define F_OWNER_TID 0 +#define F_OWNER_PID 1 +#define F_OWNER_PGRP 2 + +struct f_owner_ex { + int type; + __kernel_pid_t pid; +}; + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#ifndef F_RDLCK +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 +#endif + +/* for old implementation of bsd flock () */ +#ifndef F_EXLCK +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ +#endif + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +#define LOCK_MAND 32 /* This is a mandatory flock ... */ +#define LOCK_READ 64 /* which allows concurrent read operations */ +#define LOCK_WRITE 128 /* which allows concurrent write operations */ +#define LOCK_RW 192 /* which allows concurrent read & write ops */ + +#define F_LINUX_SPECIFIC_BASE 1024 + +#ifndef HAVE_ARCH_STRUCT_FLOCK +#ifndef __ARCH_FLOCK_PAD +#define __ARCH_FLOCK_PAD +#endif + +struct flock { + short l_type; + short l_whence; + __kernel_off_t l_start; + __kernel_off_t l_len; + __kernel_pid_t l_pid; + __ARCH_FLOCK_PAD +}; +#endif + +#ifndef HAVE_ARCH_STRUCT_FLOCK64 +#ifndef __ARCH_FLOCK64_PAD +#define __ARCH_FLOCK64_PAD +#endif + +struct flock64 { + short l_type; + short l_whence; + __kernel_loff_t l_start; + __kernel_loff_t l_len; + __kernel_pid_t l_pid; + __ARCH_FLOCK64_PAD +}; +#endif + +#endif /* _ASM_GENERIC_FCNTL_H */ -- cgit v1.2.3 From 9c47f66748381ecbaa3a5eb301b81fd2fd0a282d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 11:05:40 -0300 Subject: perf trace beauty fcntl: Basic 'arg' beautifier Sometimes it should be printed as an hex number, like with F_SETLK, F_SETLKW and F_GETLK, that treat 'arg' as a struct flock pointer, in other cases it is just an integer. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-2gykg6enk7vos6q0m97hkgsg@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 3 ++- tools/perf/trace/beauty/beauty.h | 3 +++ tools/perf/trace/beauty/fcntl.c | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index a323736043e1..2a894ea7f540 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -660,7 +660,8 @@ static struct syscall_fmt { { .name = "fchownat", .errmsg = true, .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, { .name = "fcntl", .errmsg = true, - .arg_scnprintf = { [1] = SCA_FCNTL_CMD, /* cmd */ }, + .arg_scnprintf = { [1] = SCA_FCNTL_CMD, /* cmd */ + [2] = SCA_FCNTL_ARG, /* arg */ }, .arg_parm = { [1] = &strarrays__fcntl_cmds_arrays, /* cmd */ }, }, { .name = "fdatasync", .errmsg = true, }, { .name = "flock", .errmsg = true, diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index 61aec19e55ec..d76f903bf2ed 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -43,6 +43,9 @@ size_t syscall_arg__scnprintf_long(char *bf, size_t size, struct syscall_arg *ar size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg); #define SCA_FCNTL_CMD syscall_arg__scnprintf_fcntl_cmd +size_t syscall_arg__scnprintf_fcntl_arg(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_FCNTL_ARG syscall_arg__scnprintf_fcntl_arg + size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags diff --git a/tools/perf/trace/beauty/fcntl.c b/tools/perf/trace/beauty/fcntl.c index 7e4582c9308e..8a5f58d9eb7c 100644 --- a/tools/perf/trace/beauty/fcntl.c +++ b/tools/perf/trace/beauty/fcntl.c @@ -21,3 +21,21 @@ size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_ar return syscall_arg__scnprintf_strarrays(bf, size, arg); } + +size_t syscall_arg__scnprintf_fcntl_arg(char *bf, size_t size, struct syscall_arg *arg) +{ + int cmd = syscall_arg__val(arg, 1); + + /* + * We still don't grab the contents of pointers on entry or exit, + * so just print them as hex numbers + */ + if (cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK || + cmd == F_OFD_SETLK || cmd == F_OFD_SETLKW || cmd == F_OFD_GETLK || + cmd == F_GETOWN_EX || cmd == F_SETOWN_EX || + cmd == F_GET_RW_HINT || cmd == F_SET_RW_HINT || + cmd == F_GET_FILE_RW_HINT || cmd == F_SET_FILE_RW_HINT) + return syscall_arg__scnprintf_hex(bf, size, arg); + + return syscall_arg__scnprintf_long(bf, size, arg); +} -- cgit v1.2.3 From 64e4561d17c54b64368735bdf89d6873f550d918 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 13 Jul 2017 17:34:46 -0300 Subject: perf trace: Beautify new write hint fcntl commands Those introduced by the commit c75b1d9421f8 ("fs: add fcntl() interface for setting/getting write life time hints"), tested using the proggie in that commit comment: # perf trace -e fcntl ./write_hint write_hint.c fcntl: F_GET_RW_HINT: Invalid argument 0.000 ( 0.006 ms): write_hint/7576 fcntl(fd: 3, cmd: GET_RW_HINT, arg: 0x7ffc6c918da0) = -1 EINVAL Invalid argument 0.014 ( 0.004 ms): write_hint/7576 fcntl(fd: 4, cmd: GETFL) = 33794 # perf trace -e fcntl ./write_hint write_hint.c 1 fcntl: F_SET_RW_HINT: Invalid argument 0.000 ( 0.007 ms): write_hint/7578 fcntl(fd: 3, cmd: SET_RW_HINT, arg: 0x7fff03866d70) = -1 EINVAL Invalid argument 0.019 ( 0.002 ms): write_hint/7578 fcntl(fd: 4, cmd: GETFL) = 33794 # Cc: Adrian Hunter Cc: David Ahern Cc: Jens Axboe Cc: Jiri Olsa Cc: Martin K. Petersen Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-iacglkc99cchou87k62736dn@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 2a894ea7f540..1f070bc43742 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -449,6 +449,7 @@ static DEFINE_STRARRAY(fcntl_cmds); static const char *fcntl_linux_specific_cmds[] = { "SETLEASE", "GETLEASE", "NOTIFY", [5] = "CANCELLK", "DUPFD_CLOEXEC", "SETPIPE_SZ", "GETPIPE_SZ", "ADD_SEALS", "GET_SEALS", + "GET_RW_HINT", "SET_RW_HINT", "GET_FILE_RW_HINT", "SET_FILE_RW_HINT", }; static DEFINE_STRARRAY_OFFSET(fcntl_linux_specific_cmds, F_LINUX_SPECIFIC_BASE); -- cgit v1.2.3 From b239ad28a8c9571c45e62e486ce75ebad17de6c1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 11:18:41 -0300 Subject: perf beauty open: Detach the syscall_arg agnostic bits from the flags formatter We may want to use this in other contexts, like when formatting the return of fcntl(fd, F_GETFL). Make it have the following signature, so that we can set the formatter for the return argument while processing the arguments of a syscall, as fcntl, for instance, may return fds, flags, etc, so need different return value formatters: size_t formatter(unsigned long value, char *bf, size_t size); This gets so detached from 'perf trace' internals that we may well get all these and move to a tools/lib/syscall_beauty/ library at some point and use it in other tools/ living utilities. Cc: Adrian Hunter Cc: Alexei Starovoitov Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-9aw8t22ztvnkuv26l6sw1c18@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/beauty.h | 2 ++ tools/perf/trace/beauty/open_flags.c | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index d76f903bf2ed..c05bb2ecf502 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -52,4 +52,6 @@ size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_ size_t syscall_arg__scnprintf_statx_mask(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STATX_MASK syscall_arg__scnprintf_statx_mask +size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size); + #endif /* _PERF_TRACE_BEAUTY_H */ diff --git a/tools/perf/trace/beauty/open_flags.c b/tools/perf/trace/beauty/open_flags.c index f55a4597fc38..b3c7f1155d80 100644 --- a/tools/perf/trace/beauty/open_flags.c +++ b/tools/perf/trace/beauty/open_flags.c @@ -14,13 +14,9 @@ #define O_NOATIME 01000000 #endif -static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, - struct syscall_arg *arg) +size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size) { - int printed = 0, flags = arg->val; - - if (!(flags & O_CREAT)) - arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */ + int printed = 0; if (flags == 0) return scnprintf(bf, size, "RDONLY"); @@ -68,4 +64,15 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, return printed; } +static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg) +{ + int flags = arg->val; + + if (!(flags & O_CREAT)) + arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */ + + return open__scnprintf_flags(flags, bf, size); +} + + #define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags -- cgit v1.2.3 From 84486caad942bfea338716e22010a754a0ca9199 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 11:35:03 -0300 Subject: perf trace: Allow syscall_arg beautifiers to set a different return formatter Things like fcntl will use this to set the right formatter based on its 'cmd' argument. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-4ea3wplb8b4j7aymj0d5uo0h@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 27 ++++++++++++++++++++++++++- tools/perf/trace/beauty/beauty.h | 3 +++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 1f070bc43742..d48981c36b70 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -908,6 +908,8 @@ static size_t fprintf_duration(unsigned long t, bool calculated, FILE *fp) * filename.ptr: The filename char pointer that will be vfs_getname'd * filename.entry_str_pos: Where to insert the string translated from * filename.ptr by the vfs_getname tracepoint/kprobe. + * ret_scnprintf: syscall args may set this to a different syscall return + * formatter, for instance, fcntl may return fds, file flags, etc. */ struct thread_trace { u64 entry_time; @@ -916,6 +918,7 @@ struct thread_trace { unsigned long pfmaj, pfmin; char *entry_str; double runtime_ms; + size_t (*ret_scnprintf)(unsigned long value, char *bf, size_t size); struct { unsigned long ptr; short int entry_str_pos; @@ -966,6 +969,15 @@ fail: return NULL; } + +void syscall_arg__set_ret_scnprintf(struct syscall_arg *arg, + size_t (*ret_scnprintf)(unsigned long val, char *bf, size_t size)) +{ + struct thread_trace *ttrace = thread__priv(arg->thread); + + ttrace->ret_scnprintf = ret_scnprintf; +} + #define TRACE_PFMAJ (1 << 0) #define TRACE_PFMIN (1 << 1) @@ -1390,6 +1402,14 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, { size_t printed = 0; unsigned long val; + struct thread_trace *ttrace = thread__priv(thread); + + /* + * Things like fcntl will set this in its 'cmd' formatter to pick the + * right formatter for the return value (an fd? file flags?), which is + * not needed for syscalls that always return a given type, say an fd. + */ + ttrace->ret_scnprintf = NULL; if (sc->args != NULL) { struct format_field *field; @@ -1704,7 +1724,12 @@ signed_print: fprintf(trace->output, ") = -1 %s %s", e, emsg); } else if (ret == 0 && sc->fmt->timeout) fprintf(trace->output, ") = 0 Timeout"); - else if (sc->fmt->hexret) + else if (ttrace->ret_scnprintf) { + char bf[1024]; + ttrace->ret_scnprintf(ret, bf, sizeof(bf)); + ttrace->ret_scnprintf = NULL; + fprintf(trace->output, ") = %s", bf); + } else if (sc->fmt->hexret) fprintf(trace->output, ") = %#lx", ret); else if (sc->fmt->errpid) { struct thread *child = machine__find_thread(trace->host, ret, ret); diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index c05bb2ecf502..a9613d2e6cfe 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -54,4 +54,7 @@ size_t syscall_arg__scnprintf_statx_mask(char *bf, size_t size, struct syscall_a size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size); +void syscall_arg__set_ret_scnprintf(struct syscall_arg *arg, + size_t (*ret_scnprintf)(unsigned long val, char *bf, size_t size)); + #endif /* _PERF_TRACE_BEAUTY_H */ -- cgit v1.2.3 From 6b3d5c97dbbc2a8e1f8d7e7d87b8c6637293e803 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 11:57:28 -0300 Subject: perf trace beauty open flags: Support O_TMPFILE and O_NOFOLLOW The open syscall flags beautifier wasn't considering those flags, fix it. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-ukzoldh4arrl8x2uwjafd22h@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/open_flags.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/perf/trace/beauty/open_flags.c b/tools/perf/trace/beauty/open_flags.c index b3c7f1155d80..5fb57bed7ea2 100644 --- a/tools/perf/trace/beauty/open_flags.c +++ b/tools/perf/trace/beauty/open_flags.c @@ -14,6 +14,10 @@ #define O_NOATIME 01000000 #endif +#ifndef O_TMPFILE +#define O_TMPFILE 020000000 +#endif + size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size) { int printed = 0; @@ -34,6 +38,8 @@ size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size) P_FLAG(DIRECTORY); P_FLAG(EXCL); P_FLAG(LARGEFILE); + P_FLAG(NOFOLLOW); + P_FLAG(TMPFILE); P_FLAG(NOATIME); P_FLAG(NOCTTY); #ifdef O_NONBLOCK -- cgit v1.2.3 From b84148a910598f3e733e54f3cb736d11911291df Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 12:09:31 -0300 Subject: perf trace beauty open flags: Do not depend on the system's O_LARGEFILE define In x86_64 /usr/include/bits/fcntl.h sets it to zero, so just undef it and use the standard 00100000 value when decoding the open flags arg. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-k28megguz5snwop9obvn9mcr@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/open_flags.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/trace/beauty/open_flags.c b/tools/perf/trace/beauty/open_flags.c index 5fb57bed7ea2..e520112fdb6e 100644 --- a/tools/perf/trace/beauty/open_flags.c +++ b/tools/perf/trace/beauty/open_flags.c @@ -18,6 +18,9 @@ #define O_TMPFILE 020000000 #endif +#undef O_LARGEFILE +#define O_LARGEFILE 00100000 + size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size) { int printed = 0; -- cgit v1.2.3 From 89e8524abe1c584942e6b05744946877e87dd478 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 12:14:20 -0300 Subject: perf trace beauty fcntl: Beautify F_GETFL return value The return for fcntl(fd, F_GETFL) is the fd file flags, so reuse the one for the open syscall flags parameter: 997.992 (0.002 ms): Chrome_IOThrea/19863 fcntl(fd: 144, cmd: GETFL) = RDWR|LARGEFILE Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-5nn3n4p4yfs6u0leoq880apc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/fcntl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/perf/trace/beauty/fcntl.c b/tools/perf/trace/beauty/fcntl.c index 8a5f58d9eb7c..8dcbc30427c9 100644 --- a/tools/perf/trace/beauty/fcntl.c +++ b/tools/perf/trace/beauty/fcntl.c @@ -11,13 +11,19 @@ size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg) { + if (arg->val == F_GETFL) { + syscall_arg__set_ret_scnprintf(arg, open__scnprintf_flags); + goto mask_arg; + } /* * Some commands ignore the third fcntl argument, "arg", so mask it */ - if (arg->val == F_GETFD || arg->val == F_GETFL || + if (arg->val == F_GETFD || arg->val == F_GETOWN || arg->val == F_GET_SEALS || - arg->val == F_GETLEASE || arg->val == F_GETSIG) + arg->val == F_GETLEASE || arg->val == F_GETSIG) { +mask_arg: arg->mask |= (1 << 2); + } return syscall_arg__scnprintf_strarrays(bf, size, arg); } -- cgit v1.2.3 From e07f93c0927050184110e189a69a0b9d73c0c9b1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 14 Jul 2017 14:23:17 -0300 Subject: perf trace beauty open flags: Move RDRW to the start of the output We were getting: 62597.859 ( 0.005 ms): TaskSchedulerF/18107 fcntl(fd: 194, cmd: GETFL) = LARGEFILE|RDWR Instead of the more familiar (from looking at strace output): 62597.859 ( 0.005 ms): TaskSchedulerF/18107 fcntl(fd: 194, cmd: GETFL) = RDWR|LARGEFILE Fix it. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-d4d9nd88t4bu9y9odbrcb5z6@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/open_flags.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/trace/beauty/open_flags.c b/tools/perf/trace/beauty/open_flags.c index e520112fdb6e..3c20683d8cfb 100644 --- a/tools/perf/trace/beauty/open_flags.c +++ b/tools/perf/trace/beauty/open_flags.c @@ -33,6 +33,7 @@ size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size) flags &= ~O_##n; \ } + P_FLAG(RDWR); P_FLAG(APPEND); P_FLAG(ASYNC); P_FLAG(CLOEXEC); @@ -53,7 +54,6 @@ size_t open__scnprintf_flag