perf/core improvements and fixes:

LLVM/clang/eBPF: (Arnaldo Carvalho de Melo)
 
 - Allow passing options to llc in addition to to clang.
 
 Hardware tracing: (Jack Henschel)
 
 - Improve error message for PMU address filters, clarifying availability of
   that feature in hardware having hardware tracing such as Intel PT.
 
 Python interface: (Jiri Olsa)
 
 - Fix read_on_cpu() interface.
 
 ELF/DWARF libraries: (Jiri Olsa)
 
 - Fix handling of the combo compressed module file + decompressed associated
   debuginfo file.
 
 Build (Rasmus Villemoes)
 
 - Disable parallelism for 'make clean', avoiding multiple submakes deleting
   the same files and causing the build to fail on systems such as Yocto.
 
 Kernel ABI copies: (Arnaldo Carvalho de Melo)
 
 - Update tools's copy of x86's cpufeatures.h.
 
 - Update arch/x86/lib/memcpy_64.S copy used in 'perf bench mem memcpy'.
 
 Miscellaneous: (Steven Rostedt)
 
 - Change libtraceevent to SPDX License format.
 
 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEELb9bqkb7Te0zijNb1lAW81NSqkAFAlt6508ACgkQ1lAW81NS
 qkA5Wg//dad6DiIsO4s+6jjBi+egnNxWiE2p2SimkatfeeDlpvdYar2tPf4KX0N8
 PNI/BtqrR6EDwAIzA/Aa2bcfF9p/csLe9jQED2MN86Z28Whl5CikQoKvz+r6RvoA
 tmiO/UPIM6QXPKyNKpEeaeExeIgCtE3feTO8kXfaJVrzrQu4DcfjeT4y6Mc9oBW6
 zkgCODvWswiS+uH4aj5gpHE09nrKVrrz2WilbrEIUY72iWPOviZsGcZXxsm09xxZ
 kHqRaXmqUbKmGn0zqUWwexFxnH1BZ/jvM20mLEmdgp3GHpIDtxVi9BYMJ+1Pp8/i
 6+4Tm3/4Km7pqXU56j9RZgUvNdgy2VcQuEv7d0GBb6RRDgjoJaKXq+Mx9qOnhcNH
 bNkkzm9qGt+vxGbP0cZniEZWsdSxPKvIUbwRwP77qRyXsTx+Wt84bnKRer6Wg5u0
 TbAmt35L4cr7oHJ3ctKkmCVUT98jXCdv5fTstKC/bnx5VQemNeeWeA/vmgv23E3O
 zMINDA2zfarqO8k3vQG2YVMzb+3zIHdcKCQOYP9oEBBtgvVzZyrMUQ2e69UlTvA8
 N8HXdia2fTg78btA4yeEG6VWC17Alkl3Yifei+iUGxc1EflHCGoB/HuEb6iVI/mh
 08aQMUMzZyPoABnzIlK4LJKc6DBiRQhQHwiOmcB1umNlSkbwaB4=
 =2nHb
 -----END PGP SIGNATURE-----

Merge tag 'perf-core-for-mingo-4.19-20180820' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

LLVM/clang/eBPF: (Arnaldo Carvalho de Melo)

 - Allow passing options to llc in addition to to clang.

Hardware tracing: (Jack Henschel)

 - Improve error message for PMU address filters, clarifying availability of
   that feature in hardware having hardware tracing such as Intel PT.

Python interface: (Jiri Olsa)

 - Fix read_on_cpu() interface.

ELF/DWARF libraries: (Jiri Olsa)

 - Fix handling of the combo compressed module file + decompressed associated
   debuginfo file.

Build (Rasmus Villemoes)

 - Disable parallelism for 'make clean', avoiding multiple submakes deleting
   the same files and causing the build to fail on systems such as Yocto.

Kernel ABI copies: (Arnaldo Carvalho de Melo)

 - Update tools's copy of x86's cpufeatures.h.

 - Update arch/x86/lib/memcpy_64.S copy used in 'perf bench mem memcpy'.

Miscellaneous: (Steven Rostedt)

 - Change libtraceevent to SPDX License format.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Ingo Molnar 2018-08-23 10:29:19 +02:00
commit 66e5db4a1c
26 changed files with 256 additions and 266 deletions

View file

@ -219,6 +219,7 @@
#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */
#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */
#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
#define X86_FEATURE_IBRS_ENHANCED ( 7*32+29) /* Enhanced IBRS */
/* Virtualization flags: Linux defined, word 8 */
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
@ -229,7 +230,7 @@
#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer VMMCALL to VMCALL */
#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */
#define X86_FEATURE_EPT_AD ( 8*32+17) /* Intel Extended Page Table access-dirty bit */
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/

View file

