linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: Clark Williams <williams@redhat.com>,
	linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
	Arnaldo Carvalho de Melo <acme@redhat.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	David Ahern <dsahern@gmail.com>, Jiri Olsa <jolsa@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	Wang Nan <wangnan0@huawei.com>
Subject: [PATCH 39/44] perf trace: Handle "bpf-output" events associated with "__augmented_syscalls__" BPF map
Date: Thu,  9 Aug 2018 11:58:17 -0300	[thread overview]
Message-ID: <20180809145822.21391-40-acme@kernel.org> (raw)
In-Reply-To: <20180809145822.21391-1-acme@kernel.org>

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Add an example BPF script that writes syscalls:sys_enter_openat raw
tracepoint payloads augmented with the first 64 bytes of the "filename"
syscall pointer arg.

Then catch it and print it just like with things written to the
"__bpf_stdout__" map associated with a PERF_COUNT_SW_BPF_OUTPUT software
event, by just letting the default tracepoint handler in 'perf trace',
trace__event_handler(), to use bpf_output__fprintf(trace, sample), just
like it does with all other PERF_COUNT_SW_BPF_OUTPUT events, i.e. just
do a dump on the payload, so that we can check if what is being printed
has at least the first 64 bytes of the "filename" arg:

The augmented_syscalls.c eBPF script:

  # cat tools/perf/examples/bpf/augmented_syscalls.c
  // SPDX-License-Identifier: GPL-2.0

  #include <stdio.h>

  struct bpf_map SEC("maps") __augmented_syscalls__ = {
       .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
       .key_size = sizeof(int),
       .value_size = sizeof(u32),
       .max_entries = __NR_CPUS__,
  };

  struct syscall_enter_openat_args {
	unsigned long long common_tp_fields;
	long		   syscall_nr;
	long		   dfd;
	char		   *filename_ptr;
	long		   flags;
	long		   mode;
  };

  struct augmented_enter_openat_args {
	struct syscall_enter_openat_args args;
	char				 filename[64];
  };

  int syscall_enter(openat)(struct syscall_enter_openat_args *args)
  {
	struct augmented_enter_openat_args augmented_args;

	probe_read(&augmented_args.args, sizeof(augmented_args.args), args);
	probe_read_str(&augmented_args.filename, sizeof(augmented_args.filename), args->filename_ptr);
	perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU,
			  &augmented_args, sizeof(augmented_args));
	return 1;
  }

  license(GPL);
  #

So it will just prepare a raw_syscalls:sys_enter payload for the
"openat" syscall.

This will eventually be done for all syscalls with pointer args,
globally or just when the user asks, using some spec, which args of
which syscalls it wants "expanded" this way, we'll probably start with
just all the syscalls that have char * pointers with familiar names, the
ones we already handle with the probe:vfs_getname kprobe if it is in
place hooking the kernel getname_flags() function used to copy from user
the paths.

