mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 02:50:43 +00:00
perf/urgent fixes:
perf trace: Arnaldo Carvalho de Melo: Fix handling of probe:vfs_getname when the probed routine is inlined in multiple places, fixing the collection of the 'filename' parameter in open syscalls. perf test: Gustavo A. R. Silva: Fix bitwise operator usage in evsel-tp-sched test, which made tat test always detect fields as signed. Jiri Olsa: Filter out hidden symbols from labels, added in systems where the annobin plugin is used, such as RHEL8, which, if left in place make the DWARF unwind 'perf test' to fail on PPC. Tony Jones: Fix 'perf_event_attr' tests when building with python3. perf mem/c2c: Ravi Bangoria: Fix perf_mem_events on PowerPC. tools headers UAPI: Arnaldo Carvalho de Melo: Sync linux/in.h copy from the kernel sources, silencing a perf build warning. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQR2GiIUctdOfX2qHhGyPKLppCJ+JwUCXFml/gAKCRCyPKLppCJ+ J5OJAP9PsD/IdlOmp5qpxgFB8JywLt6fpMLHndgGZYQIQDeNOQEA3fZTrXP30vlD lSOjEnzFT9c9i+57ugYuEmhd7uYrcgw= =n0xs -----END PGP SIGNATURE----- Merge tag 'perf-urgent-for-mingo-5.0-20190205' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent Pull perf/urgent fixes from Arnaldo Carvalho de Melo: perf trace: Arnaldo Carvalho de Melo: Fix handling of probe:vfs_getname when the probed routine is inlined in multiple places, fixing the collection of the 'filename' parameter in open syscalls. perf test: Gustavo A. R. Silva: Fix bitwise operator usage in evsel-tp-sched test, which made tat test always detect fields as signed. Jiri Olsa: Filter out hidden symbols from labels, added in systems where the annobin plugin is used, such as RHEL8, which, if left in place make the DWARF unwind 'perf test' to fail on PPC. Tony Jones: Fix 'perf_event_attr' tests when building with python3. perf mem/c2c: Ravi Bangoria: Fix perf_mem_events on PowerPC. tools headers UAPI: Arnaldo Carvalho de Melo: Sync linux/in.h copy from the kernel sources, silencing a perf build warning. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
3bb2600657
11 changed files with 88 additions and 30 deletions
|
@ -268,7 +268,7 @@ struct sockaddr_in {
|
|||
#define IN_MULTICAST(a) IN_CLASSD(a)
|
||||
#define IN_MULTICAST_NET 0xe0000000
|
||||
|
||||
#define IN_BADCLASS(a) ((((long int) (a) ) == 0xffffffff)
|
||||
#define IN_BADCLASS(a) (((long int) (a) ) == (long int)0xffffffff)
|
||||
#define IN_EXPERIMENTAL(a) IN_BADCLASS((a))
|
||||
|
||||
#define IN_CLASSE(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
|
||||
|
|
|
@ -19,8 +19,11 @@ C2C stands for Cache To Cache.
|
|||
The perf c2c tool provides means for Shared Data C2C/HITM analysis. It allows
|
||||
you to track down the cacheline contentions.
|
||||
|
||||
The tool is based on x86's load latency and precise store facility events
|
||||
provided by Intel CPUs. These events provide:
|
||||
On x86, the tool is based on load latency and precise store facility events
|
||||
provided by Intel CPUs. On PowerPC, the tool uses random instruction sampling
|
||||
with thresholding feature.
|
||||
|
||||
These events provide:
|
||||
- memory address of the access
|
||||
- type of the access (load and store details)
|
||||
- latency (in cycles) of the load access
|
||||
|
@ -46,7 +49,7 @@ RECORD OPTIONS
|
|||
|
||||
-l::
|
||||
--ldlat::
|
||||
Configure mem-loads latency.
|
||||
Configure mem-loads latency. (x86 only)
|
||||
|
||||
-k::
|
||||
--all-kernel::
|
||||
|
@ -119,11 +122,16 @@ Following perf record options are configured by default:
|
|||
-W,-d,--phys-data,--sample-cpu
|
||||
|
||||
Unless specified otherwise with '-e' option, following events are monitored by
|
||||
default:
|
||||
default on x86:
|
||||
|
||||
cpu/mem-loads,ldlat=30/P
|
||||
cpu/mem-stores/P
|
||||
|
||||
and following on PowerPC:
|
||||
|
||||
cpu/mem-loads/
|
||||
cpu/mem-stores/
|
||||
|
||||
User can pass any 'perf record' option behind '--' mark, like (to enable
|
||||
callchains and system wide monitoring):
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ RECORD OPTIONS
|
|||
Be more verbose (show counter open errors, etc)
|
||||
|
||||
--ldlat <n>::
|
||||
Specify desired latency for loads event.
|
||||
Specify desired latency for loads event. (x86 only)
|
||||
|
||||
In addition, for report all perf report options are valid, and for record
|
||||
all perf record options.
|
||||
|
|
|
@ -2,6 +2,7 @@ libperf-y += header.o
|
|||
libperf-y += sym-handling.o
|
||||
libperf-y += kvm-stat.o
|
||||
libperf-y += perf_regs.o
|
||||
libperf-y += mem-events.o
|
||||
|
||||
libperf-$(CONFIG_DWARF) += dwarf-regs.o
|
||||
libperf-$(CONFIG_DWARF) += skip-callchain-idx.o
|
||||
|
|
11
tools/perf/arch/powerpc/util/mem-events.c
Normal file
11
tools/perf/arch/powerpc/util/mem-events.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "mem-events.h"
|
||||
|
||||
/* PowerPC does not support 'ldlat' parameter. */
|
||||
char *perf_mem_events__name(int i)
|
||||
{
|
||||
if (i == PERF_MEM_EVENTS__LOAD)
|
||||
return (char *) "cpu/mem-loads/";
|
||||
|
||||
return (char *) "cpu/mem-stores/";
|
||||
}
|
|
@ -2514,19 +2514,30 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp);
|
|||
|
||||
static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *evsel = perf_evsel__newtp("probe", "vfs_getname");
|
||||
bool found = false;
|
||||
struct perf_evsel *evsel, *tmp;
|
||||
struct parse_events_error err = { .idx = 0, };
|
||||
int ret = parse_events(evlist, "probe:vfs_getname*", &err);
|
||||
|
||||
if (IS_ERR(evsel))
|
||||
if (ret)
|
||||
return false;
|
||||
|
||||
if (perf_evsel__field(evsel, "pathname") == NULL) {
|
||||
evlist__for_each_entry_safe(evlist, evsel, tmp) {
|
||||
if (!strstarts(perf_evsel__name(evsel), "probe:vfs_getname"))
|
||||
continue;
|
||||
|
||||
if (perf_evsel__field(evsel, "pathname")) {
|
||||
evsel->handler = trace__vfs_getname;
|
||||
found = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
list_del_init(&evsel->node);
|
||||
evsel->evlist = NULL;
|
||||
perf_evsel__delete(evsel);
|
||||
return false;
|
||||
}
|
||||
|
||||
evsel->handler = trace__vfs_getname;
|
||||
perf_evlist__add(evlist, evsel);
|
||||
return true;
|
||||
return found;
|
||||
}
|
||||
|
||||
static struct perf_evsel *perf_evsel__new_pgfault(u64 config)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#! /usr/bin/python
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import glob
|
||||
|
@ -8,7 +10,11 @@ import optparse
|
|||
import tempfile
|
||||
import logging
|
||||
import shutil
|
||||
import ConfigParser
|
||||
|
||||
try:
|
||||
import configparser
|
||||
except ImportError:
|
||||
import ConfigParser as configparser
|
||||
|
||||
def data_equal(a, b):
|
||||
# Allow multiple values in assignment separated by '|'
|
||||
|
@ -100,20 +106,20 @@ class Event(dict):
|
|||
def equal(self, other):
|
||||
for t in Event.terms:
|
||||
log.debug(" [%s] %s %s" % (t, self[t], other[t]));
|
||||
if not self.has_key(t) or not other.has_key(t):
|
||||
if t not in self or t not in other:
|
||||
return False
|
||||
if not data_equal(self[t], other[t]):
|
||||
return False
|
||||
return True
|
||||
|
||||
def optional(self):
|
||||
if self.has_key('optional') and self['optional'] == '1':
|
||||
if 'optional' in self and self['optional'] == '1':
|
||||
return True
|
||||
return False
|
||||
|
||||
def diff(self, other):
|
||||
for t in Event.terms:
|
||||
if not self.has_key(t) or not other.has_key(t):
|
||||
if t not in self or t not in other:
|
||||
continue
|
||||
if not data_equal(self[t], other[t]):
|
||||
log.warning("expected %s=%s, got %s" % (t, self[t], other[t]))
|
||||
|
@ -134,7 +140,7 @@ class Event(dict):
|
|||
# - expected values assignments
|
||||
class Test(object):
|
||||
def __init__(self, path, options):
|
||||
parser = ConfigParser.SafeConfigParser()
|
||||
parser = configparser.SafeConfigParser()
|
||||
parser.read(path)
|
||||
|
||||
log.warning("running '%s'" % path)
|
||||
|
@ -193,7 +199,7 @@ class Test(object):
|
|||
return True
|
||||
|
||||
def load_events(self, path, events):
|
||||
parser_event = ConfigParser.SafeConfigParser()
|
||||
parser_event = configparser.SafeConfigParser()
|
||||
parser_event.read(path)
|
||||
|
||||
# The event record section header contains 'event' word,
|
||||
|
@ -207,7 +213,7 @@ class Test(object):
|
|||
# Read parent event if there's any
|
||||
if (':' in section):
|
||||
base = section[section.index(':') + 1:]
|
||||
parser_base = ConfigParser.SafeConfigParser()
|
||||
parser_base = configparser.SafeConfigParser()
|
||||
parser_base.read(self.test_dir + '/' + base)
|
||||
base_items = parser_base.items('event')
|
||||
|
||||
|
@ -322,9 +328,9 @@ def run_tests(options):
|
|||
for f in glob.glob(options.test_dir + '/' + options.test):
|
||||
try:
|
||||
Test(f, options).run()
|
||||
except Unsup, obj:
|
||||
except Unsup as obj:
|
||||
log.warning("unsupp %s" % obj.getMsg())
|
||||
except Notest, obj:
|
||||
except Notest as obj:
|
||||
log.warning("skipped %s" % obj.getMsg())
|
||||
|
||||
def setup_log(verbose):
|
||||
|
@ -363,7 +369,7 @@ def main():
|
|||
parser.add_option("-p", "--perf",
|
||||
action="store", type="string", dest="perf")
|
||||
parser.add_option("-v", "--verbose",
|
||||
action="count", dest="verbose")
|
||||
default=0, action="count", dest="verbose")
|
||||
|
||||
options, args = parser.parse_args()
|
||||
if args:
|
||||
|
@ -373,7 +379,7 @@ def main():
|
|||
setup_log(options.verbose)
|
||||
|
||||
if not options.test_dir:
|
||||
print 'FAILED no -d option specified'
|
||||
print('FAILED no -d option specified')
|
||||
sys.exit(-1)
|
||||
|
||||
if not options.test:
|
||||
|
@ -382,8 +388,8 @@ def main():
|
|||
try:
|
||||
run_tests(options)
|
||||
|
||||
except Fail, obj:
|
||||
print "FAILED %s" % obj.getMsg();
|
||||
except Fail as obj:
|
||||
print("FAILED %s" % obj.getMsg())
|
||||
sys.exit(-1)
|
||||
|
||||
sys.exit(0)
|
||||
|
|
|
@ -17,7 +17,7 @@ static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name,
|
|||
return -1;
|
||||
}
|
||||
|
||||
is_signed = !!(field->flags | TEP_FIELD_IS_SIGNED);
|
||||
is_signed = !!(field->flags & TEP_FIELD_IS_SIGNED);
|
||||
if (should_be_signed && !is_signed) {
|
||||
pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n",
|
||||
evsel->name, name, is_signed, should_be_signed);
|
||||
|
|
|
@ -160,7 +160,7 @@ getBPFObjectFromModule(llvm::Module *Module)
|
|||
}
|
||||
PM.run(*Module);
|
||||
|
||||
return std::move(Buffer);
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX] = {
|
|||
static char mem_loads_name[100];
|
||||
static bool mem_loads_name__init;
|
||||
|
||||
char *perf_mem_events__name(int i)
|
||||
char * __weak perf_mem_events__name(int i)
|
||||
{
|
||||
if (i == PERF_MEM_EVENTS__LOAD) {
|
||||
if (!mem_loads_name__init) {
|
||||
|
|
|
@ -19,6 +19,20 @@
|
|||
#define EM_AARCH64 183 /* ARM 64 bit */
|
||||
#endif
|
||||
|
||||
#ifndef ELF32_ST_VISIBILITY
|
||||
#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
|
||||
#endif
|
||||
|
||||
/* For ELF64 the definitions are the same. */
|
||||
#ifndef ELF64_ST_VISIBILITY
|
||||
#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
|
||||
#endif
|
||||
|
||||
/* How to extract information held in the st_other field. */
|
||||
#ifndef GELF_ST_VISIBILITY
|
||||
#define GELF_ST_VISIBILITY(val) ELF64_ST_VISIBILITY (val)
|
||||
#endif
|
||||
|
||||
typedef Elf64_Nhdr GElf_Nhdr;
|
||||
|
||||
#ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
|
||||
|
@ -87,6 +101,11 @@ static inline uint8_t elf_sym__type(const GElf_Sym *sym)
|
|||
return GELF_ST_TYPE(sym->st_info);
|
||||
}
|
||||
|
||||
static inline uint8_t elf_sym__visibility(const GElf_Sym *sym)
|
||||
{
|
||||
return GELF_ST_VISIBILITY(sym->st_other);
|
||||
}
|
||||
|
||||
#ifndef STT_GNU_IFUNC
|
||||
#define STT_GNU_IFUNC 10
|
||||
#endif
|
||||
|
@ -111,7 +130,9 @@ static inline int elf_sym__is_label(const GElf_Sym *sym)
|
|||
return elf_sym__type(sym) == STT_NOTYPE &&
|
||||
sym->st_name != 0 &&
|
||||
sym->st_shndx != SHN_UNDEF &&
|
||||
sym->st_shndx != SHN_ABS;
|
||||
sym->st_shndx != SHN_ABS &&
|
||||
elf_sym__visibility(sym) != STV_HIDDEN &&
|
||||
elf_sym__visibility(sym) != STV_INTERNAL;
|
||||
}
|
||||
|
||||
static bool elf_sym__filter(GElf_Sym *sym)
|
||||
|
|
Loading…
Reference in a new issue