@ -256,7 +256,7 @@ ENTRY(__memcpy_mcsafe)
/* Copy successful. Return zero */
.L_done_memcpy_trap:
xorq %rax, %rax
xorl %eax, %eax
ret
ENDPROC(__memcpy_mcsafe)
EXPORT_SYMBOL_GPL(__memcpy_mcsafe)

View file

@ -1,21 +1,7 @@
// SPDX-License-Identifier: LGPL-2.1
/*
* Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License (not later!)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* The parts for function graph printing was taken and modified from the
* Linux Kernel that were written by

View file

@ -1,21 +1,7 @@
// SPDX-License-Identifier: LGPL-2.1
/*
* Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License (not later!)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <ctype.h>

View file

@ -1,21 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1 */
/*
* Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License (not later!)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#ifndef __UTIL_H
#define __UTIL_H

View file

@ -1,22 +1,7 @@
// SPDX-License-Identifier: LGPL-2.1
/*
* Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License (not later!)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <stdio.h>
#include <stdlib.h>

View file

@ -1,21 +1,7 @@
// SPDX-License-Identifier: LGPL-2.1
/*
* Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License (not later!)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <stdio.h>
#include <stdlib.h>

View file

@ -1,21 +1,7 @@
// SPDX-License-Identifier: LGPL-2.1
/*
* Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License (not later!)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <stdio.h>
#include <stdlib.h>

View file

@ -1,21 +1,7 @@
// SPDX-License-Identifier: LGPL-2.1
/*
* Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License (not later!)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <stdio.h>
#include <stdlib.h>

View file

@ -84,10 +84,10 @@ endif # has_clean
endif # MAKECMDGOALS
#
# The clean target is not really parallel, don't print the jobs info:
# Explicitly disable parallelism for the clean target.
#
clean:
$(make)
$(make) -j1
#
# The build-test target is not really parallel, don't print the jobs info,

View file

@ -232,6 +232,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
u64 objdump_addr;
const char *objdump_name;
char decomp_name[KMOD_DECOMP_LEN];
bool decomp = false;
int ret;
pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
@ -305,6 +306,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
return -1;
}
decomp = true;
objdump_name = decomp_name;
}
@ -312,7 +314,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
objdump_addr = map__rip_2objdump(al.map, al.addr);
ret = read_via_objdump(objdump_name, objdump_addr, buf2, len);
if (dso__needs_decompress(al.map->dso))
if (decomp)
unlink(objdump_name);
if (ret > 0) {

View file

@ -5,34 +5,28 @@
#include "dso.h"
#include "debug.h"
static int test(const char *path, bool alloc_name, bool alloc_ext,
bool kmod, bool comp, const char *name, const char *ext)
static int test(const char *path, bool alloc_name, bool kmod,
int comp, const char *name)
{
struct kmod_path m;
memset(&m, 0x0, sizeof(m));
TEST_ASSERT_VAL("kmod_path__parse",
!__kmod_path__parse(&m, path, alloc_name, alloc_ext));
!__kmod_path__parse(&m, path, alloc_name));
pr_debug("%s - alloc name %d, alloc ext %d, kmod %d, comp %d, name '%s', ext '%s'\n",
path, alloc_name, alloc_ext, m.kmod, m.comp, m.name, m.ext);
pr_debug("%s - alloc name %d, kmod %d, comp %d, name '%s'\n",
path, alloc_name, m.kmod, m.comp, m.name);
TEST_ASSERT_VAL("wrong kmod", m.kmod == kmod);
TEST_ASSERT_VAL("wrong comp", m.comp == comp);
if (ext)
TEST_ASSERT_VAL("wrong ext", m.ext && !strcmp(ext, m.ext));
else
TEST_ASSERT_VAL("wrong ext", !m.ext);
if (name)
TEST_ASSERT_VAL("wrong name", m.name && !strcmp(name, m.name));
else
TEST_ASSERT_VAL("wrong name", !m.name);
free(m.name);
free(m.ext);
return 0;
}
@ -45,118 +39,118 @@ static int test_is_kernel_module(const char *path, int cpumode, bool expect)
return 0;
}
#define T(path, an, ae, k, c, n, e) \
TEST_ASSERT_VAL("failed", !test(path, an, ae, k, c, n, e))
#define T(path, an, k, c, n) \
TEST_ASSERT_VAL("failed", !test(path, an, k, c, n))
#define M(path, c, e) \
TEST_ASSERT_VAL("failed", !test_is_kernel_module(path, c, e))
int test__kmod_path__parse(struct test *t __maybe_unused, int subtest __maybe_unused)
{
/* path alloc_name alloc_ext kmod comp name ext */
T("/xxxx/xxxx/x-x.ko", true , true , true, false, "[x_x]", NULL);
T("/xxxx/xxxx/x-x.ko", false , true , true, false, NULL , NULL);
T("/xxxx/xxxx/x-x.ko", true , false , true, false, "[x_x]", NULL);
T("/xxxx/xxxx/x-x.ko", false , false , true, false, NULL , NULL);
/* path alloc_name kmod comp name */
T("/xxxx/xxxx/x-x.ko", true , true, 0 , "[x_x]");
T("/xxxx/xxxx/x-x.ko", false , true, 0 , NULL );
T("/xxxx/xxxx/x-x.ko", true , true, 0 , "[x_x]");
T("/xxxx/xxxx/x-x.ko", false , true, 0 , NULL );
M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_KERNEL, true);
M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_USER, false);
#ifdef HAVE_ZLIB_SUPPORT
/* path alloc_name alloc_ext kmod comp name ext */
T("/xxxx/xxxx/x.ko.gz", true , true , true, true, "[x]", "gz");
T("/xxxx/xxxx/x.ko.gz", false , true , true, true, NULL , "gz");
T("/xxxx/xxxx/x.ko.gz", true , false , true, true, "[x]", NULL);
T("/xxxx/xxxx/x.ko.gz", false , false , true, true, NULL , NULL);
/* path alloc_name kmod comp name */
T("/xxxx/xxxx/x.ko.gz", true , true, 1 , "[x]");
T("/xxxx/xxxx/x.ko.gz", false , true, 1 , NULL );
T("/xxxx/xxxx/x.ko.gz", true , true, 1 , "[x]");
T("/xxxx/xxxx/x.ko.gz", false , true, 1 , NULL );
M("/xxxx/xxxx/x.ko.gz", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
M("/xxxx/xxxx/x.ko.gz", PERF_RECORD_MISC_KERNEL, true);
M("/xxxx/xxxx/x.ko.gz", PERF_RECORD_MISC_USER, false);
/* path alloc_name alloc_ext kmod comp name ext */
T("/xxxx/xxxx/x.gz", true , true , false, true, "x.gz" ,"gz");
T("/xxxx/xxxx/x.gz", false , true , false, true, NULL ,"gz");
T("/xxxx/xxxx/x.gz", true , false , false, true, "x.gz" , NULL);
T("/xxxx/xxxx/x.gz", false , false , false, true, NULL , NULL);
/* path alloc_name kmod comp name */
T("/xxxx/xxxx/x.gz", true , false, 1 , "x.gz");
T("/xxxx/xxxx/x.gz", false , false, 1 , NULL );
T("/xxxx/xxxx/x.gz", true , false, 1 , "x.gz");
T("/xxxx/xxxx/x.gz", false , false, 1 , NULL );
M("/xxxx/xxxx/x.gz", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
M("/xxxx/xxxx/x.gz", PERF_RECORD_MISC_KERNEL, false);
M("/xxxx/xxxx/x.gz", PERF_RECORD_MISC_USER, false);
/* path alloc_name alloc_ext kmod comp name ext */
T("x.gz", true , true , false, true, "x.gz", "gz");
T("x.gz", false , true , false, true, NULL , "gz");
T("x.gz", true , false , false, true, "x.gz", NULL);
T("x.gz", false , false , false, true, NULL , NULL);
/* path alloc_name kmod comp name */
T("x.gz", true , false, 1 , "x.gz");
T("x.gz", false , false, 1 , NULL );
T("x.gz", true , false, 1 , "x.gz");
T("x.gz", false , false, 1 , NULL );
M("x.gz", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
M("x.gz", PERF_RECORD_MISC_KERNEL, false);
M("x.gz", PERF_RECORD_MISC_USER, false);
/* path alloc_name alloc_ext kmod comp name ext */
T("x.ko.gz", true , true , true, true, "[x]", "gz");
T("x.ko.gz", false , true , true, true, NULL , "gz");
T("x.ko.gz", true , false , true, true, "[x]", NULL);
T("x.ko.gz", false , false , true, true, NULL , NULL);
/* path alloc_name kmod comp name */
T("x.ko.gz", true , true, 1 , "[x]");
T("x.ko.gz", false , true, 1 , NULL );
T("x.ko.gz", true , true, 1 , "[x]");
T("x.ko.gz", false , true, 1 , NULL );
M("x.ko.gz", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
M("x.ko.gz", PERF_RECORD_MISC_KERNEL, true);
M("x.ko.gz", PERF_RECORD_MISC_USER, false);
#endif
/* path alloc_name alloc_ext kmod comp name ext */
T("[test_module]", true , true , true, false, "[test_module]", NULL);
T("[test_module]", false , true , true, false, NULL , NULL);
T("[test_module]", true , false , true, false, "[test_module]", NULL);
T("[test_module]", false , false , true, false, NULL , NULL);
/* path alloc_name kmod comp name */
T("[test_module]", true , true, false, "[test_module]");
T("[test_module]", false , true, false, NULL );
T("[test_module]", true , true, false, "[test_module]");
T("[test_module]", false , true, false, NULL );
M("[test_module]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
M("[test_module]", PERF_RECORD_MISC_KERNEL, true);
M("[test_module]", PERF_RECORD_MISC_USER, false);
/* path alloc_name alloc_ext kmod comp name ext */
T("[test.module]", true , true , true, false, "[test.module]", NULL);
T("[test.module]", false , true , true, false, NULL , NULL);
T("[test.module]", true , false , true, false, "[test.module]", NULL);
T("[test.module]", false , false , true, false, NULL , NULL);
/* path alloc_name kmod comp name */
T("[test.module]", true , true, false, "[test.module]");
T("[test.module]", false , true, false, NULL );
T("[test.module]", true , true, false, "[test.module]");
T("[test.module]", false , true, false, NULL );
M("[test.module]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
M("[test.module]", PERF_RECORD_MISC_KERNEL, true);
M("[test.module]", PERF_RECORD_MISC_USER, false);
/* path alloc_name alloc_ext kmod comp name ext */
T("[vdso]", true , true , false, false, "[vdso]", NULL);
T("[vdso]", false , true , false, false, NULL , NULL);
T("[vdso]", true , false , false, false, "[vdso]", NULL);
T("[vdso]", false , false , false, false, NULL , NULL);
/* path alloc_name kmod comp name */
T("[vdso]", true , false, false, "[vdso]");
T("[vdso]", false , false, false, NULL );
T("[vdso]", true , false, false, "[vdso]");
T("[vdso]", false , false, false, NULL );
M("[vdso]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
M("[vdso]", PERF_RECORD_MISC_KERNEL, false);
M("[vdso]", PERF_RECORD_MISC_USER, false);
T("[vdso32]", true , true , false, false, "[vdso32]", NULL);
T("[vdso32]", false , true , false, false, NULL , NULL);
T("[vdso32]", true , false , false, false, "[vdso32]", NULL);
T("[vdso32]", false , false , false, false, NULL , NULL);
T("[vdso32]", true , false, false, "[vdso32]");
T("[vdso32]", false , false, false, NULL );
T("[vdso32]", true , false, false, "[vdso32]");
T("[vdso32]", false , false, false, NULL );
M("[vdso32]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
M("[vdso32]", PERF_RECORD_MISC_KERNEL, false);
M("[vdso32]", PERF_RECORD_MISC_USER, false);
T("[vdsox32]", true , true , false, false, "[vdsox32]", NULL);
T("[vdsox32]", false , true , false, false, NULL , NULL);
T("[vdsox32]", true , false , false, false, "[vdsox32]", NULL);
T("[vdsox32]", false , false , false, false, NULL , NULL);
T("[vdsox32]", true , false, false, "[vdsox32]");
T("[vdsox32]", false , false, false, NULL );
T("[vdsox32]", true , false, false, "[vdsox32]");
T("[vdsox32]", false , false, false, NULL );
M("[vdsox32]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
M("[vdsox32]", PERF_RECORD_MISC_KERNEL, false);
M("[vdsox32]", PERF_RECORD_MISC_USER, false);
/* path alloc_name alloc_ext kmod comp name ext */
T("[vsyscall]", true , true , false, false, "[vsyscall]", NULL);
T("[vsyscall]", false , true , false, false, NULL , NULL);
T("[vsyscall]", true , false , false, false, "[vsyscall]", NULL);
T("[vsyscall]", false , false , false, false, NULL , NULL);
/* path alloc_name kmod comp name */
T("[vsyscall]", true , false, false, "[vsyscall]");
T("[vsyscall]", false , false, false, NULL );
T("[vsyscall]", true , false, false, "[vsyscall]");
T("[vsyscall]", false , false, false, NULL );
M("[vsyscall]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
M("[vsyscall]", PERF_RECORD_MISC_KERNEL, false);
M("[vsyscall]", PERF_RECORD_MISC_USER, false);
/* path alloc_name alloc_ext kmod comp name ext */
T("[kernel.kallsyms]", true , true , false, false, "[kernel.kallsyms]", NULL);
T("[kernel.kallsyms]", false , true , false, false, NULL , NULL);
T("[kernel.kallsyms]", true , false , false, false, "[kernel.kallsyms]", NULL);
T("[kernel.kallsyms]", false , false , false, false, NULL , NULL);
/* path alloc_name kmod comp name */
T("[kernel.kallsyms]", true , false, false, "[kernel.kallsyms]");
T("[kernel.kallsyms]", false , false, false, NULL );
T("[kernel.kallsyms]", true , false, false, "[kernel.kallsyms]");
T("[kernel.kallsyms]", false , false, false, NULL );
M("[kernel.kallsyms]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
M("[kernel.kallsyms]", PERF_RECORD_MISC_KERNEL, false);
M("[kernel.kallsyms]", PERF_RECORD_MISC_USER, false);

View file

@ -1629,6 +1629,7 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
char symfs_filename[PATH_MAX];
struct kcore_extract kce;
bool delete_extract = false;
bool decomp = false;
int stdout_fd[2];
int lineno = 0;
int nline;
@ -1662,6 +1663,7 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
tmp, sizeof(tmp)) < 0)
goto out;
decomp = true;
strcpy(symfs_filename, tmp);
}
@ -1748,7 +1750,7 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
out_remove_tmp:
close(stdout_fd[0]);
if (dso__needs_decompress(dso))
if (decomp)
unlink(symfs_filename);
if (delete_extract)

View file

@ -4,10 +4,12 @@
#ifdef HAVE_ZLIB_SUPPORT
int gzip_decompress_to_file(const char *input, int output_fd);
bool gzip_is_compressed(const char *input);
#endif
#ifdef HAVE_LZMA_SUPPORT
int lzma_decompress_to_file(const char *input, int output_fd);
bool lzma_is_compressed(const char *input);
#endif
#endif /* PERF_COMPRESS_H */

View file

@ -189,28 +189,34 @@ int dso__read_binary_type_filename(const struct dso *dso,
return ret;
}
enum {
COMP_ID__NONE = 0,
};
static const struct {
const char *fmt;
int (*decompress)(const char *input, int output);
bool (*is_compressed)(const char *input);
} compressions[] = {
[COMP_ID__NONE] = { .fmt = NULL, },
#ifdef HAVE_ZLIB_SUPPORT
{ "gz", gzip_decompress_to_file },
{ "gz", gzip_decompress_to_file, gzip_is_compressed },
#endif
#ifdef HAVE_LZMA_SUPPORT
{ "xz", lzma_decompress_to_file },
{ "xz", lzma_decompress_to_file, lzma_is_compressed },
#endif
{ NULL, NULL },
{ NULL, NULL, NULL },
};
bool is_supported_compression(const char *ext)
static int is_supported_compression(const char *ext)
{
unsigned i;
for (i = 0; compressions[i].fmt; i++) {
for (i = 1; compressions[i].fmt; i++) {
if (!strcmp(ext, compressions[i].fmt))
return true;
return i;
}
return false;
return COMP_ID__NONE;
}
bool is_kernel_module(const char *pathname, int cpumode)
@ -239,80 +245,73 @@ bool is_kernel_module(const char *pathname, int cpumode)
return m.kmod;
}
bool decompress_to_file(const char *ext, const char *filename, int output_fd)
{
unsigned i;
for (i = 0; compressions[i].fmt; i++) {
if (!strcmp(ext, compressions[i].fmt))
return !compressions[i].decompress(filename,
output_fd);
}
return false;
}
bool dso__needs_decompress(struct dso *dso)
{
return dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
}
static int decompress_kmodule(struct dso *dso, const char *name, char *tmpbuf)
static int decompress_kmodule(struct dso *dso, const char *name,
char *pathname, size_t len)
{
char tmpbuf[] = KMOD_DECOMP_NAME;
int fd = -1;
struct kmod_path m;
if (!dso__needs_decompress(dso))
return -1;
if (kmod_path__parse_ext(&m, dso->long_name))
if (dso->comp == COMP_ID__NONE)
return -1;
if (!m.comp)
goto out;
/*
* We have proper compression id for DSO and yet the file
* behind the 'name' can still be plain uncompressed object.
*
* The reason is behind the logic we open the DSO object files,
* when we try all possible 'debug' objects until we find the
* data. So even if the DSO is represented by 'krava.xz' module,
* we can end up here opening ~/.debug/....23432432/debug' file
* which is not compressed.
*
* To keep this transparent, we detect this and return the file
* descriptor to the uncompressed file.
*/
if (!compressions[dso->comp].is_compressed(name))
return open(name, O_RDONLY);
fd = mkstemp(tmpbuf);
if (fd < 0) {
dso->load_errno = errno;
goto out;
return -1;
}
if (!decompress_to_file(m.ext, name, fd)) {
if (compressions[dso->comp].decompress(name, fd)) {
dso->load_errno = DSO_LOAD_ERRNO__DECOMPRESSION_FAILURE;
close(fd);
fd = -1;
}
out:
free(m.ext);
if (!pathname || (fd < 0))
unlink(tmpbuf);
if (pathname && (fd >= 0))
strncpy(pathname, tmpbuf, len);
return fd;
}
int dso__decompress_kmodule_fd(struct dso *dso, const char *name)
{
char tmpbuf[] = KMOD_DECOMP_NAME;
int fd;
fd = decompress_kmodule(dso, name, tmpbuf);
unlink(tmpbuf);
return fd;
return decompress_kmodule(dso, name, NULL, 0);
}
int dso__decompress_kmodule_path(struct dso *dso, const char *name,
char *pathname, size_t len)
{
char tmpbuf[] = KMOD_DECOMP_NAME;
int fd;
int fd = decompress_kmodule(dso, name, pathname, len);
fd = decompress_kmodule(dso, name, tmpbuf);
if (fd < 0) {
unlink(tmpbuf);
return -1;
}
strncpy(pathname, tmpbuf, len);
close(fd);
return 0;
return fd >= 0 ? 0 : -1;
}
/*
@ -332,7 +331,7 @@ int dso__decompress_kmodule_path(struct dso *dso, const char *name,
* Returns 0 if there's no strdup error, -ENOMEM otherwise.
*/
int __kmod_path__parse(struct kmod_path *m, const char *path,
bool alloc_name, bool alloc_ext)
bool alloc_name)
{
const char *name = strrchr(path, '/');
const char *ext = strrchr(path, '.');
@ -372,10 +371,9 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
return 0;
}
if (is_supported_compression(ext + 1)) {
m->comp = true;
m->comp = is_supported_compression(ext + 1);
if (m->comp > COMP_ID__NONE)
ext -= 3;
}
/* Check .ko extension only if there's enough name left. */
if (ext > name)
@ -393,14 +391,6 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
strxfrchar(m->name, '-', '_');
}
if (alloc_ext && m->comp) {
m->ext = strdup(ext + 4);
if (!m->ext) {
free((void *) m->name);
return -ENOMEM;
}
}
return 0;
}
@ -413,8 +403,10 @@ void dso__set_module_info(struct dso *dso, struct kmod_path *m,
dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
/* _KMODULE_COMP should be next to _KMODULE */
if (m->kmod && m->comp)
if (m->kmod && m->comp) {
dso->symtab_type++;
dso->comp = m->comp;
}
dso__set_short_name(dso, strdup(m->name), true);
}
@ -468,6 +460,7 @@ static int __open_dso(struct dso *dso, struct machine *machine)
int fd = -EINVAL;
char *root_dir = (char *)"";
char *name = malloc(PATH_MAX);
bool decomp = false;
if (!name)
return -ENOMEM;
@ -491,12 +484,13 @@ static int __open_dso(struct dso *dso, struct machine *machine)
goto out;
}
decomp = true;
strcpy(name, newpath);
}
fd = do_open(name);
if (dso__needs_decompress(dso))
if (decomp)
unlink(name);
out:
@ -1218,6 +1212,7 @@ struct dso *dso__new(const char *name)
dso->a2l_fails = 1;
dso->kernel = DSO_TYPE_USER;
dso->needs_swap = DSO_SWAP__UNSET;
dso->comp = COMP_ID__NONE;
RB_CLEAR_NODE(&dso->rb_node);
dso->root = NULL;
INIT_LIST_HEAD(&dso->node);

View file

@ -175,6 +175,7 @@ struct dso {
u16 short_name_len;
void *dwfl; /* DWARF debug info */
struct auxtrace_cache *auxtrace_cache;
int comp;
/* dso data file */
struct {
@ -250,9 +251,7 @@ int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
char dso__symtab_origin(const struct dso *dso);
int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type,
char *root_dir, char *filename, size_t size);
bool is_supported_compression(const char *ext);
bool is_kernel_module(const char *pathname, int cpumode);
bool decompress_to_file(const char *ext, const char *filename, int output_fd);
bool dso__needs_decompress(struct dso *dso);
int dso__decompress_kmodule_fd(struct dso *dso, const char *name);
int dso__decompress_kmodule_path(struct dso *dso, const char *name,
@ -263,17 +262,15 @@ int dso__decompress_kmodule_path(struct dso *dso, const char *name,
struct kmod_path {
char *name;
char *ext;
bool comp;
int comp;
bool kmod;
};
int __kmod_path__parse(struct kmod_path *m, const char *path,
bool alloc_name, bool alloc_ext);
bool alloc_name);
#define kmod_path__parse(__m, __p) __kmod_path__parse(__m, __p, false, false)
#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
#define kmod_path__parse_ext(__m, __p) __kmod_path__parse(__m, __p, false, true)
#define kmod_path__parse(__m, __p) __kmod_path__parse(__m, __p, false)
#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true)
void dso__set_module_info(struct dso *dso, struct kmod_path *m,
struct machine *machine);

View file

@ -803,7 +803,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
if (*output == -1) {
*output = fd;
if (perf_mmap__mmap(&maps[idx], mp, *output) < 0)
if (perf_mmap__mmap(&maps[idx], mp, *output, evlist_cpu) < 0)
return -1;
} else {
if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)

View file

@ -22,12 +22,14 @@
"$CLANG_OPTIONS $KERNEL_INC_OPTIONS $PERF_BPF_INC_OPTIONS " \
"-Wno-unused-value -Wno-pointer-sign " \
"-working-directory $WORKING_DIR " \
"-c \"$CLANG_SOURCE\" -target bpf -O2 -o -"
"-c \"$CLANG_SOURCE\" -target bpf $CLANG_EMIT_LLVM -O2 -o - $LLVM_OPTIONS_PIPE"
struct llvm_param llvm_param = {
.clang_path = "clang",
.llc_path = "llc",
.clang_bpf_cmd_template = CLANG_BPF_CMD_DEFAULT_TEMPLATE,
.clang_opt = NULL,
.opts = NULL,
.kbuild_dir = NULL,
.kbuild_opts = NULL,
.user_set_param = false,
@ -51,6 +53,8 @@ int perf_llvm_config(const char *var, const char *value)
llvm_param.kbuild_opts = strdup(value);
else if (!strcmp(var, "dump-obj"))
llvm_param.dump_obj = !!perf_config_bool(var, value);
else if (!strcmp(var, "opts"))
llvm_param.opts = strdup(value);
else {
pr_debug("Invalid LLVM config option: %s\n", value);
return -1;
@ -430,11 +434,13 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
unsigned int kernel_version;
char linux_version_code_str[64];
const char *clang_opt = llvm_param.clang_opt;
char clang_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64];
char clang_path[PATH_MAX], llc_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64];
char serr[STRERR_BUFSIZE];
char *kbuild_dir = NULL, *kbuild_include_opts = NULL,
*perf_bpf_include_opts = NULL;
const char *template = llvm_param.clang_bpf_cmd_template;
char *pipe_template = NULL;
const char *opts = llvm_param.opts;
char *command_echo = NULL, *command_out;
char *perf_include_dir = system_path(PERF_INCLUDE_DIR);
@ -484,6 +490,26 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
force_set_env("PERF_BPF_INC_OPTIONS", perf_bpf_include_opts);
force_set_env("WORKING_DIR", kbuild_dir ? : ".");
if (opts) {
err = search_program(llvm_param.llc_path, "llc", llc_path);
if (err) {
pr_err("ERROR:\tunable to find llc.\n"
"Hint:\tTry to install latest clang/llvm to support BPF. Check your $PATH\n"
" \tand 'llc-path' option in [llvm] section of ~/.perfconfig.\n");
version_notice();
goto errout;
}
if (asprintf(&pipe_template, "%s -emit-llvm | %s -march=bpf %s -filetype=obj -o -",
template, llc_path, opts) < 0) {
pr_err("ERROR:\tnot enough memory to setup command line\n");
goto errout;
}
template = pipe_template;
}
/*
* Since we may reset clang's working dir, path of source file
* should be transferred into absolute path, except we want
@ -535,6 +561,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
free(obj_buf);
free(perf_bpf_include_opts);
free(perf_include_dir);
free(pipe_template);
if (p_obj_buf)
*p_obj_buf = NULL;
if (p_obj_buf_sz)

View file

@ -11,6 +11,8 @@
struct llvm_param {
/* Path of clang executable */
const char *clang_path;
/* Path of llc executable */
const char *llc_path;
/*
* Template of clang bpf compiling. 5 env variables
* can be used:
@ -23,6 +25,13 @@ struct llvm_param {
const char *clang_bpf_cmd_template;
/* Will be filled in $CLANG_OPTIONS */
const char *clang_opt;
/*
* If present it'll add -emit-llvm to $CLANG_OPTIONS to pipe
* the clang output to llc, useful for new llvm options not
* yet selectable via 'clang -mllvm option', such as -mattr=dwarfris
* in clang 6.0/llvm 7
*/
const char *opts;
/* Where to find kbuild system */
const char *kbuild_dir;
/*

View file

@ -3,9 +3,13 @@
#include <lzma.h>
#include <stdio.h>
#include <linux/compiler.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "compress.h"
#include "util.h"
#include "debug.h"
#include <unistd.h>
#define BUFSIZE 8192
@ -99,3 +103,19 @@ int lzma_decompress_to_file(const char *input, int output_fd)
fclose(infile);
return err;
}
bool lzma_is_compressed(const char *input)
{
int fd = open(input, O_RDONLY);
const uint8_t magic[6] = { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
char buf[6] = { 0 };
ssize_t rc;
if (fd < 0)
return -1;
rc = read(fd, buf, sizeof(buf));
close(fd);
return rc == sizeof(buf) ?
memcmp(buf, magic, sizeof(buf)) == 0 : false;
}

View file

@ -1212,8 +1212,10 @@ static int map_groups__set_module_path(struct map_groups *mg, const char *path,
* Full name could reveal us kmod compression, so
* we need to update the symtab_type if needed.
*/
if (m->comp && is_kmod_dso(map->dso))
if (m->comp && is_kmod_dso(map->dso)) {
map->dso->symtab_type++;
map->dso->comp = m->comp;
}
return 0;
}

View file

@ -164,7 +164,7 @@ void perf_mmap__munmap(struct perf_mmap *map)
auxtrace_mmap__munmap(&map->auxtrace_mmap);
}
int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd)
int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd, int cpu)
{
/*
* The last one will be done at perf_mmap__consume(), so that we
@ -191,6 +191,7 @@ int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd)
return -1;
}
map->fd = fd;
map->cpu = cpu;
if (auxtrace_mmap__mmap(&map->auxtrace_mmap,
&mp->auxtrace_mp, map->base, fd))

View file

@ -18,6 +18,7 @@ struct perf_mmap {
void *base;
int mask;
int fd;
int cpu;
refcount_t refcnt;
u64 prev;
u64 start;
@ -60,7 +61,7 @@ struct mmap_params {
struct auxtrace_mmap_params auxtrace_mp;
};
int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd);
int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd, int cpu);
void perf_mmap__munmap(struct perf_mmap *map);
void perf_mmap__get(struct perf_mmap *map);

View file

@ -1991,8 +1991,11 @@ static int set_filter(struct perf_evsel *evsel, const void *arg)
int nr_addr_filters = 0;
struct perf_pmu *pmu = NULL;
if (evsel == NULL)
goto err;
if (evsel == NULL) {
fprintf(stderr,
"--filter option should follow a -e tracepoint or HW tracer option\n");
return -1;
}
if (evsel->attr.type == PERF_TYPE_TRACEPOINT) {
if (perf_evsel__append_tp_filter(evsel, str) < 0) {
@ -2014,8 +2017,11 @@ static int set_filter(struct perf_evsel *evsel, const void *arg)
perf_pmu__scan_file(pmu, "nr_addr_filters",
"%d", &nr_addr_filters);
if (!nr_addr_filters)
goto err;
if (!nr_addr_filters) {
fprintf(stderr,
"This CPU does not support address filtering\n");
return -1;
}
if (perf_evsel__append_addr_filter(evsel, str) < 0) {
fprintf(stderr,
@ -2024,12 +2030,6 @@ static int set_filter(struct perf_evsel *evsel, const void *arg)
}
return 0;
err:
fprintf(stderr,
"--filter option should follow a -e tracepoint or HW tracer option\n");
return -1;
}
int parse_filter(const struct option *opt, const char *str,

View file

@ -11,6 +11,7 @@
#include "cpumap.h"
#include "print_binary.h"
#include "thread_map.h"
#include "mmap.h"
#if PY_MAJOR_VERSION < 3
#define _PyUnicode_FromString(arg) \
@ -976,6 +977,20 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
return Py_BuildValue("i", evlist->nr_entries);
}
static struct perf_mmap *get_md(struct perf_evlist *evlist, int cpu)
{
int i;
for (i = 0; i < evlist->nr_mmaps; i++) {
struct perf_mmap *md = &evlist->mmap[i];
if (md->cpu == cpu)
return md;
}
return NULL;
}
static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
PyObject *args, PyObject *kwargs)
{
@ -990,7 +1005,10 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
&cpu, &sample_id_all))
return NULL;
md = &evlist->mmap[cpu];
md = get_md(evlist, cpu);
if (!md)
return NULL;
if (perf_mmap__read_init(md) < 0)
goto end;

View file

@ -5,6 +5,8 @@
#include <sys/stat.h>
#include <sys/mman.h>
#include <zlib.h>
#include <linux/compiler.h>
#include <unistd.h>
#include "util/compress.h"
#include "util/util.h"
@ -79,3 +81,19 @@ int gzip_decompress_to_file(const char *input, int output_fd)
return ret == Z_STREAM_END ? 0 : -1;
}
bool gzip_is_compressed(const char *input)
{
int fd = open(input, O_RDONLY);
const uint8_t magic[2] = { 0x1f, 0x8b };
char buf[2] = { 0 };
ssize_t rc;
if (fd < 0)
return -1;
rc = read(fd, buf, sizeof(buf));
close(fd);
return rc == sizeof(buf) ?
memcmp(buf, magic, sizeof(buf)) == 0 : false;
}