From: Sasha Levin Date: Mon, 28 Jan 2019 21:27:05 +0000 (-0500) Subject: patches for 4.14 X-Git-Tag: v4.9.154~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3047e0ff67859cd4e6d15876a9596e07a1939b4c;p=thirdparty%2Fkernel%2Fstable-queue.git patches for 4.14 Signed-off-by: Sasha Levin --- diff --git a/queue-4.14/perf-unwind-take-pgoff-into-account-when-reporting-e.patch b/queue-4.14/perf-unwind-take-pgoff-into-account-when-reporting-e.patch new file mode 100644 index 00000000000..33745ba2992 --- /dev/null +++ b/queue-4.14/perf-unwind-take-pgoff-into-account-when-reporting-e.patch @@ -0,0 +1,197 @@ +From 3f3325fba1a83235a9d56e20a0e72c25c85416b3 Mon Sep 17 00:00:00 2001 +From: Milian Wolff +Date: Mon, 29 Oct 2018 15:16:44 +0100 +Subject: perf unwind: Take pgoff into account when reporting elf to libdwfl + +[ Upstream commit 1fe627da30331024f453faef04d500079b901107 ] + +libdwfl parses an ELF file itself and creates mappings for the +individual sections. perf on the other hand sees raw mmap events which +represent individual sections. When we encounter an address pointing +into a mapping with pgoff != 0, we must take that into account and +report the file at the non-offset base address. + +This fixes unwinding with libdwfl in some cases. E.g. for a file like: + +``` + +using namespace std; + +mutex g_mutex; + +double worker() +{ + lock_guard guard(g_mutex); + uniform_real_distribution uniform(-1E5, 1E5); + default_random_engine engine; + double s = 0; + for (int i = 0; i < 1000; ++i) { + s += norm(complex(uniform(engine), uniform(engine))); + } + cout << s << endl; + return s; +} + +int main() +{ + vector> results; + for (int i = 0; i < 10000; ++i) { + results.push_back(async(launch::async, worker)); + } + return 0; +} +``` + +Compile it with `g++ -g -O2 -lpthread cpp-locking.cpp -o cpp-locking`, +then record it with `perf record --call-graph dwarf -e +sched:sched_switch`. + +When you analyze it with `perf script` and libunwind, you should see: + +``` +cpp-locking 20038 [005] 54830.236589: sched:sched_switch: prev_comm=cpp-locking prev_pid=20038 prev_prio=120 prev_state=T ==> next_comm=swapper/5 next_pid=0 next_prio=120 + ffffffffb166fec5 __sched_text_start+0x545 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb166fec5 __sched_text_start+0x545 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb1670208 schedule+0x28 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb16737cc rwsem_down_read_failed+0xec (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb1665e04 call_rwsem_down_read_failed+0x14 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb1672a03 down_read+0x13 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb106bd85 __do_page_fault+0x445 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb18015f5 page_fault+0x45 (/lib/modules/4.14.78-1-lts/build/vmlinux) + 7f38e4252591 new_heap+0x101 (/usr/lib/libc-2.28.so) + 7f38e4252d0b arena_get2.part.4+0x2fb (/usr/lib/libc-2.28.so) + 7f38e4255b1c tcache_init.part.6+0xec (/usr/lib/libc-2.28.so) + 7f38e42569e5 __GI___libc_malloc+0x115 (inlined) + 7f38e4241790 __GI__IO_file_doallocate+0x90 (inlined) + 7f38e424fbbf __GI__IO_doallocbuf+0x4f (inlined) + 7f38e424ee47 __GI__IO_file_overflow+0x197 (inlined) + 7f38e424df36 _IO_new_file_xsputn+0x116 (inlined) + 7f38e4242bfb __GI__IO_fwrite+0xdb (inlined) + 7f38e463fa6d std::basic_streambuf >::sputn(char const*, long)+0x1cd (inlined) + 7f38e463fa6d std::ostreambuf_iterator >::_M_put(char const*, long)+0x1cd (inlined) + 7f38e463fa6d std::ostreambuf_iterator > std::__write(std::ostreambuf_iterator >, char const*, int)+0x1cd (inlined) + 7f38e463fa6d std::ostreambuf_iterator > std::num_put > >::_M_insert_float(std::ostreambuf_iterator + 7f38e464bd70 std::num_put > >::put(std::ostreambuf_iterator >, std::ios_base&, char, double) const+0x90 (inl> + 7f38e464bd70 std::ostream& std::ostream::_M_insert(double)+0x90 (/usr/lib/libstdc++.so.6.0.25) + 563b9cb502f7 std::ostream::operator<<(double)+0xb7 (inlined) + 563b9cb502f7 worker()+0xb7 (/ssd/milian/projects/kdab/rnd/hotspot/build/tests/test-clients/cpp-locking/cpp-locking) + 563b9cb506fb double std::__invoke_impl(std::__invoke_other, double (*&&)())+0x2b (inlined) + 563b9cb506fb std::__invoke_result::type std::__invoke(double (*&&)())+0x2b (inlined) + 563b9cb506fb decltype (__invoke((_S_declval<0ul>)())) std::thread::_Invoker >::_M_invoke<0ul>(std::_Index_tuple<0ul>)+0x2b (inlined) + 563b9cb506fb std::thread::_Invoker >::operator()()+0x2b (inlined) + 563b9cb506fb std::__future_base::_Task_setter, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker >, dou> + 563b9cb506fb std::_Function_handler (), std::__future_base::_Task_setter + 563b9cb507e8 std::function ()>::operator()() const+0x28 (inlined) + 563b9cb507e8 std::__future_base::_State_baseV2::_M_do_set(std::function ()>*, bool*)+0x28 (/ssd/milian/> + 7f38e46d24fe __pthread_once_slow+0xbe (/usr/lib/libpthread-2.28.so) + 563b9cb51149 __gthread_once+0xe9 (inlined) + 563b9cb51149 void std::call_once ()>*, bool*)> + 563b9cb51149 std::__future_base::_State_baseV2::_M_set_result(std::function ()>, bool)+0xe9 (inlined) + 563b9cb51149 std::__future_base::_Async_state_impl >, double>::_Async_state_impl(std::thread::_Invoker >&&)::{lambda()#1}::op> + 563b9cb51149 void std::__invoke_impl >, double>::_Async_state_impl(std::thread::_Invoker + 563b9cb51149 std::__invoke_result >, double>::_Async_state_impl(std::thread::_Invoker >> + 563b9cb51149 decltype (__invoke((_S_declval<0ul>)())) std::thread::_Invoker >, double>::_Async_state_> + 563b9cb51149 std::thread::_Invoker >, double>::_Async_state_impl(std::thread::_Invoker + 563b9cb51149 std::thread::_State_impl >, double>::_Async_state_impl(std::thread> + 7f38e45f0062 execute_native_thread_routine+0x12 (/usr/lib/libstdc++.so.6.0.25) + 7f38e46caa9c start_thread+0xfc (/usr/lib/libpthread-2.28.so) + 7f38e42ccb22 __GI___clone+0x42 (inlined) +``` + +Before this patch, using libdwfl, you would see: + +``` +cpp-locking 20038 [005] 54830.236589: sched:sched_switch: prev_comm=cpp-locking prev_pid=20038 prev_prio=120 prev_state=T ==> next_comm=swapper/5 next_pid=0 next_prio=120 + ffffffffb166fec5 __sched_text_start+0x545 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb166fec5 __sched_text_start+0x545 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb1670208 schedule+0x28 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb16737cc rwsem_down_read_failed+0xec (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb1665e04 call_rwsem_down_read_failed+0x14 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb1672a03 down_read+0x13 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb106bd85 __do_page_fault+0x445 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb18015f5 page_fault+0x45 (/lib/modules/4.14.78-1-lts/build/vmlinux) + 7f38e4252591 new_heap+0x101 (/usr/lib/libc-2.28.so) + a041161e77950c5c [unknown] ([unknown]) +``` + +With this patch applied, we get a bit further in unwinding: + +``` +cpp-locking 20038 [005] 54830.236589: sched:sched_switch: prev_comm=cpp-locking prev_pid=20038 prev_prio=120 prev_state=T ==> next_comm=swapper/5 next_pid=0 next_prio=120 + ffffffffb166fec5 __sched_text_start+0x545 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb166fec5 __sched_text_start+0x545 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb1670208 schedule+0x28 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb16737cc rwsem_down_read_failed+0xec (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb1665e04 call_rwsem_down_read_failed+0x14 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb1672a03 down_read+0x13 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb106bd85 __do_page_fault+0x445 (/lib/modules/4.14.78-1-lts/build/vmlinux) + ffffffffb18015f5 page_fault+0x45 (/lib/modules/4.14.78-1-lts/build/vmlinux) + 7f38e4252591 new_heap+0x101 (/usr/lib/libc-2.28.so) + 7f38e4252d0b arena_get2.part.4+0x2fb (/usr/lib/libc-2.28.so) + 7f38e4255b1c tcache_init.part.6+0xec (/usr/lib/libc-2.28.so) + 7f38e42569e5 __GI___libc_malloc+0x115 (inlined) + 7f38e4241790 __GI__IO_file_doallocate+0x90 (inlined) + 7f38e424fbbf __GI__IO_doallocbuf+0x4f (inlined) + 7f38e424ee47 __GI__IO_file_overflow+0x197 (inlined) + 7f38e424df36 _IO_new_file_xsputn+0x116 (inlined) + 7f38e4242bfb __GI__IO_fwrite+0xdb (inlined) + 7f38e463fa6d std::basic_streambuf >::sputn(char const*, long)+0x1cd (inlined) + 7f38e463fa6d std::ostreambuf_iterator >::_M_put(char const*, long)+0x1cd (inlined) + 7f38e463fa6d std::ostreambuf_iterator > std::__write(std::ostreambuf_iterator >, char const*, int)+0x1cd (inlined) + 7f38e463fa6d std::ostreambuf_iterator > std::num_put > >::_M_insert_float(std::ostreambuf_iterator + 7f38e464bd70 std::num_put > >::put(std::ostreambuf_iterator >, std::ios_base&, char, double) const+0x90 (inl> + 7f38e464bd70 std::ostream& std::ostream::_M_insert(double)+0x90 (/usr/lib/libstdc++.so.6.0.25) + 563b9cb502f7 std::ostream::operator<<(double)+0xb7 (inlined) + 563b9cb502f7 worker()+0xb7 (/ssd/milian/projects/kdab/rnd/hotspot/build/tests/test-clients/cpp-locking/cpp-locking) + 6eab825c1ee3e4ff [unknown] ([unknown]) +``` + +Note that the backtrace is still stopping too early, when compared to +the nice results obtained via libunwind. It's unclear so far what the +reason for that is. + +Committer note: + +Further comment by Milian on the thread started on the Link: tag below: + + --- +The remaining issue is due to a bug in elfutils: + +https://sourceware.org/ml/elfutils-devel/2018-q4/msg00089.html + +With both patches applied, libunwind and elfutils produce the same output for +the above scenario. + --- + +Signed-off-by: Milian Wolff +Acked-by: Jiri Olsa +Link: http://lkml.kernel.org/r/20181029141644.3907-1-milian.wolff@kdab.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/util/unwind-libdw.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c +index 8e969f28cc59..f1fe5acdbba4 100644 +--- a/tools/perf/util/unwind-libdw.c ++++ b/tools/perf/util/unwind-libdw.c +@@ -44,13 +44,13 @@ static int __report_module(struct addr_location *al, u64 ip, + Dwarf_Addr s; + + dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL); +- if (s != al->map->start) ++ if (s != al->map->start - al->map->pgoff) + mod = 0; + } + + if (!mod) + mod = dwfl_report_elf(ui->dwfl, dso->short_name, +- (dso->symsrc_filename ? dso->symsrc_filename : dso->long_name), -1, al->map->start, ++ (dso->symsrc_filename ? dso->symsrc_filename : dso->long_name), -1, al->map->start - al->map->pgoff, + false); + + return mod && dwfl_addrmodule(ui->dwfl, ip) == mod ? 0 : -1; +-- +2.19.1 + diff --git a/queue-4.14/perf-unwind-unwind-with-libdw-doesn-t-take-symfs-int.patch b/queue-4.14/perf-unwind-unwind-with-libdw-doesn-t-take-symfs-int.patch new file mode 100644 index 00000000000..e12889b01a3 --- /dev/null +++ b/queue-4.14/perf-unwind-unwind-with-libdw-doesn-t-take-symfs-int.patch @@ -0,0 +1,42 @@ +From 3dff6cbdc492647bdfc4a064a4ae6285416327c7 Mon Sep 17 00:00:00 2001 +From: Martin Vuille +Date: Sun, 11 Feb 2018 16:24:20 -0500 +Subject: perf unwind: Unwind with libdw doesn't take symfs into account + +[ Upstream commit 3d20c6246690219881786de10d2dda93f616d0ac ] + +Path passed to libdw for unwinding doesn't include symfs path +if specified, so unwinding fails because ELF file is not found. + +Similar to unwinding with libunwind, pass symsrc_filename instead +of long_name. If there is no symsrc_filename, fallback to long_name. + +Signed-off-by: Martin Vuille +Cc: Adrian Hunter +Cc: David Ahern +Cc: Jiri Olsa +Cc: Namhyung Kim +Cc: Wang Nan +Link: http://lkml.kernel.org/r/20180211212420.18388-1-jpmv27@aim.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/util/unwind-libdw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c +index 1e9c974faf67..8e969f28cc59 100644 +--- a/tools/perf/util/unwind-libdw.c ++++ b/tools/perf/util/unwind-libdw.c +@@ -50,7 +50,7 @@ static int __report_module(struct addr_location *al, u64 ip, + + if (!mod) + mod = dwfl_report_elf(ui->dwfl, dso->short_name, +- dso->long_name, -1, al->map->start, ++ (dso->symsrc_filename ? dso->symsrc_filename : dso->long_name), -1, al->map->start, + false); + + return mod && dwfl_addrmodule(ui->dwfl, ip) == mod ? 0 : -1; +-- +2.19.1 + diff --git a/queue-4.14/revert-seccomp-add-a-selftest-for-get_metadata.patch b/queue-4.14/revert-seccomp-add-a-selftest-for-get_metadata.patch new file mode 100644 index 00000000000..48a53a899b7 --- /dev/null +++ b/queue-4.14/revert-seccomp-add-a-selftest-for-get_metadata.patch @@ -0,0 +1,108 @@ +From 068966cd0a774e6336ddb5424dd65341320b488b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Jan 2019 14:40:49 -0500 +Subject: Revert "seccomp: add a selftest for get_metadata" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reverts commit e65cd9a20343ea90f576c24c38ee85ab6e7d5fec. + +Tommi T. Rrantala notes: + + PTRACE_SECCOMP_GET_METADATA was only added in 4.16 + (26500475ac1b499d8636ff281311d633909f5d20) + + And it's also breaking seccomp_bpf.c compilation for me: + + seccomp_bpf.c: In function ‘get_metadata’: + seccomp_bpf.c:2878:26: error: storage size of ‘md’ isn’t known + struct seccomp_metadata md; + +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/seccomp/seccomp_bpf.c | 61 ------------------- + 1 file changed, 61 deletions(-) + +diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c +index e350cf3d4f90..194759ec9e70 100644 +--- a/tools/testing/selftests/seccomp/seccomp_bpf.c ++++ b/tools/testing/selftests/seccomp/seccomp_bpf.c +@@ -145,15 +145,6 @@ struct seccomp_data { + #define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2) + #endif + +-#ifndef PTRACE_SECCOMP_GET_METADATA +-#define PTRACE_SECCOMP_GET_METADATA 0x420d +- +-struct seccomp_metadata { +- __u64 filter_off; /* Input: which filter */ +- __u64 flags; /* Output: filter's flags */ +-}; +-#endif +- + #ifndef seccomp + int seccomp(unsigned int op, unsigned int flags, void *args) + { +@@ -2870,58 +2861,6 @@ TEST(get_action_avail) + EXPECT_EQ(errno, EOPNOTSUPP); + } + +-TEST(get_metadata) +-{ +- pid_t pid; +- int pipefd[2]; +- char buf; +- struct seccomp_metadata md; +- +- ASSERT_EQ(0, pipe(pipefd)); +- +- pid = fork(); +- ASSERT_GE(pid, 0); +- if (pid == 0) { +- struct sock_filter filter[] = { +- BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), +- }; +- struct sock_fprog prog = { +- .len = (unsigned short)ARRAY_SIZE(filter), +- .filter = filter, +- }; +- +- /* one with log, one without */ +- ASSERT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER, +- SECCOMP_FILTER_FLAG_LOG, &prog)); +- ASSERT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog)); +- +- ASSERT_EQ(0, close(pipefd[0])); +- ASSERT_EQ(1, write(pipefd[1], "1", 1)); +- ASSERT_EQ(0, close(pipefd[1])); +- +- while (1) +- sleep(100); +- } +- +- ASSERT_EQ(0, close(pipefd[1])); +- ASSERT_EQ(1, read(pipefd[0], &buf, 1)); +- +- ASSERT_EQ(0, ptrace(PTRACE_ATTACH, pid)); +- ASSERT_EQ(pid, waitpid(pid, NULL, 0)); +- +- md.filter_off = 0; +- ASSERT_EQ(sizeof(md), ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md)); +- EXPECT_EQ(md.flags, SECCOMP_FILTER_FLAG_LOG); +- EXPECT_EQ(md.filter_off, 0); +- +- md.filter_off = 1; +- ASSERT_EQ(sizeof(md), ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md)); +- EXPECT_EQ(md.flags, 0); +- EXPECT_EQ(md.filter_off, 1); +- +- ASSERT_EQ(0, kill(pid, SIGKILL)); +-} +- + /* + * TODO: + * - add microbenchmarks +-- +2.19.1 + diff --git a/queue-4.14/series b/queue-4.14/series index 2052ca27afc..fab0a976a8b 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -47,3 +47,6 @@ irqchip-gic-v3-its-align-pci-multi-msi-allocation-on-their-size.patch can-dev-__can_get_echo_skb-fix-bogous-check-for-non-existing-skb-by-removing-it.patch can-bcm-check-timer-values-before-ktime-conversion.patch vt-invoke-notifier-on-screen-size-change.patch +perf-unwind-unwind-with-libdw-doesn-t-take-symfs-int.patch +perf-unwind-take-pgoff-into-account-when-reporting-e.patch +revert-seccomp-add-a-selftest-for-get_metadata.patch