Running it we get:

  # perf trace -e perf/tools/perf/examples/bpf/augmented_syscalls.c,openat cat /etc/passwd > /dev/null
     0.000 (         ): __augmented_syscalls__:X?.C......................`\..................../etc/ld.so.cache..#......,....ao.k...............k......1.".........
     0.006 (         ): syscalls:sys_enter_openat:dfd: CWD, filename: 0x5c600da8, flags: CLOEXEC
     0.008 ( 0.005 ms): cat/31292 openat(dfd: CWD, filename: 0x5c600da8, flags: CLOEXEC                 ) = 3
     0.036 (         ): __augmented_syscalls__:X?.C.......................\..................../lib64/libc.so.6......... .\....#........?.......=.C..../.".........
     0.037 (         ): syscalls:sys_enter_openat:dfd: CWD, filename: 0x5c808ce0, flags: CLOEXEC
     0.039 ( 0.007 ms): cat/31292 openat(dfd: CWD, filename: 0x5c808ce0, flags: CLOEXEC                 ) = 3
     0.323 (         ): __augmented_syscalls__:X?.C.....................P....................../etc/passwd......>.C....@................>.C.....,....ao.>.C........
     0.325 (         ): syscalls:sys_enter_openat:dfd: CWD, filename: 0xe8be50d6
     0.327 ( 0.004 ms): cat/31292 openat(dfd: CWD, filename: 0xe8be50d6                                 ) = 3
  #

We need to go on optimizing this to avoid seding trash or zeroes in the
pointer content payload, using the return from bpf_probe_read_str(), but
to keep things simple at this stage and make incremental progress, lets
leave it at that for now.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: https://lkml.kernel.org/n/tip-g360n1zbj6bkbk6q0qo11c28@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-trace.c                   |  7 ++++
 tools/perf/examples/bpf/augmented_syscalls.c | 55 ++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)
 create mode 100644 tools/perf/examples/bpf/augmented_syscalls.c

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 7232a7302580..9b4e24217c46 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -3240,6 +3240,13 @@ int cmd_trace(int argc, const char **argv)
 				       "cgroup monitoring only available in system-wide mode");
 	}
 
+	err = bpf__setup_output_event(trace.evlist, "__augmented_syscalls__");
+	if (err) {
+		bpf__strerror_setup_output_event(trace.evlist, err, bf, sizeof(bf));
+		pr_err("ERROR: Setup trace syscalls enter failed: %s\n", bf);
+		goto out;
+	}
+
 	err = bpf__setup_stdout(trace.evlist);
 	if (err) {
 		bpf__strerror_setup_stdout(trace.evlist, err, bf, sizeof(bf));
diff --git a/tools/perf/examples/bpf/augmented_syscalls.c b/tools/perf/examples/bpf/augmented_syscalls.c
new file mode 100644
index 000000000000..69a31386d8cd
--- /dev/null
+++ b/tools/perf/examples/bpf/augmented_syscalls.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Augment the openat syscall with the contents of the filename pointer argument.
+ *
+ * Test it with:
+ *
+ * perf trace -e tools/perf/examples/bpf/augmented_syscalls.c cat /etc/passwd > /dev/null
+ *
+ * It'll catch some openat syscalls related to the dynamic linked and
+ * the last one should be the one for '/etc/passwd'.
+ *
+ * This matches what is marshalled into the raw_syscall:sys_enter payload
+ * expected by the 'perf trace' beautifiers, and can be used by them unmodified,
+ * which will be done as that feature is implemented in the next csets, for now
+ * it will appear in a dump done by the default tracepoint handler in 'perf trace',
+ * that uses bpf_output__fprintf() to just dump those contents, as done with
+ * the bpf-output event associated with the __bpf_output__ map declared in
+ * tools/perf/include/bpf/stdio.h.
+ */
+
+#include <stdio.h>
+
+struct bpf_map SEC("maps") __augmented_syscalls__ = {
+       .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+       .key_size = sizeof(int),
+       .value_size = sizeof(u32),
+       .max_entries = __NR_CPUS__,
+};
+
+struct syscall_enter_openat_args {
+	unsigned long long common_tp_fields;
+	long		   syscall_nr;
+	long		   dfd;
+	char		   *filename_ptr;
+	long		   flags;
+	long		   mode;
+};
+
+struct augmented_enter_openat_args {
+	struct syscall_enter_openat_args args;
+	char				 filename[64];
+};
+
+int syscall_enter(openat)(struct syscall_enter_openat_args *args)
+{
+	struct augmented_enter_openat_args augmented_args;
+
+	probe_read(&augmented_args.args, sizeof(augmented_args.args), args);
+	probe_read_str(&augmented_args.filename, sizeof(augmented_args.filename), args->filename_ptr);
+	perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU,
+			  &augmented_args, sizeof(augmented_args));
+	return 1;
+}
+
+license(GPL);
-- 
2.14.4

  parent reply	other threads:[~2018-08-09 14:58 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-09 14:57 [GIT PULL 00/44] perf/core improvements and fixes Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 01/44] perf trace: Associate vfs_getname()'ed pathname with fd returned from 'openat' Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 02/44] perf trace: Use beautifiers on syscalls:sys_enter_ handlers Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 03/44] perf trace: Rename some syscall_tp methods to raw_syscall Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 04/44] perf trace: Allow setting up a syscall_tp struct without a format_field Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 05/44] perf trace: Setup struct syscall_tp for syscalls:sys_{enter,exit}_NAME events Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 06/44] perf trace: Use perf_evsel__sc_tp_{uint,ptr} for "id"/"args" handling syscalls:* events Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 07/44] perf auxtrace: Support for perf report -D for s390 Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 08/44] perf report: Add raw report support for s390 auxiliary trace Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 09/44] perf report: Add GUI " Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 10/44] perf vendor events arm64: Enable JSON events for eMAG Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 11/44] perf tools: Drop unneeded bitmap_zero() calls Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 12/44] perf bpf: Add 'syscall_enter' probe helper for syscall enter tracepoints Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 13/44] perf annotate: Make symbol__annotate_fprintf2() local Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 14/44] perf annotate: Make annotation_line__max_percent static Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 15/44] perf annotate: Get rid of annotation__scnprintf_samples_period() Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 16/44] perf annotate: Rename struct annotation_line::samples* to data* Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 17/44] perf annotate: Rename local sample variables to data Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 18/44] perf annotate: Rename hist to sym_hist in annotation__calc_percent Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 19/44] perf annotate: Loop group events directly in annotation__calc_percent() Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 20/44] perf annotate: Switch struct annotation_data::percent to array Arnaldo Carvalho de Melo
2018-08-09 14:57 ` [PATCH 21/44] perf annotate: Add PERCENT_HITS_GLOBAL percent value Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 22/44] perf annotate: Add PERCENT_PERIOD_LOCAL " Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 23/44] perf annotate: Add PERCENT_PERIOD_GLOBAL " Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 24/44] perf annotate: Add percent_type to struct annotation_options Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 25/44] perf annotate: Pass struct annotation_options to symbol__calc_lines() Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 26/44] perf annotate: Pass 'struct annotation_options' to map_symbol__annotation_dump() Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 27/44] perf annotate: Pass browser percent_type in annotate_browser__calc_percent() Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 28/44] perf annotate: Add support to toggle percent type Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 29/44] perf annotate: Make local period the default " Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 30/44] perf annotate: Display percent type in stdio output Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 31/44] perf annotate: Add --percent-type option Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 32/44] perf report: " Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 33/44] perf bpf: Add struct bpf_map struct Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 34/44] perf bpf: Add bpf/stdio.h wrapper to bpf_perf_event_output function Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 35/44] perf bpf: Make bpf__for_each_stdout_map() generic Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 36/44] perf bpf: Generalize bpf__setup_stdout() Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 37/44] perf bpf: Add bpf__setup_output_event() strerror() counterpart Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 38/44] perf bpf: Add wrappers to BPF_FUNC_probe_read(_str) functions Arnaldo Carvalho de Melo
2018-08-09 14:58 ` Arnaldo Carvalho de Melo [this message]
2018-08-09 14:58 ` [PATCH 40/44] perf bpf: Make bpf__setup_output_event() return the bpf-output event Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 41/44] perf trace: Setup the augmented syscalls bpf-output event fields Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 42/44] perf trace: Wire up the augmented syscalls with the syscalls:sys_enter_FOO beautifier Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 43/44] perf map: Synthesize maps only for thread group leader Arnaldo Carvalho de Melo
2018-08-09 14:58 ` [PATCH 44/44] perf map: Optimize maps__fixup_overlappings() Arnaldo Carvalho de Melo
2018-08-09 15:27 ` [GIT PULL 00/44] perf/core improvements and fixes Kim Phillips
2018-08-09 15:35   ` Arnaldo Carvalho de Melo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180809145822.21391-40-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=dsahern@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=wangnan0@huawei.com \
    --cc=williams@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).