Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1158111 > unrolled thread
| Started by | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| First post | 2015-06-04 00:50 +0200 |
| Last post | 2015-06-04 12:30 +0200 |
| Articles | 7 — 3 participants |
Back to article view | Back to linux.kernel
[GIT PULL 0/6] perf/core improvements and fixes Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-06-04 00:50 +0200
[PATCH 4/6] perf tools: Move linux/kernel.h to tools/include Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-06-04 00:50 +0200
[PATCH 5/6] tools: Move tools/perf/util/include/linux/{list.h,poison.h} to tools/include Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-06-04 00:50 +0200
[PATCH 1/6] perf probe: Fix segfault when glob matching function without debuginfo Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-06-04 00:50 +0200
[PATCH 3/6] perf machine: Fix the search for the kernel DSO on the unified list Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-06-04 00:50 +0200
Re: [GIT PULL 0/6] perf/core improvements and fixes Ingo Molnar <mingo@kernel.org> - 2015-06-04 09:30 +0200
[EXPERIENCE] My experience on using perf record BPF filter on a real usecase "Wangnan (F)" <wangnan0@huawei.com> - 2015-06-04 12:30 +0200
| From | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| Date | 2015-06-04 00:50 +0200 |
| Subject | [GIT PULL 0/6] perf/core improvements and fixes |
| Message-ID | <pxpDX-6H6-5@gated-at.bofh.it> |
Hi Ingo,
Please consider applying.
One of the next requests probably will have the eBPF work by Wang Nan,
but I am still going thru it and want to test it thoroughly.
BTW: Have you looked at it lately? It is at:
http://lkml.kernel.org/r/1433144296-74992-1-git-send-email-wangnan0@huawei.com
Super summary from the above cover letter:
---------------------
It enables 'perf record' to filter events using eBPF programs like:
# perf record --event bpf-file.o sleep 1
Events are selected and filtered according to definitions in bpf-file.o.
---------------------
The first two patches from that series are in this pull req, as
they just move stuff into tools/include/linux/ from tools/perf/include.
Regards,
- Arnaldo
The following changes since commit 5c9b9bc67c684e40b3a5e7e9facde0fb7200cd8c:
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2015-05-29 20:19:02 +0200)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo
for you to fetch changes up to 1f121b03d058dd07199d8924373d3c52a207f63b:
perf tools: Deal with kernel module names in '[]' correctly (2015-06-03 10:02:38 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
User visible:
- Fix 'perf probe' segfault when glob matching function without debuginfo (Wang Nan)
- Remove newline char when reading event scale and unit (Madhavan Srinivasan)
- Deal with kernel module names in '[]' correctly (Wang Nan)
Infrastructure:
- Fix the search for the kernel DSO on the unified list (Arnaldo Carvalho de Melo)
- Move tools/perf/util/include/linux/{kernel.h,list.h,poison.h} to tools/include,
to be used in tools/lib/bpf/ (Wang Nan)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
----------------------------------------------------------------
Arnaldo Carvalho de Melo (1):
perf machine: Fix the search for the kernel DSO on the unified list
Madhavan Srinivasan (1):
perf tools: Remove newline char when reading event scale and unit
Wang Nan (4):
perf probe: Fix segfault when glob matching function without debuginfo
perf tools: Move linux/kernel.h to tools/include
tools: Move tools/perf/util/include/linux/{list.h,poison.h} to tools/include
perf tools: Deal with kernel module names in '[]' correctly
tools/{perf/util => }/include/linux/kernel.h | 4 +-
tools/{perf/util => }/include/linux/list.h | 6 +--
tools/include/linux/poison.h | 1 +
tools/perf/MANIFEST | 3 ++
tools/perf/tests/kmod-path.c | 72 ++++++++++++++++++++++++++++
tools/perf/util/dso.c | 47 ++++++++++++++++--
tools/perf/util/dso.h | 2 +-
tools/perf/util/header.c | 8 ++--
tools/perf/util/include/linux/poison.h | 1 -
tools/perf/util/machine.c | 22 ++++++++-
tools/perf/util/pmu.c | 11 ++++-
tools/perf/util/probe-event.c | 26 ++++++++--
12 files changed, 179 insertions(+), 24 deletions(-)
rename tools/{perf/util => }/include/linux/kernel.h (97%)
rename tools/{perf/util => }/include/linux/list.h (90%)
create mode 100644 tools/include/linux/poison.h
delete mode 100644 tools/perf/util/include/linux/poison.h
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| Date | 2015-06-04 00:50 +0200 |
| Subject | [PATCH 4/6] perf tools: Move linux/kernel.h to tools/include |
| Message-ID | <pxpDY-6H6-11@gated-at.bofh.it> |
| In reply to | #1158111 |
From: Wang Nan <wangnan0@huawei.com>
This patch moves kernel.h from tools/perf/util/include/linux/kernel.h
to tools/include/linux/kernel.h to enable other libraries use macros in
it, like libbpf which will be introduced by further patches.
MANIFEST is also updated for 'make perf-*-src-pkg'.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: David Ahern <dsahern@gmail.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kaixu Xia <xiakaixu@huawei.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1433144296-74992-2-git-send-email-wangnan0@huawei.com
[ Fixed up the ifdef guard to match other entries in tools/include/linux ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/include/linux/kernel.h | 107 +++++++++++++++++++++++++++++++++
tools/perf/MANIFEST | 1 +
tools/perf/util/include/linux/kernel.h | 107 ---------------------------------
3 files changed, 108 insertions(+), 107 deletions(-)
create mode 100644 tools/include/linux/kernel.h
delete mode 100644 tools/perf/util/include/linux/kernel.h
diff --git a/tools/include/linux/kernel.h b/tools/include/linux/kernel.h
new file mode 100644
index 000000000000..76df53539c2a
--- /dev/null
+++ b/tools/include/linux/kernel.h
@@ -0,0 +1,107 @@
+#ifndef __TOOLS_LINUX_KERNEL_H
+#define __TOOLS_LINUX_KERNEL_H
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
+#define PERF_ALIGN(x, a) __PERF_ALIGN_MASK(x, (typeof(x))(a)-1)
+#define __PERF_ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#ifndef container_of
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof(((type *)0)->member) * __mptr = (ptr); \
+ (type *)((char *)__mptr - offsetof(type, member)); })
+#endif
+
+#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
+
+#ifndef max
+#define max(x, y) ({ \
+ typeof(x) _max1 = (x); \
+ typeof(y) _max2 = (y); \
+ (void) (&_max1 == &_max2); \
+ _max1 > _max2 ? _max1 : _max2; })
+#endif
+
+#ifndef min
+#define min(x, y) ({ \
+ typeof(x) _min1 = (x); \
+ typeof(y) _min2 = (y); \
+ (void) (&_min1 == &_min2); \
+ _min1 < _min2 ? _min1 : _min2; })
+#endif
+
+#ifndef roundup
+#define roundup(x, y) ( \
+{ \
+ const typeof(y) __y = y; \
+ (((x) + (__y - 1)) / __y) * __y; \
+} \
+)
+#endif
+
+#ifndef BUG_ON
+#ifdef NDEBUG
+#define BUG_ON(cond) do { if (cond) {} } while (0)
+#else
+#define BUG_ON(cond) assert(!(cond))
+#endif
+#endif
+
+/*
+ * Both need more care to handle endianness
+ * (Don't use bitmap_copy_le() for now)
+ */
+#define cpu_to_le64(x) (x)
+#define cpu_to_le32(x) (x)
+
+static inline int
+vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
+{
+ int i;
+ ssize_t ssize = size;
+
+ i = vsnprintf(buf, size, fmt, args);
+
+ return (i >= ssize) ? (ssize - 1) : i;
+}
+
+static inline int scnprintf(char * buf, size_t size, const char * fmt, ...)
+{
+ va_list args;
+ ssize_t ssize = size;
+ int i;
+
+ va_start(args, fmt);
+ i = vsnprintf(buf, size, fmt, args);
+ va_end(args);
+
+ return (i >= ssize) ? (ssize - 1) : i;
+}
+
+/*
+ * This looks more complex than it should be. But we need to
+ * get the type for the ~ right in round_down (it needs to be
+ * as wide as the result!), and we want to evaluate the macro
+ * arguments just once each.
+ */
+#define __round_mask(x, y) ((__typeof__(x))((y)-1))
+#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
+#define round_down(x, y) ((x) & ~__round_mask(x, y))
+
+#endif
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index a83cf75164e1..fce4a47347aa 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -40,6 +40,7 @@ tools/include/linux/bitops.h
tools/include/linux/compiler.h
tools/include/linux/export.h
tools/include/linux/hash.h
+tools/include/linux/kernel.h
tools/include/linux/log2.h
tools/include/linux/types.h
include/asm-generic/bitops/arch_hweight.h
diff --git a/tools/perf/util/include/linux/kernel.h b/tools/perf/util/include/linux/kernel.h
deleted file mode 100644
index 09e8e7aea7c6..000000000000
--- a/tools/perf/util/include/linux/kernel.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef PERF_LINUX_KERNEL_H_
-#define PERF_LINUX_KERNEL_H_
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-
-#define PERF_ALIGN(x, a) __PERF_ALIGN_MASK(x, (typeof(x))(a)-1)
-#define __PERF_ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
-
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-
-#ifndef container_of
-/**
- * container_of - cast a member of a structure out to the containing structure
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({ \
- const typeof(((type *)0)->member) * __mptr = (ptr); \
- (type *)((char *)__mptr - offsetof(type, member)); })
-#endif
-
-#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
-
-#ifndef max
-#define max(x, y) ({ \
- typeof(x) _max1 = (x); \
- typeof(y) _max2 = (y); \
- (void) (&_max1 == &_max2); \
- _max1 > _max2 ? _max1 : _max2; })
-#endif
-
-#ifndef min
-#define min(x, y) ({ \
- typeof(x) _min1 = (x); \
- typeof(y) _min2 = (y); \
- (void) (&_min1 == &_min2); \
- _min1 < _min2 ? _min1 : _min2; })
-#endif
-
-#ifndef roundup
-#define roundup(x, y) ( \
-{ \
- const typeof(y) __y = y; \
- (((x) + (__y - 1)) / __y) * __y; \
-} \
-)
-#endif
-
-#ifndef BUG_ON
-#ifdef NDEBUG
-#define BUG_ON(cond) do { if (cond) {} } while (0)
-#else
-#define BUG_ON(cond) assert(!(cond))
-#endif
-#endif
-
-/*
- * Both need more care to handle endianness
- * (Don't use bitmap_copy_le() for now)
- */
-#define cpu_to_le64(x) (x)
-#define cpu_to_le32(x) (x)
-
-static inline int
-vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
-{
- int i;
- ssize_t ssize = size;
-
- i = vsnprintf(buf, size, fmt, args);
-
- return (i >= ssize) ? (ssize - 1) : i;
-}
-
-static inline int scnprintf(char * buf, size_t size, const char * fmt, ...)
-{
- va_list args;
- ssize_t ssize = size;
- int i;
-
- va_start(args, fmt);
- i = vsnprintf(buf, size, fmt, args);
- va_end(args);
-
- return (i >= ssize) ? (ssize - 1) : i;
-}
-
-/*
- * This looks more complex than it should be. But we need to
- * get the type for the ~ right in round_down (it needs to be
- * as wide as the result!), and we want to evaluate the macro
- * arguments just once each.
- */
-#define __round_mask(x, y) ((__typeof__(x))((y)-1))
-#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
-#define round_down(x, y) ((x) & ~__round_mask(x, y))
-
-#endif
--
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| Date | 2015-06-04 00:50 +0200 |
| Subject | [PATCH 5/6] tools: Move tools/perf/util/include/linux/{list.h,poison.h} to tools/include |
| Message-ID | <pxpDY-6H6-27@gated-at.bofh.it> |
| In reply to | #1158111 |
From: Wang Nan <wangnan0@huawei.com>
This patch moves list.h from tools/perf/util/include/linux/list.h to
tools/include/linux/list.h to enable other libraries use macros in it,
like libbpf which will be introduced by further patches. Since list.h
depend on poison.h, poison.h is also moved.
Both file use relative path, so one '..' is removed for each header to
make them suit for new directory.
MANIFEST is also updated for 'make perf-*-src-pkg'.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: David Ahern <dsahern@gmail.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kaixu Xia <xiakaixu@huawei.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1433144296-74992-3-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/include/linux/list.h | 29 +++++++++++++++++++++++++++++
tools/include/linux/poison.h | 1 +
tools/perf/MANIFEST | 2 ++
tools/perf/util/include/linux/list.h | 29 -----------------------------
tools/perf/util/include/linux/poison.h | 1 -
5 files changed, 32 insertions(+), 30 deletions(-)
create mode 100644 tools/include/linux/list.h
create mode 100644 tools/include/linux/poison.h
delete mode 100644 tools/perf/util/include/linux/list.h
delete mode 100644 tools/perf/util/include/linux/poison.h
diff --git a/tools/include/linux/list.h b/tools/include/linux/list.h
new file mode 100644
index 000000000000..76b014c96893
--- /dev/null
+++ b/tools/include/linux/list.h
@@ -0,0 +1,29 @@
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "../../../include/linux/list.h"
+
+#ifndef TOOLS_LIST_H
+#define TOOLS_LIST_H
+/**
+ * list_del_range - deletes range of entries from list.
+ * @begin: first element in the range to delete from the list.
+ * @end: last element in the range to delete from the list.
+ * Note: list_empty on the range of entries does not return true after this,
+ * the entries is in an undefined state.
+ */
+static inline void list_del_range(struct list_head *begin,
+ struct list_head *end)
+{
+ begin->prev->next = end->next;
+ end->next->prev = begin->prev;
+}
+
+/**
+ * list_for_each_from - iterate over a list from one of its nodes
+ * @pos: the &struct list_head to use as a loop cursor, from where to start
+ * @head: the head for your list.
+ */
+#define list_for_each_from(pos, head) \
+ for (; pos != (head); pos = pos->next)
+#endif
diff --git a/tools/include/linux/poison.h b/tools/include/linux/poison.h
new file mode 100644
index 000000000000..0c27bdf14233
--- /dev/null
+++ b/tools/include/linux/poison.h
@@ -0,0 +1 @@
+#include "../../../include/linux/poison.h"
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index fce4a47347aa..a0bdd6124583 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -41,7 +41,9 @@ tools/include/linux/compiler.h
tools/include/linux/export.h
tools/include/linux/hash.h
tools/include/linux/kernel.h
+tools/include/linux/list.h
tools/include/linux/log2.h
+tools/include/linux/poison.h
tools/include/linux/types.h
include/asm-generic/bitops/arch_hweight.h
include/asm-generic/bitops/const_hweight.h
diff --git a/tools/perf/util/include/linux/list.h b/tools/perf/util/include/linux/list.h
deleted file mode 100644
index 76ddbc726343..000000000000
--- a/tools/perf/util/include/linux/list.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-#include "../../../../include/linux/list.h"
-
-#ifndef PERF_LIST_H
-#define PERF_LIST_H
-/**
- * list_del_range - deletes range of entries from list.
- * @begin: first element in the range to delete from the list.
- * @end: last element in the range to delete from the list.
- * Note: list_empty on the range of entries does not return true after this,
- * the entries is in an undefined state.
- */
-static inline void list_del_range(struct list_head *begin,
- struct list_head *end)
-{
- begin->prev->next = end->next;
- end->next->prev = begin->prev;
-}
-
-/**
- * list_for_each_from - iterate over a list from one of its nodes
- * @pos: the &struct list_head to use as a loop cursor, from where to start
- * @head: the head for your list.
- */
-#define list_for_each_from(pos, head) \
- for (; pos != (head); pos = pos->next)
-#endif
diff --git a/tools/perf/util/include/linux/poison.h b/tools/perf/util/include/linux/poison.h
deleted file mode 100644
index fef6dbc9ce13..000000000000
--- a/tools/perf/util/include/linux/poison.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../../include/linux/poison.h"
--
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| Date | 2015-06-04 00:50 +0200 |
| Subject | [PATCH 1/6] perf probe: Fix segfault when glob matching function without debuginfo |
| Message-ID | <pxpDZ-6H6-33@gated-at.bofh.it> |
| In reply to | #1158111 |
From: Wang Nan <wangnan0@huawei.com>
Commit 4c859351226c920b227fec040a3b447f0d482af3 ("perf probe: Support
glob wildcards for function name") introduces segfault problems when
debuginfo is not available:
# perf probe 'sys_w*'
Added new events:
Segmentation fault
The first problem resides in find_probe_trace_events_from_map(). In
that function, find_probe_functions() is called to match each symbol
against glob to find the number of matching functions, but still use
map__for_each_symbol_by_name() to find 'struct symbol' for matching
functions. Unfortunately, map__for_each_symbol_by_name() does
exact matching by searching in an rbtree.
It doesn't know glob matching, and not easy for it to support it because
it use rbtree based binary search, but we are unable to ensure all names
matched by the glob (any glob passed by user) reside in one subtree.
This patch drops map__for_each_symbol_by_name(). Since there is no
rbtree again, re-matching all symbols costs a lot. This patch avoid it
by saving all matching results into an array (syms).
The second problem is the lost of tp->realname. In
__add_probe_trace_events(), if pev->point.function is glob, the event
name should be set to tev->point.realname. This patch ensures its
existence by strdup sym->name instead of leaving a NULL pointer there.
After this patch:
# perf probe 'sys_w*'
Added new events:
probe:sys_waitid (on sys_w*)
probe:sys_wait4 (on sys_w*)
probe:sys_waitpid (on sys_w*)
probe:sys_write (on sys_w*)
probe:sys_writev (on sys_w*)
You can now use it in all perf tools, such as:
perf record -e probe:sys_writev -aR sleep 1
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Link: http://lkml.kernel.org/r/1432892747-232506-1-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/probe-event.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index d27edef5eb5b..e6f215b7a052 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2494,7 +2494,8 @@ close_out:
return ret;
}
-static int find_probe_functions(struct map *map, char *name)
+static int find_probe_functions(struct map *map, char *name,
+ struct symbol **syms)
{
int found = 0;
struct symbol *sym;
@@ -2504,8 +2505,11 @@ static int find_probe_functions(struct map *map, char *name)
return 0;
map__for_each_symbol(map, sym, tmp) {
- if (strglobmatch(sym->name, name))
+ if (strglobmatch(sym->name, name)) {
found++;
+ if (syms && found < probe_conf.max_probes)
+ syms[found - 1] = sym;
+ }
}
return found;
@@ -2528,11 +2532,12 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
struct map *map = NULL;
struct ref_reloc_sym *reloc_sym = NULL;
struct symbol *sym;
+ struct symbol **syms = NULL;
struct probe_trace_event *tev;
struct perf_probe_point *pp = &pev->point;
struct probe_trace_point *tp;
int num_matched_functions;
- int ret, i;
+ int ret, i, j;
map = get_target_map(pev->target, pev->uprobes);
if (!map) {
@@ -2540,11 +2545,17 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
goto out;
}
+ syms = malloc(sizeof(struct symbol *) * probe_conf.max_probes);
+ if (!syms) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
/*
* Load matched symbols: Since the different local symbols may have
* same name but different addresses, this lists all the symbols.
*/
- num_matched_functions = find_probe_functions(map, pp->function);
+ num_matched_functions = find_probe_functions(map, pp->function, syms);
if (num_matched_functions == 0) {
pr_err("Failed to find symbol %s in %s\n", pp->function,
pev->target ? : "kernel");
@@ -2575,7 +2586,9 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
ret = 0;
- map__for_each_symbol_by_name(map, pp->function, sym) {
+ for (j = 0; j < num_matched_functions; j++) {
+ sym = syms[j];
+
tev = (*tevs) + ret;
tp = &tev->point;
if (ret == num_matched_functions) {
@@ -2599,6 +2612,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
tp->symbol = strdup_or_goto(sym->name, nomem_out);
tp->offset = pp->offset;
}
+ tp->realname = strdup_or_goto(sym->name, nomem_out);
+
tp->retprobe = pp->retprobe;
if (pev->target)
tev->point.module = strdup_or_goto(pev->target,
@@ -2629,6 +2644,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
out:
put_target_map(map, pev->uprobes);
+ free(syms);
return ret;
nomem_out:
--
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| Date | 2015-06-04 00:50 +0200 |
| Subject | [PATCH 3/6] perf machine: Fix the search for the kernel DSO on the unified list |
| Message-ID | <pxpDZ-6H6-43@gated-at.bofh.it> |
| In reply to | #1158111 |
From: Arnaldo Carvalho de Melo <acme@redhat.com>
When unifying the user_dsos and kernel_dsos a bug was introduced by
inverting the check for dso->kernel, fix it.
Fixes: 3d39ac538629 ("perf machine: No need to have two DSOs lists")
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/n/tip-xnrnq0kams3s2z9ek1wjb506@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/machine.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 2ed61f59d415..4e29e80932e5 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1149,7 +1149,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
struct dso *dso;
list_for_each_entry(dso, &machine->dsos.head, node) {
- if (dso->kernel && is_kernel_module(dso->long_name))
+ if (!dso->kernel || is_kernel_module(dso->long_name))
continue;
kernel = dso;
--
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Ingo Molnar <mingo@kernel.org> |
|---|---|
| Date | 2015-06-04 09:30 +0200 |
| Message-ID | <pxxLb-27e-11@gated-at.bofh.it> |
| In reply to | #1158111 |
* Wangnan (F) <wangnan0@huawei.com> wrote: > On 2015/6/4 13:48, Ingo Molnar wrote: > >* Arnaldo Carvalho de Melo <acme@kernel.org> wrote: > > > >>Hi Ingo, > >> > >> Please consider applying. > >> > >> One of the next requests probably will have the eBPF work by Wang Nan, > >>but I am still going thru it and want to test it thoroughly. > >> > >> BTW: Have you looked at it lately? It is at: > >> > >>http://lkml.kernel.org/r/1433144296-74992-1-git-send-email-wangnan0@huawei.com > >> > >>Super summary from the above cover letter: > >> > >>--------------------- > >>It enables 'perf record' to filter events using eBPF programs like: > >> > >> # perf record --event bpf-file.o sleep 1 > >> > >>Events are selected and filtered according to definitions in bpf-file.o. > >Looks useful, but I think the UI needs one more tweak: could you fix it to be able > >to filter based on the eBPF _source_ file, not just the object file? > > > >People want to tweak such filters as they profile, so we should use the eBPF > >source code as the primary interface. We can compile it internally to the .o just > >fine. The .o file is a totally uninteresting intermediate product in itself. > > > >I.e. we need to first think through such profiling workflows from beginning to end > >before allowing them upstream. > > In a private mail Alexei Starovoitov disscussed with me about this. He said that > he is working on a shared object which can compile C program into BPF bytecode > on the fly. After he done his work, I think perf can support dtrace-like > profiling that, users will be able to feed source code to perf directly on > cmdline. He said he can release it on June. I added him to the CC-list. > > However I think the '.o' intermediate is still needed. [...] So how do you generate the .o? Why cannot the tool, if it sees that the filter parameter is eBPF source code, do that automatically? I.e. you are making the user jump through hoops for no good reason - that's a bad UI and a bad workflow. Please don't do that! Thanks, Ingo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | "Wangnan (F)" <wangnan0@huawei.com> |
|---|---|
| Date | 2015-06-04 12:30 +0200 |
| Subject | [EXPERIENCE] My experience on using perf record BPF filter on a real usecase |
| Message-ID | <pxAzo-6eI-3@gated-at.bofh.it> |
| In reply to | #1158111 |
Hi all,
I'd like to share my exprience on using 'perf record' BPF filter in a
real usecase to show the power and shortcome in my patch series:
https://lkml.kernel.org/r/1433144296-74992-1-git-send-email-wangnan0@huawei.com
and other works on eBPF.
My usecase shows that such filter is useful. Also, I hope it can help us
to find way to further improve it.
My task is to find the reason why iozone test result is bad on some
specific cases. The development environment is a x86_64 server, the target
machine is a smartphone with Android. By previous analysis I have
already got some useful information:
1. iozone computes bandwidth by averaging time of each sys_write.
2. In our case, 1% sys_write takes 75% of total time, so what I need
to do now should be finding the reason why those sys_write take so
long.
3. By sampling call stack on sched:sched_switch, I find that those
sys_write calls lock_page() and blocks on it.
I decide to use BPF filter to find the other side of this locking
contention. The idea is simple:
1. For all calls of lock_page(), probe at entry and exit points of
it. Measure the execution time of the lock_page() call. If it takes
too long (longer than 0.1 second) then there should have a lock
contention. Take the sample at exit point.
2. For all calls of unlock_page(), if the page is acquiring by other
on at least 0.1 second before, take a sample at this point.
Currently making the above idea work is possible but not very
straightforward. One problem I can identify is:
Doesn't like ftrace, there is no way for eBPF program to access call
stack information. Without extra information, eBPF programs are
unable to match lock_page events and corresponding lock_page%return
events. Currently the only way for passing information between
programs are maps. To simulate call stack matching, I create a
BPF_FUNC_git_tid() which returns current->pid, and a
proc_locking_page_map map which records the acquired page and time
of calling lock_page.
Another problem is: at the entry of lock_page() and
unlock_page(), for fetching the page pointer I have to directly
use 'ctx->regs[0]' (I am on aarch64). Which is not protable.
The final program I used is attached at the bottom of this email. It
costs more than 100 lines of code. I have to do some debugging to
ensure it works correctly on a virtual machine.
It is compiled using:
# $CLANG ${INCLUDE} -D__KERNEL__ -Wno-unused-value -Wno-pointer-sign -O2 \
-emit-llvm -c lock_page.c -o - | $LLC -march=bpf -filetype=obj -o \
lock_page.o
Then the lock_page.o is transfered onto target system.
I loaded it using following command:
# perf record -e syscalls:sys_enter_write -e syscalls:sys_exit_write \
-e lock_page.o -a iozone ...
Here is another inconvenience. Currently I only concern on write
syscall issued by iozone. However, without '-a' I'm unable to collect
information of the locker. If I want to filter sys_{enter,exit}_write
belong to iozone out using eBPF, I need to implement another function
like BPF_FUNC_git_comm. Another method is to use perf '--filter' after
the two events. However it looks strange to use two filter mechanisms
together. This time I choose to do filtering offline using perf script.
The result is resonable. Finaly I found the two side of lock contention.
It shows the way to improve. I'm sorry I can't share the call stack in
this list.
One inconvenience in this stage is: the information is
printed into ring buffer while the samples are stored into perf.data.
By analysing perf.data without ftrace ring buffer I don't know how long
the lock_page() cost becasue I don't sample at the entry of
lock_page().
The final part is the BPF program I used. I think there should have
better way to do it. If any know how to make it shorter please let me
know.
Thank you.
/* ------------- START OF BPF PROGRAM ------------- */
/* __lock_page pass to unlock_page, key is pid */
struct proc_locking_page {
unsigned long page;
unsigned long time;
};
struct bpf_map_def SEC("maps") proc_locking_page_map = {
.type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(unsigned long),
.value_size = sizeof(struct proc_locking_page),
.max_entries = 1000000,
};
/* from page get pid */
struct page_being_locked_by_proc {
unsigned long tid;
unsigned long time;
};
struct bpf_map_def SEC("maps") page_being_locked_by_proc_map = {
.type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(unsigned long),
.value_size = sizeof(struct page_being_locked_by_proc),
.max_entries = 1000000,
};
SEC("lock_page=__lock_page")
int lock_page_recorder(struct pt_regs *ctx)
{
unsigned long tid = bpf_get_tid();
unsigned long page = ctx->regs[0];
unsigned long curr_ns = bpf_ktime_get_ns();
struct proc_locking_page locking_page;
struct page_being_locked_by_proc being_locked;
locking_page.page = page;
locking_page.time = curr_ns;
being_locked.tid = tid;
being_locked.time = curr_ns;
bpf_map_update_elem(&proc_locking_page_map, &tid,
&locking_page, BPF_ANY);
bpf_map_update_elem(&page_being_locked_by_proc_map, &page,
&being_locked, BPF_ANY);
return 0;
}
SEC("lock_page_ret=__lock_page%return")
int lock_page_return_recorder(struct pt_regs *ctx)
{
unsigned long tid = bpf_get_tid();
unsigned long curr_ns = bpf_ktime_get_ns();
unsigned long page;
unsigned long diff_time;
struct proc_locking_page *p_locking_page;
p_locking_page = bpf_map_lookup_elem(&proc_locking_page_map, &tid);
/* BAD!! */
if (!p_locking_page)
return 0;
page = p_locking_page->page;
diff_time = curr_ns - p_locking_page->time;
bpf_map_delete_elem(&proc_locking_page_map, &tid);
bpf_map_delete_elem(&page_being_locked_by_proc_map, &page);
if (diff_time > 10000000) {
char fmt[] = "tid %d get page %lx using %d ns\n";
bpf_trace_printk(fmt, sizeof(fmt), tid, page, diff_time);
return 1;
}
return 0;
}
SEC("unlock_page=unlock_page")
int unlock_page_recorder(struct pt_regs *ctx)
{
unsigned long tid = bpf_get_tid();
unsigned long page = ctx->regs[0];
unsigned long time = bpf_ktime_get_ns();
unsigned long diff_time;
struct page_being_locked_by_proc *p_being_locked;
char fmt[] = "%d vs %d, %d ns\n";
p_being_locked =
bpf_map_lookup_elem(&page_being_locked_by_proc_map, &page);
if (!p_being_locked)
return 0;
diff_time = time - p_being_locked->time;
if (diff_time > 10000000) {
bpf_trace_printk(fmt, sizeof(fmt), tid,
p_being_locked->tid, diff_time);
return 1;
}
return 0;
}
/* ------------- END OF BPF PROGRAM ------------- */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web