File perf-probe-check-address-correctness-by-map-instead-of-etext.patch of Package perf
115
1
From: Masami Hiramatsu <mhiramat@kernel.org>
2
Date: Thu, 23 Apr 2020 20:01:13 +0900
3
Subject: perf probe: Check address correctness by map instead of _etext
4
Git-commit: 2ae5d0d7d8868df7c05c2013c0b9cddd4d40610e
5
References: git-fixes
6
7
Since commit 03db8b583d1c ("perf tools: Fix
8
maps__find_symbol_by_name()") introduced map address range check in
9
maps__find_symbol_by_name(), we can not get "_etext" from kernel map
10
because _etext is placed on the edge of the kernel .text section (=
11
kernel map in perf.)
12
13
To fix this issue, this checks the address correctness by map address
14
range information (map->start and map->end) instead of using _etext
15
address.
16
17
This can cause an error if the target inlined function is embedded in
18
both __init function and normal function.
19
20
For exaample, request_resource() is a normal function but also embedded
21
in __init reserve_setup(). In this case, the probe point in
22
reserve_setup() must be skipped.
23
24
However, without this fix, it failes to setup all probe points:
25
26
# ./perf probe -v request_resource
27
probe-definition(0): request_resource
28
symbol:request_resource file:(null) line:0 offset:0 return:0 lazy:(null)
29
0 arguments
30
Looking at the vmlinux_path (8 entries long)
31
Using /usr/lib/debug/lib/modules/5.5.17-200.fc31.x86_64/vmlinux for symbols
32
Open Debuginfo file: /usr/lib/debug/lib/modules/5.5.17-200.fc31.x86_64/vmlinux
33
Try to find probe point from debuginfo.
34
Matched function: request_resource [15e29ad]
35
found inline addr: 0xffffffff82fbf892
36
Probe point found: reserve_setup+204
37
found inline addr: 0xffffffff810e9790
38
Probe point found: request_resource+0
39
Found 2 probe_trace_events.
40
Opening /sys/kernel/debug/tracing//kprobe_events write=1
41
Opening /sys/kernel/debug/tracing//README write=0
42
Writing event: p:probe/request_resource _text+33290386
43
Failed to write event: Invalid argument
44
Error: Failed to add events. Reason: Invalid argument (Code: -22)
45
#
46
47
With this fix,
48
49
# ./perf probe request_resource
50
reserve_setup is out of .text, skip it.
51
Added new events:
52
(null):(null) (on request_resource)
53
probe:request_resource (on request_resource)
54
55
You can now use it in all perf tools, such as:
56
57
perf record -e probe:request_resource -aR sleep 1
58
59
#
60
61
Fixes: 03db8b583d1c ("perf tools: Fix maps__find_symbol_by_name()")
62
Reported-by: Arnaldo Carvalho de Melo <acme@kernel.org>
63
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
64
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
65
Cc: Jiri Olsa <jolsa@kernel.org>
66
Cc: Namhyung Kim <namhyung@kernel.org>
67
Cc: stable@vger.kernel.org
68
Link: http://lore.kernel.org/lkml/158763967332.30755.4922496724365529088.stgit@devnote2
69
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
70
Acked-by: Tony Jones <tonyj@suse.de>
71
---
72
tools/perf/util/probe-event.c | 25 +++++++++++++------------
73
1 file changed, 13 insertions(+), 12 deletions(-)
74
75
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
76
index 63d936f6e993..a08f373d3305 100644
77
--- a/tools/perf/util/probe-event.c
78
+++ b/tools/perf/util/probe-event.c
79
80
static bool kprobe_blacklist__listed(unsigned long address);
81
static bool kprobe_warn_out_range(const char *symbol, unsigned long address)
82
{
83
- u64 etext_addr = 0;
84
- int ret;
85
-
86
- /* Get the address of _etext for checking non-probable text symbol */
87
- ret = kernel_get_symbol_address_by_name("_etext", &etext_addr,
88
- false, false);
89
+ struct map *map;
90
+ bool ret = false;
91
92
- if (ret == 0 && etext_addr < address)
93
- pr_warning("%s is out of .text, skip it.\n", symbol);
94
- else if (kprobe_blacklist__listed(address))
95
+ map = kernel_get_module_map(NULL);
96
+ if (map) {
97
+ ret = address <= map->start || map->end < address;
98
+ if (ret)
99
+ pr_warning("%s is out of .text, skip it.\n", symbol);
100
+ map__put(map);
101
+ }
102
+ if (!ret && kprobe_blacklist__listed(address)) {
103
pr_warning("%s is blacklisted function, skip it.\n", symbol);
104
- else
105
- return false;
106
+ ret = true;
107
+ }
108
109
- return true;
110
+ return ret;
111
}
112
113
/*
114
115