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:
commit
66e5db4a1c
26 changed files with 256 additions and 266 deletions
|
@ -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*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue