Commit 212146f0 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
 "A couple of kernel side fixes:

   - Fix the Intel uncore driver on certain hardware configurations

   - Fix a CPU hotplug related memory allocation bug

   - Remove a spurious WARN()

  ... plus also a handful of perf tooling fixes"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf script python: Add Python3 support to tests/attr.py
  perf trace: Support multiple "vfs_getname" probes
  perf symbols: Filter out hidden symbols from labels
  perf symbols: Add fallback definitions for GELF_ST_VISIBILITY()
  tools headers uapi: Sync linux/in.h copy from the kernel sources
  perf clang: Do not use 'return std::move(something)'
  perf mem/c2c: Fix perf_mem_events to support powerpc
  perf tests evsel-tp-sched: Fix bitwise operator
  perf/core: Don't WARN() for impossible ring-buffer sizes
  perf/x86/intel: Delay memory deallocation until x86_pmu_dead_cpu()
  perf/x86/intel/uncore: Add Node ID mask
parents d2a6aae9 3bb26006
...@@ -3558,6 +3558,14 @@ static void free_excl_cntrs(int cpu) ...@@ -3558,6 +3558,14 @@ static void free_excl_cntrs(int cpu)
} }
static void intel_pmu_cpu_dying(int cpu) static void intel_pmu_cpu_dying(int cpu)
{
fini_debug_store_on_cpu(cpu);
if (x86_pmu.counter_freezing)
disable_counter_freeze();
}
static void intel_pmu_cpu_dead(int cpu)
{ {
struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
struct intel_shared_regs *pc; struct intel_shared_regs *pc;
...@@ -3570,11 +3578,6 @@ static void intel_pmu_cpu_dying(int cpu) ...@@ -3570,11 +3578,6 @@ static void intel_pmu_cpu_dying(int cpu)
} }
free_excl_cntrs(cpu); free_excl_cntrs(cpu);
fini_debug_store_on_cpu(cpu);
if (x86_pmu.counter_freezing)
disable_counter_freeze();
} }
static void intel_pmu_sched_task(struct perf_event_context *ctx, static void intel_pmu_sched_task(struct perf_event_context *ctx,
...@@ -3663,6 +3666,7 @@ static __initconst const struct x86_pmu core_pmu = { ...@@ -3663,6 +3666,7 @@ static __initconst const struct x86_pmu core_pmu = {
.cpu_prepare = intel_pmu_cpu_prepare, .cpu_prepare = intel_pmu_cpu_prepare,
.cpu_starting = intel_pmu_cpu_starting, .cpu_starting = intel_pmu_cpu_starting,
.cpu_dying = intel_pmu_cpu_dying, .cpu_dying = intel_pmu_cpu_dying,
.cpu_dead = intel_pmu_cpu_dead,
}; };
static struct attribute *intel_pmu_attrs[]; static struct attribute *intel_pmu_attrs[];
...@@ -3703,6 +3707,8 @@ static __initconst const struct x86_pmu intel_pmu = { ...@@ -3703,6 +3707,8 @@ static __initconst const struct x86_pmu intel_pmu = {
.cpu_prepare = intel_pmu_cpu_prepare, .cpu_prepare = intel_pmu_cpu_prepare,
.cpu_starting = intel_pmu_cpu_starting, .cpu_starting = intel_pmu_cpu_starting,
.cpu_dying = intel_pmu_cpu_dying, .cpu_dying = intel_pmu_cpu_dying,
.cpu_dead = intel_pmu_cpu_dead,
.guest_get_msrs = intel_guest_get_msrs, .guest_get_msrs = intel_guest_get_msrs,
.sched_task = intel_pmu_sched_task, .sched_task = intel_pmu_sched_task,
}; };
......
...@@ -1222,6 +1222,8 @@ static struct pci_driver snbep_uncore_pci_driver = { ...@@ -1222,6 +1222,8 @@ static struct pci_driver snbep_uncore_pci_driver = {
.id_table = snbep_uncore_pci_ids, .id_table = snbep_uncore_pci_ids,
}; };
#define NODE_ID_MASK 0x7
/* /*
* build pci bus to socket mapping * build pci bus to socket mapping
*/ */
...@@ -1243,7 +1245,7 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool ...@@ -1243,7 +1245,7 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool
err = pci_read_config_dword(ubox_dev, nodeid_loc, &config); err = pci_read_config_dword(ubox_dev, nodeid_loc, &config);
if (err) if (err)
break; break;
nodeid = config; nodeid = config & NODE_ID_MASK;
/* get the Node ID mapping */ /* get the Node ID mapping */
err = pci_read_config_dword(ubox_dev, idmap_loc, &config); err = pci_read_config_dword(ubox_dev, idmap_loc, &config);
if (err) if (err)
......
...@@ -734,6 +734,9 @@ struct ring_buffer *rb_alloc(int nr_pages, long watermark, int cpu, int flags) ...@@ -734,6 +734,9 @@ struct ring_buffer *rb_alloc(int nr_pages, long watermark, int cpu, int flags)
size = sizeof(struct ring_buffer); size = sizeof(struct ring_buffer);
size += nr_pages * sizeof(void *); size += nr_pages * sizeof(void *);
if (order_base_2(size) >= MAX_ORDER)
goto fail;
rb = kzalloc(size, GFP_KERNEL); rb = kzalloc(size, GFP_KERNEL);
if (!rb) if (!rb)
goto fail; goto fail;
......
...@@ -268,7 +268,7 @@ struct sockaddr_in { ...@@ -268,7 +268,7 @@ struct sockaddr_in {
#define IN_MULTICAST(a) IN_CLASSD(a) #define IN_MULTICAST(a) IN_CLASSD(a)
#define IN_MULTICAST_NET 0xe0000000 #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_EXPERIMENTAL(a) IN_BADCLASS((a))
#define IN_CLASSE(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000) #define IN_CLASSE(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
......
...@@ -19,8 +19,11 @@ C2C stands for Cache To Cache. ...@@ -19,8 +19,11 @@ C2C stands for Cache To Cache.
The perf c2c tool provides means for Shared Data C2C/HITM analysis. It allows The perf c2c tool provides means for Shared Data C2C/HITM analysis. It allows
you to track down the cacheline contentions. you to track down the cacheline contentions.
The tool is based on x86's load latency and precise store facility events On x86, the tool is based on load latency and precise store facility events
provided by Intel CPUs. These events provide: provided by Intel CPUs. On PowerPC, the tool uses random instruction sampling
with thresholding feature.
These events provide:
- memory address of the access - memory address of the access
- type of the access (load and store details) - type of the access (load and store details)
- latency (in cycles) of the load access - latency (in cycles) of the load access
...@@ -46,7 +49,7 @@ RECORD OPTIONS ...@@ -46,7 +49,7 @@ RECORD OPTIONS
-l:: -l::
--ldlat:: --ldlat::
Configure mem-loads latency. Configure mem-loads latency. (x86 only)
-k:: -k::
--all-kernel:: --all-kernel::
...@@ -119,11 +122,16 @@ Following perf record options are configured by default: ...@@ -119,11 +122,16 @@ Following perf record options are configured by default:
-W,-d,--phys-data,--sample-cpu -W,-d,--phys-data,--sample-cpu
Unless specified otherwise with '-e' option, following events are monitored by Unless specified otherwise with '-e' option, following events are monitored by
default: default on x86:
cpu/mem-loads,ldlat=30/P cpu/mem-loads,ldlat=30/P
cpu/mem-stores/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 User can pass any 'perf record' option behind '--' mark, like (to enable
callchains and system wide monitoring): callchains and system wide monitoring):
......
...@@ -82,7 +82,7 @@ RECORD OPTIONS ...@@ -82,7 +82,7 @@ RECORD OPTIONS
Be more verbose (show counter open errors, etc) Be more verbose (show counter open errors, etc)
--ldlat <n>:: --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 In addition, for report all perf report options are valid, and for record
all perf record options. all perf record options.
......
...@@ -2,6 +2,7 @@ libperf-y += header.o ...@@ -2,6 +2,7 @@ libperf-y += header.o
libperf-y += sym-handling.o libperf-y += sym-handling.o
libperf-y += kvm-stat.o libperf-y += kvm-stat.o
libperf-y += perf_regs.o libperf-y += perf_regs.o
libperf-y += mem-events.o
libperf-$(CONFIG_DWARF) += dwarf-regs.o libperf-$(CONFIG_DWARF) += dwarf-regs.o
libperf-$(CONFIG_DWARF) += skip-callchain-idx.o libperf-$(CONFIG_DWARF) += skip-callchain-idx.o
......
// 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); ...@@ -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) 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; 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); perf_evsel__delete(evsel);
return false;
} }
evsel->handler = trace__vfs_getname; return found;
perf_evlist__add(evlist, evsel);
return true;
} }
static struct perf_evsel *perf_evsel__new_pgfault(u64 config) static struct perf_evsel *perf_evsel__new_pgfault(u64 config)
......
#! /usr/bin/python #! /usr/bin/python
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
from __future__ import print_function
import os import os
import sys import sys
import glob import glob
...@@ -8,7 +10,11 @@ import optparse ...@@ -8,7 +10,11 @@ import optparse
import tempfile import tempfile
import logging import logging
import shutil import shutil
import ConfigParser
try:
import configparser
except ImportError:
import ConfigParser as configparser
def data_equal(a, b): def data_equal(a, b):
# Allow multiple values in assignment separated by '|' # Allow multiple values in assignment separated by '|'
...@@ -100,20 +106,20 @@ class Event(dict): ...@@ -100,20 +106,20 @@ class Event(dict):
def equal(self, other): def equal(self, other):
for t in Event.terms: for t in Event.terms:
log.debug(" [%s] %s %s" % (t, self[t], other[t])); 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 return False
if not data_equal(self[t], other[t]): if not data_equal(self[t], other[t]):
return False return False
return True return True
def optional(self): def optional(self):
if self.has_key('optional') and self['optional'] == '1': if 'optional' in self and self['optional'] == '1':
return True return True
return False return False
def diff(self, other): def diff(self, other):
for t in Event.terms: 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 continue
if not data_equal(self[t], other[t]): if not data_equal(self[t], other[t]):
log.warning("expected %s=%s, got %s" % (t, self[t], other[t])) log.warning("expected %s=%s, got %s" % (t, self[t], other[t]))
...@@ -134,7 +140,7 @@ class Event(dict): ...@@ -134,7 +140,7 @@ class Event(dict):
# - expected values assignments # - expected values assignments
class Test(object): class Test(object):
def __init__(self, path, options): def __init__(self, path, options):
parser = ConfigParser.SafeConfigParser() parser = configparser.SafeConfigParser()
parser.read(path) parser.read(path)
log.warning("running '%s'" % path) log.warning("running '%s'" % path)
...@@ -193,7 +199,7 @@ class Test(object): ...@@ -193,7 +199,7 @@ class Test(object):
return True return True
def load_events(self, path, events): def load_events(self, path, events):
parser_event = ConfigParser.SafeConfigParser() parser_event = configparser.SafeConfigParser()
parser_event.read(path) parser_event.read(path)
# The event record section header contains 'event' word, # The event record section header contains 'event' word,
...@@ -207,7 +213,7 @@ class Test(object): ...@@ -207,7 +213,7 @@ class Test(object):
# Read parent event if there's any # Read parent event if there's any
if (':' in section): if (':' in section):
base = section[section.index(':') + 1:] base = section[section.index(':') + 1:]
parser_base = ConfigParser.SafeConfigParser() parser_base = configparser.SafeConfigParser()
parser_base.read(self.test_dir + '/' + base) parser_base.read(self.test_dir + '/' + base)
base_items = parser_base.items('event') base_items = parser_base.items('event')
...@@ -322,9 +328,9 @@ def run_tests(options): ...@@ -322,9 +328,9 @@ def run_tests(options):
for f in glob.glob(options.test_dir + '/' + options.test): for f in glob.glob(options.test_dir + '/' + options.test):
try: try:
Test(f, options).run() Test(f, options).run()
except Unsup, obj: except Unsup as obj:
log.warning("unsupp %s" % obj.getMsg()) log.warning("unsupp %s" % obj.getMsg())
except Notest, obj: except Notest as obj:
log.warning("skipped %s" % obj.getMsg()) log.warning("skipped %s" % obj.getMsg())
def setup_log(verbose): def setup_log(verbose):
...@@ -363,7 +369,7 @@ def main(): ...@@ -363,7 +369,7 @@ def main():
parser.add_option("-p", "--perf", parser.add_option("-p", "--perf",
action="store", type="string", dest="perf") action="store", type="string", dest="perf")
parser.add_option("-v", "--verbose", parser.add_option("-v", "--verbose",
action="count", dest="verbose") default=0, action="count", dest="verbose")
options, args = parser.parse_args() options, args = parser.parse_args()
if args: if args:
...@@ -373,7 +379,7 @@ def main(): ...@@ -373,7 +379,7 @@ def main():
setup_log(options.verbose) setup_log(options.verbose)
if not options.test_dir: if not options.test_dir:
print 'FAILED no -d option specified' print('FAILED no -d option specified')
sys.exit(-1) sys.exit(-1)
if not options.test: if not options.test:
...@@ -382,8 +388,8 @@ def main(): ...@@ -382,8 +388,8 @@ def main():
try: try:
run_tests(options) run_tests(options)
except Fail, obj: except Fail as obj:
print "FAILED %s" % obj.getMsg(); print("FAILED %s" % obj.getMsg())
sys.exit(-1) sys.exit(-1)
sys.exit(0) sys.exit(0)
......
...@@ -17,7 +17,7 @@ static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name, ...@@ -17,7 +17,7 @@ static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name,
return -1; return -1;
} }
is_signed = !!(field->flags | TEP_FIELD_IS_SIGNED); is_signed = !!(field->flags & TEP_FIELD_IS_SIGNED);
if (should_be_signed && !is_signed) { if (should_be_signed && !is_signed) {
pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n", pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n",
evsel->name, name, is_signed, should_be_signed); evsel->name, name, is_signed, should_be_signed);
......
...@@ -160,7 +160,7 @@ getBPFObjectFromModule(llvm::Module *Module) ...@@ -160,7 +160,7 @@ getBPFObjectFromModule(llvm::Module *Module)
} }
PM.run(*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] = { ...@@ -28,7 +28,7 @@ struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX] = {
static char mem_loads_name[100]; static char mem_loads_name[100];
static bool mem_loads_name__init; 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 (i == PERF_MEM_EVENTS__LOAD) {
if (!mem_loads_name__init) { if (!mem_loads_name__init) {
......
...@@ -19,6 +19,20 @@ ...@@ -19,6 +19,20 @@
#define EM_AARCH64 183 /* ARM 64 bit */ #define EM_AARCH64 183 /* ARM 64 bit */
#endif #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; typedef Elf64_Nhdr GElf_Nhdr;
#ifdef HAVE_CPLUS_DEMANGLE_SUPPORT #ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
...@@ -87,6 +101,11 @@ static inline uint8_t elf_sym__type(const GElf_Sym *sym) ...@@ -87,6 +101,11 @@ static inline uint8_t elf_sym__type(const GElf_Sym *sym)
return GELF_ST_TYPE(sym->st_info); 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 #ifndef STT_GNU_IFUNC
#define STT_GNU_IFUNC 10 #define STT_GNU_IFUNC 10
#endif #endif
...@@ -111,7 +130,9 @@ static inline int elf_sym__is_label(const GElf_Sym *sym) ...@@ -111,7 +130,9 @@ static inline int elf_sym__is_label(const GElf_Sym *sym)
return elf_sym__type(sym) == STT_NOTYPE && return elf_sym__type(sym) == STT_NOTYPE &&
sym->st_name != 0 && sym->st_name != 0 &&
sym->st_shndx != SHN_UNDEF && 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) static bool elf_sym__filter(GElf_Sym *sym)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment