mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: tip-bot for Alexei Starovoitov <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: acme@redhat.com, davem@davemloft.net, rostedt@goodmis.org,
	peterz@infradead.org, hpa@zytor.com, tglx@linutronix.de,
	ast@plumgrid.com, a.p.zijlstra@chello.nl, daniel@iogearbox.net,
	jolsa@redhat.com, akpm@linux-foundation.org,
	linux-kernel@vger.kernel.org, acme@infradead.org,
	namhyung@kernel.org, torvalds@linux-foundation.org,
	mingo@kernel.org, masami.hiramatsu.pt@hitachi.com
Subject: [tip:perf/core] samples/bpf: Add kmem_alloc()/free() tracker tool
Date: Thu, 2 Apr 2015 05:36:55 -0700	[thread overview]
Message-ID: <tip-9811e35359d4b18baf5bb603b225e957255b9c46@git.kernel.org> (raw)
In-Reply-To: <1427312966-8434-10-git-send-email-ast@plumgrid.com>

Commit-ID:  9811e35359d4b18baf5bb603b225e957255b9c46
Gitweb:     http://git.kernel.org/tip/9811e35359d4b18baf5bb603b225e957255b9c46
Author:     Alexei Starovoitov <ast@plumgrid.com>
AuthorDate: Wed, 25 Mar 2015 12:49:26 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 2 Apr 2015 13:25:51 +0200

samples/bpf: Add kmem_alloc()/free() tracker tool

One BPF program attaches to kmem_cache_alloc_node() and
remembers all allocated objects in the map.
Another program attaches to kmem_cache_free() and deletes
corresponding object from the map.

User space walks the map every second and prints any objects
which are older than 1 second.

Usage:

	$ sudo tracex4

Then start few long living processes. The 'tracex4' will print
something like this:

	obj 0xffff880465928000 is 13sec old was allocated at ip ffffffff8105dc32
	obj 0xffff88043181c280 is 13sec old was allocated at ip ffffffff8105dc32
	obj 0xffff880465848000 is  8sec old was allocated at ip ffffffff8105dc32
	obj 0xffff8804338bc280 is 15sec old was allocated at ip ffffffff8105dc32

	$ addr2line -fispe vmlinux ffffffff8105dc32
	do_fork at fork.c:1665

As soon as processes exit the memory is reclaimed and 'tracex4'
prints nothing.

Similar experiment can be done with the __kmalloc()/kfree() pair.

Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: David S. Miller <davem@davemloft.net>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/1427312966-8434-10-git-send-email-ast@plumgrid.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 samples/bpf/Makefile       |  4 +++
 samples/bpf/tracex4_kern.c | 54 ++++++++++++++++++++++++++++++++++++
 samples/bpf/tracex4_user.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+)

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index dcd8505..fe98fb2 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -9,6 +9,7 @@ hostprogs-y += sockex2
 hostprogs-y += tracex1
 hostprogs-y += tracex2
 hostprogs-y += tracex3
+hostprogs-y += tracex4
 
 test_verifier-objs := test_verifier.o libbpf.o
 test_maps-objs := test_maps.o libbpf.o
@@ -18,6 +19,7 @@ sockex2-objs := bpf_load.o libbpf.o sockex2_user.o
 tracex1-objs := bpf_load.o libbpf.o tracex1_user.o
 tracex2-objs := bpf_load.o libbpf.o tracex2_user.o
 tracex3-objs := bpf_load.o libbpf.o tracex3_user.o
+tracex4-objs := bpf_load.o libbpf.o tracex4_user.o
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
@@ -26,6 +28,7 @@ always += sockex2_kern.o
 always += tracex1_kern.o
 always += tracex2_kern.o
 always += tracex3_kern.o
+always += tracex4_kern.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 
@@ -35,6 +38,7 @@ HOSTLOADLIBES_sockex2 += -lelf
 HOSTLOADLIBES_tracex1 += -lelf
 HOSTLOADLIBES_tracex2 += -lelf
 HOSTLOADLIBES_tracex3 += -lelf
+HOSTLOADLIBES_tracex4 += -lelf -lrt
 
 # point this to your LLVM backend with bpf support
 LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc
