summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorThomas Richter <tmricht@linux.ibm.com>2019-07-24 08:27:02 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-08-08 14:41:11 -0400
commit12a6d2940b5f02b4b9f71ce098e3bb02bc24a9ea (patch)
tree484a05f6c20afdcfae1256e6a2583e8a0646543e /tools
parentfa37bab6d7154658d8a35920513f9396587754cc (diff)
perf record: Fix module size on s390
On s390 the modules loaded in memory have the text segment located after the GOT and Relocation table. This can be seen with this output: [root@m35lp76 perf]# fgrep qeth /proc/modules qeth 151552 1 qeth_l2, Live 0x000003ff800b2000 ... [root@m35lp76 perf]# cat /sys/module/qeth/sections/.text 0x000003ff800b3990 [root@m35lp76 perf]# There is an offset of 0x1990 bytes. The size of the qeth module is 151552 bytes (0x25000 in hex). The location of the GOT/relocation table at the beginning of a module is unique to s390. commit 203d8a4aa6ed ("perf s390: Fix 'start' address of module's map") adjusts the start address of a module in the map structures, but does not adjust the size of the modules. This leads to overlapping of module maps as this example shows: [root@m35lp76 perf] # ./perf report -D 0 0 0xfb0 [0xa0]: PERF_RECORD_MMAP -1/0: [0x3ff800b3990(0x25000) @ 0]: x /lib/modules/.../qeth.ko.xz 0 0 0x1050 [0xb0]: PERF_RECORD_MMAP -1/0: [0x3ff800d85a0(0x8000) @ 0]: x /lib/modules/.../ip6_tables.ko.xz The module qeth.ko has an adjusted start address modified to b3990, but its size is unchanged and the module ends at 0x3ff800d8990. This end address overlaps with the next modules start address of 0x3ff800d85a0. When the size of the leading GOT/Relocation table stored in the beginning of the text segment (0x1990 bytes) is subtracted from module qeth end address, there are no overlaps anymore: 0x3ff800d8990 - 0x1990 = 0x0x3ff800d7000 which is the same as 0x3ff800b2000 + 0x25000 = 0x0x3ff800d7000. To fix this issue, also adjust the modules size in function arch__fix_module_text_start(). Add another function parameter named size and reduce the size of the module when the text segment start address is changed. Output after: 0 0 0xfb0 [0xa0]: PERF_RECORD_MMAP -1/0: [0x3ff800b3990(0x23670) @ 0]: x /lib/modules/.../qeth.ko.xz 0 0 0x1050 [0xb0]: PERF_RECORD_MMAP -1/0: [0x3ff800d85a0(0x7a60) @ 0]: x /lib/modules/.../ip6_tables.ko.xz Reported-by: Stefan Liebler <stli@linux.ibm.com> Signed-off-by: Thomas Richter <tmricht@linux.ibm.com> Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Hendrik Brueckner <brueckner@linux.ibm.com> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: stable@vger.kernel.org Fixes: 203d8a4aa6ed ("perf s390: Fix 'start' address of module's map") Link: http://lkml.kernel.org/r/20190724122703.3996-1-tmricht@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/arch/s390/util/machine.c14
-rw-r--r--tools/perf/util/machine.c3
-rw-r--r--tools/perf/util/machine.h2
3 files changed, 16 insertions, 3 deletions
diff --git a/tools/perf/arch/s390/util/machine.c b/tools/perf/arch/s390/util/machine.c
index a19690a17291..de26b1441a48 100644
--- a/tools/perf/arch/s390/util/machine.c
+++ b/tools/perf/arch/s390/util/machine.c
@@ -7,7 +7,7 @@
7#include "api/fs/fs.h" 7#include "api/fs/fs.h"
8#include "debug.h" 8#include "debug.h"
9 9
10int arch__fix_module_text_start(u64 *start, const char *name) 10int arch__fix_module_text_start(u64 *start, u64 *size, const char *name)
11{ 11{
12 u64 m_start = *start; 12 u64 m_start = *start;
13 char path[PATH_MAX]; 13 char path[PATH_MAX];
@@ -17,6 +17,18 @@ int arch__fix_module_text_start(u64 *start, const char *name)
17 if (sysfs__read_ull(path, (unsigned long long *)start) < 0) { 17 if (sysfs__read_ull(path, (unsigned long long *)start) < 0) {
18 pr_debug2("Using module %s start:%#lx\n", path, m_start); 18 pr_debug2("Using module %s start:%#lx\n", path, m_start);
19 *start = m_start; 19 *start = m_start;
20 } else {
21 /* Successful read of the modules segment text start address.
22 * Calculate difference between module start address
23 * in memory and module text segment start address.
24 * For example module load address is 0x3ff8011b000
25 * (from /proc/modules) and module text segment start
26 * address is 0x3ff8011b870 (from file above).
27 *
28 * Adjust the module size and subtract the GOT table
29 * size located at the beginning of the module.
30 */
31 *size -= (*start - m_start);
20 } 32 }
21 33
22 return 0; 34 return 0;
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index cf826eca3aaf..83b2fbbeeb90 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1378,6 +1378,7 @@ static int machine__set_modules_path(struct machine *machine)
1378 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0); 1378 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0);
1379} 1379}
1380int __weak arch__fix_module_text_start(u64 *start __maybe_unused, 1380int __weak arch__fix_module_text_start(u64 *start __maybe_unused,
1381 u64 *size __maybe_unused,
1381 const char *name __maybe_unused) 1382 const char *name __maybe_unused)
1382{ 1383{
1383 return 0; 1384 return 0;
@@ -1389,7 +1390,7 @@ static int machine__create_module(void *arg, const char *name, u64 start,
1389 struct machine *machine = arg; 1390 struct machine *machine = arg;
1390 struct map *map; 1391 struct map *map;
1391 1392
1392 if (arch__fix_module_text_start(&start, name) < 0) 1393 if (arch__fix_module_text_start(&start, &size, name) < 0)
1393 return -1; 1394 return -1;
1394 1395
1395 map = machine__findnew_module_map(machine, start, name); 1396 map = machine__findnew_module_map(machine, start, name);
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index f70ab98a7bde..7aa38da26427 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -222,7 +222,7 @@ struct symbol *machine__find_kernel_symbol_by_name(struct machine *machine,
222 222
223struct map *machine__findnew_module_map(struct machine *machine, u64 start, 223struct map *machine__findnew_module_map(struct machine *machine, u64 start,
224 const char *filename); 224 const char *filename);
225int arch__fix_module_text_start(u64 *start, const char *name); 225int arch__fix_module_text_start(u64 *start, u64 *size, const char *name);
226 226
227int machine__load_kallsyms(struct machine *machine, const char *filename); 227int machine__load_kallsyms(struct machine *machine, const char *filename);
228 228