diff --git a/samples/bpf/tracex4_kern.c b/samples/bpf/tracex4_kern.c
new file mode 100644
index 0000000..126b805
--- /dev/null
+++ b/samples/bpf/tracex4_kern.c
@@ -0,0 +1,54 @@
+/* Copyright (c) 2015 PLUMgrid, http://plumgrid.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#include <linux/ptrace.h>
+#include <linux/version.h>
+#include <uapi/linux/bpf.h>
+#include "bpf_helpers.h"
+
+struct pair {
+	u64 val;
+	u64 ip;
+};
+
+struct bpf_map_def SEC("maps") my_map = {
+	.type = BPF_MAP_TYPE_HASH,
+	.key_size = sizeof(long),
+	.value_size = sizeof(struct pair),
+	.max_entries = 1000000,
+};
+
+/* kprobe is NOT a stable ABI. If kernel internals change this bpf+kprobe
+ * example will no longer be meaningful
+ */
+SEC("kprobe/kmem_cache_free")
+int bpf_prog1(struct pt_regs *ctx)
+{
+	long ptr = ctx->si;
+
+	bpf_map_delete_elem(&my_map, &ptr);
+	return 0;
+}
+
+SEC("kretprobe/kmem_cache_alloc_node")
+int bpf_prog2(struct pt_regs *ctx)
+{
+	long ptr = ctx->ax;
+	long ip = 0;
+
+	/* get ip address of kmem_cache_alloc_node() caller */
+	bpf_probe_read(&ip, sizeof(ip), (void *)(ctx->bp + sizeof(ip)));
+
+	struct pair v = {
+		.val = bpf_ktime_get_ns(),
+		.ip = ip,
+	};
+
+	bpf_map_update_elem(&my_map, &ptr, &v, BPF_ANY);
+	return 0;
+}
+char _license[] SEC("license") = "GPL";
+u32 _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/tracex4_user.c b/samples/bpf/tracex4_user.c
new file mode 100644
index 0000000..bc4a3bd
--- /dev/null
+++ b/samples/bpf/tracex4_user.c
@@ -0,0 +1,69 @@
+/* Copyright (c) 2015 PLUMgrid, http://plumgrid.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <string.h>
+#include <time.h>
+#include <linux/bpf.h>
+#include "libbpf.h"
+#include "bpf_load.h"
+
+struct pair {
+	long long val;
+	__u64 ip;
+};
+
+static __u64 time_get_ns(void)
+{
+	struct timespec ts;
+
+	clock_gettime(CLOCK_MONOTONIC, &ts);
+	return ts.tv_sec * 1000000000ull + ts.tv_nsec;
+}
+
+static void print_old_objects(int fd)
+{
+	long long val = time_get_ns();
+	__u64 key, next_key;
+	struct pair v;
+
+	key = write(1, "\e[1;1H\e[2J", 12); /* clear screen */
+
+	key = -1;
+	while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) {
+		bpf_lookup_elem(map_fd[0], &next_key, &v);
+		key = next_key;
+		if (val - v.val < 1000000000ll)
+			/* object was allocated more then 1 sec ago */
+			continue;
+		printf("obj 0x%llx is %2lldsec old was allocated at ip %llx\n",
+		       next_key, (val - v.val) / 1000000000ll, v.ip);
+	}
+}
+
+int main(int ac, char **argv)
+{
+	char filename[256];
+	int i;
+
+	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+
+	if (load_bpf_file(filename)) {
+		printf("%s", bpf_log_buf);
+		return 1;
+	}
+
+	for (i = 0; ; i++) {
+		print_old_objects(map_fd[1]);
+		sleep(1);
+	}
+
+	return 0;
+}

      reply	other threads:[~2015-04-02 12:37 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-25 19:49 [PATCH v11 tip 0/9] tracing: attach eBPF programs to kprobes Alexei Starovoitov
2015-03-25 19:49 ` [PATCH v11 tip 1/9] bpf: make internal bpf API independent of CONFIG_BPF_SYSCALL ifdefs Alexei Starovoitov
2015-04-02 12:34   ` [tip:perf/core] bpf: Make internal bpf API independent of CONFIG_BPF_SYSCALL #ifdefs tip-bot for Daniel Borkmann
2015-03-25 19:49 ` [PATCH v11 tip 2/9] tracing: add kprobe flag Alexei Starovoitov
2015-04-02 12:34   ` [tip:perf/core] tracing: Add " tip-bot for Alexei Starovoitov
2015-03-25 19:49 ` [PATCH v11 tip 3/9] tracing: attach BPF programs to kprobes Alexei Starovoitov
2015-04-02 12:35   ` [tip:perf/core] tracing, perf: Implement BPF programs attached " tip-bot for Alexei Starovoitov
2015-03-25 19:49 ` [PATCH v11 tip 4/9] tracing: allow BPF programs to call bpf_ktime_get_ns() Alexei Starovoitov
2015-04-02 12:35   ` [tip:perf/core] tracing: Allow " tip-bot for Alexei Starovoitov
2015-03-25 19:49 ` [PATCH v11 tip 5/9] tracing: allow BPF programs to call bpf_trace_printk() Alexei Starovoitov
2015-04-02 12:35   ` [tip:perf/core] tracing: Allow " tip-bot for Alexei Starovoitov
2015-03-25 19:49 ` [PATCH v11 tip 6/9] samples: bpf: simple non-portable kprobe filter example Alexei Starovoitov
2015-03-30  0:34   ` Jovi Zhangwei
2015-03-30  0:59     ` Alexei Starovoitov
2015-04-02 12:36   ` [tip:perf/core] samples/bpf: Add " tip-bot for Alexei Starovoitov
2015-03-25 19:49 ` [PATCH v11 tip 7/9] samples: bpf: counting example for kfree_skb and write syscall Alexei Starovoitov
2015-04-02 12:36   ` [tip:perf/core] samples/bpf: Add counting example for kfree_skb() function calls and the write() syscall tip-bot for Alexei Starovoitov
2015-03-25 19:49 ` [PATCH v11 tip 8/9] samples: bpf: IO latency analysis (iosnoop/heatmap) Alexei Starovoitov
2015-04-02 12:36   ` [tip:perf/core] samples/bpf: Add IO latency analysis (iosnoop/ heatmap) tool tip-bot for Alexei Starovoitov
2015-03-25 19:49 ` [PATCH v11 tip 9/9] samples: bpf: kmem_alloc/free tracker Alexei Starovoitov
2015-04-02 12:36   ` tip-bot for Alexei Starovoitov [this message]

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=tip-9811e35359d4b18baf5bb603b225e957255b9c46@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=acme@infradead.org \
    --cc=acme@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=ast@plumgrid.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=hpa@zytor.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /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

Powered by JetHome