Commit d7d53886 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:
 "Tooling fixes mostly, plus a build warning fix"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (21 commits)
  perf/core: Move inline keyword at the beginning of declaration
  tools/headers: Pick up latest kernel ABIs
  perf tools: Fix crash caused by accessing feat_ops[HEADER_LAST_FEATURE]
  perf script: Fix crash because of missing evsel->priv
  perf script: Add missing output fields in a hint
  perf bench: Fix numa report output code
  perf stat: Remove duplicate event counting
  perf alias: Rebuild alias expression string to make it comparable
  perf alias: Remove trailing newline when reading sysfs files
  perf tools: Fix a clang 7.0 compilation error
  tools include uapi: Synchronize bpf.h with the kernel
  tools include uapi: Update if_link.h to pick IFLA_{BRPORT_ISOLATED,VXLAN_TTL_INHERIT}
  tools include powerpc: Update arch/powerpc/include/uapi/asm/unistd.h copy to get 'rseq' syscall
  perf tools: Update x86's syscall_64.tbl, adding 'io_pgetevents' and 'rseq'
  tools headers uapi: Synchronize drm/drm.h
  perf intel-pt: Fix packet decoding of CYC packets
  perf tests: Add valid callback for parse-events test
  perf tests: Add event parsing error handling to parse events test
  perf report powerpc: Fix crash if callchain is empty
  perf test session topology: Fix test on s390
  ...
parents 34a484d5 93315101
...@@ -6482,7 +6482,7 @@ void perf_prepare_sample(struct perf_event_header *header, ...@@ -6482,7 +6482,7 @@ void perf_prepare_sample(struct perf_event_header *header,
data->phys_addr = perf_virt_to_phys(data->addr); data->phys_addr = perf_virt_to_phys(data->addr);
} }
static void __always_inline static __always_inline void
__perf_event_output(struct perf_event *event, __perf_event_output(struct perf_event *event,
struct perf_sample_data *data, struct perf_sample_data *data,
struct pt_regs *regs, struct pt_regs *regs,
......
...@@ -91,6 +91,7 @@ struct kvm_regs { ...@@ -91,6 +91,7 @@ struct kvm_regs {
#define KVM_VGIC_V3_ADDR_TYPE_DIST 2 #define KVM_VGIC_V3_ADDR_TYPE_DIST 2
#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3 #define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
#define KVM_VGIC_ITS_ADDR_TYPE 4 #define KVM_VGIC_ITS_ADDR_TYPE 4
#define KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION 5
#define KVM_VGIC_V3_DIST_SIZE SZ_64K #define KVM_VGIC_V3_DIST_SIZE SZ_64K
#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K) #define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
......
...@@ -91,6 +91,7 @@ struct kvm_regs { ...@@ -91,6 +91,7 @@ struct kvm_regs {
#define KVM_VGIC_V3_ADDR_TYPE_DIST 2 #define KVM_VGIC_V3_ADDR_TYPE_DIST 2
#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3 #define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
#define KVM_VGIC_ITS_ADDR_TYPE 4 #define KVM_VGIC_ITS_ADDR_TYPE 4
#define KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION 5
#define KVM_VGIC_V3_DIST_SIZE SZ_64K #define KVM_VGIC_V3_DIST_SIZE SZ_64K
#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K) #define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
......
...@@ -633,6 +633,7 @@ struct kvm_ppc_cpu_char { ...@@ -633,6 +633,7 @@ struct kvm_ppc_cpu_char {
#define KVM_REG_PPC_PSSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd) #define KVM_REG_PPC_PSSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd)
#define KVM_REG_PPC_DEC_EXPIRY (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbe) #define KVM_REG_PPC_DEC_EXPIRY (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbe)
#define KVM_REG_PPC_ONLINE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbf)
/* Transactional Memory checkpointed state: /* Transactional Memory checkpointed state:
* This is all GPRs, all VSX regs and a subset of SPRs * This is all GPRs, all VSX regs and a subset of SPRs
......
...@@ -398,5 +398,6 @@ ...@@ -398,5 +398,6 @@
#define __NR_pkey_alloc 384 #define __NR_pkey_alloc 384
#define __NR_pkey_free 385 #define __NR_pkey_free 385
#define __NR_pkey_mprotect 386 #define __NR_pkey_mprotect 386
#define __NR_rseq 387
#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
...@@ -282,7 +282,9 @@ ...@@ -282,7 +282,9 @@
#define X86_FEATURE_AMD_IBPB (13*32+12) /* "" Indirect Branch Prediction Barrier */ #define X86_FEATURE_AMD_IBPB (13*32+12) /* "" Indirect Branch Prediction Barrier */
#define X86_FEATURE_AMD_IBRS (13*32+14) /* "" Indirect Branch Restricted Speculation */ #define X86_FEATURE_AMD_IBRS (13*32+14) /* "" Indirect Branch Restricted Speculation */
#define X86_FEATURE_AMD_STIBP (13*32+15) /* "" Single Thread Indirect Branch Predictors */ #define X86_FEATURE_AMD_STIBP (13*32+15) /* "" Single Thread Indirect Branch Predictors */
#define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */
#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
#define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
......
...@@ -680,6 +680,13 @@ struct drm_get_cap { ...@@ -680,6 +680,13 @@ struct drm_get_cap {
*/ */
#define DRM_CLIENT_CAP_ATOMIC 3 #define DRM_CLIENT_CAP_ATOMIC 3
/**
* DRM_CLIENT_CAP_ASPECT_RATIO
*
* If set to 1, the DRM core will provide aspect ratio information in modes.
*/
#define DRM_CLIENT_CAP_ASPECT_RATIO 4
/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
struct drm_set_client_cap { struct drm_set_client_cap {
__u64 capability; __u64 capability;
......
...@@ -2630,7 +2630,7 @@ struct bpf_fib_lookup { ...@@ -2630,7 +2630,7 @@ struct bpf_fib_lookup {
union { union {
/* inputs to lookup */ /* inputs to lookup */
__u8 tos; /* AF_INET */ __u8 tos; /* AF_INET */
__be32 flowlabel; /* AF_INET6 */ __be32 flowinfo; /* AF_INET6, flow_label + priority */
/* output: metric of fib result (IPv4/IPv6 only) */ /* output: metric of fib result (IPv4/IPv6 only) */
__u32 rt_metric; __u32 rt_metric;
......
...@@ -333,6 +333,7 @@ enum { ...@@ -333,6 +333,7 @@ enum {
IFLA_BRPORT_BCAST_FLOOD, IFLA_BRPORT_BCAST_FLOOD,
IFLA_BRPORT_GROUP_FWD_MASK, IFLA_BRPORT_GROUP_FWD_MASK,
IFLA_BRPORT_NEIGH_SUPPRESS, IFLA_BRPORT_NEIGH_SUPPRESS,
IFLA_BRPORT_ISOLATED,
__IFLA_BRPORT_MAX __IFLA_BRPORT_MAX
}; };
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
...@@ -516,6 +517,7 @@ enum { ...@@ -516,6 +517,7 @@ enum {
IFLA_VXLAN_COLLECT_METADATA, IFLA_VXLAN_COLLECT_METADATA,
IFLA_VXLAN_LABEL, IFLA_VXLAN_LABEL,
IFLA_VXLAN_GPE, IFLA_VXLAN_GPE,
IFLA_VXLAN_TTL_INHERIT,
__IFLA_VXLAN_MAX __IFLA_VXLAN_MAX
}; };
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
......
...@@ -948,6 +948,7 @@ struct kvm_ppc_resize_hpt { ...@@ -948,6 +948,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_S390_BPB 152 #define KVM_CAP_S390_BPB 152
#define KVM_CAP_GET_MSR_FEATURES 153 #define KVM_CAP_GET_MSR_FEATURES 153
#define KVM_CAP_HYPERV_EVENTFD 154 #define KVM_CAP_HYPERV_EVENTFD 154
#define KVM_CAP_HYPERV_TLBFLUSH 155
#ifdef KVM_CAP_IRQ_ROUTING #ifdef KVM_CAP_IRQ_ROUTING
......
...@@ -243,7 +243,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain) ...@@ -243,7 +243,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain)
u64 ip; u64 ip;
u64 skip_slot = -1; u64 skip_slot = -1;
if (chain->nr < 3) if (!chain || chain->nr < 3)
return skip_slot; return skip_slot;
ip = chain->ips[2]; ip = chain->ips[2];
......
...@@ -341,6 +341,8 @@ ...@@ -341,6 +341,8 @@
330 common pkey_alloc __x64_sys_pkey_alloc 330 common pkey_alloc __x64_sys_pkey_alloc
331 common pkey_free __x64_sys_pkey_free 331 common pkey_free __x64_sys_pkey_free
332 common statx __x64_sys_statx 332 common statx __x64_sys_statx
333 common io_pgetevents __x64_sys_io_pgetevents
334 common rseq __x64_sys_rseq
# #
# x32-specific system call numbers start at 512 to avoid cache impact # x32-specific system call numbers start at 512 to avoid cache impact
......
...@@ -1098,7 +1098,7 @@ static void *worker_thread(void *__tdata) ...@@ -1098,7 +1098,7 @@ static void *worker_thread(void *__tdata)
u8 *global_data; u8 *global_data;
u8 *process_data; u8 *process_data;
u8 *thread_data; u8 *thread_data;
u64 bytes_done; u64 bytes_done, secs;
long work_done; long work_done;
u32 l; u32 l;
struct rusage rusage; struct rusage rusage;
...@@ -1254,7 +1254,8 @@ static void *worker_thread(void *__tdata) ...@@ -1254,7 +1254,8 @@ static void *worker_thread(void *__tdata)
timersub(&stop, &start0, &diff); timersub(&stop, &start0, &diff);
td->runtime_ns = diff.tv_sec * NSEC_PER_SEC; td->runtime_ns = diff.tv_sec * NSEC_PER_SEC;
td->runtime_ns += diff.tv_usec * NSEC_PER_USEC; td->runtime_ns += diff.tv_usec * NSEC_PER_USEC;
td->speed_gbs = bytes_done / (td->runtime_ns / NSEC_PER_SEC) / 1e9; secs = td->runtime_ns / NSEC_PER_SEC;
td->speed_gbs = secs ? bytes_done / secs / 1e9 : 0;
getrusage(RUSAGE_THREAD, &rusage); getrusage(RUSAGE_THREAD, &rusage);
td->system_time_ns = rusage.ru_stime.tv_sec * NSEC_PER_SEC; td->system_time_ns = rusage.ru_stime.tv_sec * NSEC_PER_SEC;
......
...@@ -283,6 +283,15 @@ static int process_sample_event(struct perf_tool *tool, ...@@ -283,6 +283,15 @@ static int process_sample_event(struct perf_tool *tool,
return ret; return ret;
} }
static int process_feature_event(struct perf_tool *tool,
union perf_event *event,
struct perf_session *session)
{
if (event->feat.feat_id < HEADER_LAST_FEATURE)
return perf_event__process_feature(tool, event, session);
return 0;
}
static int hist_entry__tty_annotate(struct hist_entry *he, static int hist_entry__tty_annotate(struct hist_entry *he,
struct perf_evsel *evsel, struct perf_evsel *evsel,
struct perf_annotate *ann) struct perf_annotate *ann)
...@@ -471,7 +480,7 @@ int cmd_annotate(int argc, const char **argv) ...@@ -471,7 +480,7 @@ int cmd_annotate(int argc, const char **argv)
.attr = perf_event__process_attr, .attr = perf_event__process_attr,
.build_id = perf_event__process_build_id, .build_id = perf_event__process_build_id,
.tracing_data = perf_event__process_tracing_data, .tracing_data = perf_event__process_tracing_data,
.feature = perf_event__process_feature, .feature = process_feature_event,
.ordered_events = true, .ordered_events = true,
.ordering_requires_timestamps = true, .ordering_requires_timestamps = true,
}, },
......
...@@ -217,7 +217,8 @@ static int process_feature_event(struct perf_tool *tool, ...@@ -217,7 +217,8 @@ static int process_feature_event(struct perf_tool *tool,
} }
/* /*
* All features are received, we can force the * (feat_id = HEADER_LAST_FEATURE) is the end marker which
* means all features are received, now we can force the
* group if needed. * group if needed.
*/ */
setup_forced_leader(rep, session->evlist); setup_forced_leader(rep, session->evlist);
......
...@@ -1834,6 +1834,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, ...@@ -1834,6 +1834,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
struct perf_evlist *evlist; struct perf_evlist *evlist;
struct perf_evsel *evsel, *pos; struct perf_evsel *evsel, *pos;
int err; int err;
static struct perf_evsel_script *es;
err = perf_event__process_attr(tool, event, pevlist); err = perf_event__process_attr(tool, event, pevlist);
if (err) if (err)
...@@ -1842,6 +1843,19 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, ...@@ -1842,6 +1843,19 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
evlist = *pevlist; evlist = *pevlist;
evsel = perf_evlist__last(*pevlist); evsel = perf_evlist__last(*pevlist);
if (!evsel->priv) {
if (scr->per_event_dump) {
evsel->priv = perf_evsel_script__new(evsel,
scr->session->data);
} else {
es = zalloc(sizeof(*es));
if (!es)
return -ENOMEM;
es->fp = stdout;
evsel->priv = es;
}
}
if (evsel->attr.type >= PERF_TYPE_MAX && if (evsel->attr.type >= PERF_TYPE_MAX &&
evsel->attr.type != PERF_TYPE_SYNTH) evsel->attr.type != PERF_TYPE_SYNTH)
return 0; return 0;
...@@ -3030,6 +3044,15 @@ int process_cpu_map_event(struct perf_tool *tool __maybe_unused, ...@@ -3030,6 +3044,15 @@ int process_cpu_map_event(struct perf_tool *tool __maybe_unused,
return set_maps(script); return set_maps(script);
} }
static int process_feature_event(struct perf_tool *tool,
union perf_event *event,
struct perf_session *session)
{
if (event->feat.feat_id < HEADER_LAST_FEATURE)
return perf_event__process_feature(tool, event, session);
return 0;
}
#ifdef HAVE_AUXTRACE_SUPPORT #ifdef HAVE_AUXTRACE_SUPPORT
static int perf_script__process_auxtrace_info(struct perf_tool *tool, static int perf_script__process_auxtrace_info(struct perf_tool *tool,
union perf_event *event, union perf_event *event,
...@@ -3074,7 +3097,7 @@ int cmd_script(int argc, const char **argv) ...@@ -3074,7 +3097,7 @@ int cmd_script(int argc, const char **argv)
.attr = process_attr, .attr = process_attr,
.event_update = perf_event__process_event_update, .event_update = perf_event__process_event_update,
.tracing_data = perf_event__process_tracing_data, .tracing_data = perf_event__process_tracing_data,
.feature = perf_event__process_feature, .feature = process_feature_event,
.build_id = perf_event__process_build_id, .build_id = perf_event__process_build_id,
.id_index = perf_event__process_id_index, .id_index = perf_event__process_id_index,
.auxtrace_info = perf_script__process_auxtrace_info, .auxtrace_info = perf_script__process_auxtrace_info,
...@@ -3125,8 +3148,9 @@ int cmd_script(int argc, const char **argv) ...@@ -3125,8 +3148,9 @@ int cmd_script(int argc, const char **argv)
"+field to add and -field to remove." "+field to add and -field to remove."
"Valid types: hw,sw,trace,raw,synth. " "Valid types: hw,sw,trace,raw,synth. "
"Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
"addr,symoff,period,iregs,uregs,brstack,brstacksym,flags," "addr,symoff,srcline,period,iregs,uregs,brstack,"
"bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr", "brstacksym,flags,bpf-output,brstackinsn,brstackoff,"
"callindent,insn,insnlen,synth,phys_addr,metric,misc",
parse_output_fields), parse_output_fields),
OPT_BOOLEAN('a', "all-cpus", &system_wide, OPT_BOOLEAN('a', "all-cpus", &system_wide,
"system-wide collection from all CPUs"), "system-wide collection from all CPUs"),
......
...@@ -1309,6 +1309,11 @@ static int test__checkevent_config_cache(struct perf_evlist *evlist) ...@@ -1309,6 +1309,11 @@ static int test__checkevent_config_cache(struct perf_evlist *evlist)
return 0; return 0;
} }
static bool test__intel_pt_valid(void)
{
return !!perf_pmu__find("intel_pt");
}
static int test__intel_pt(struct perf_evlist *evlist) static int test__intel_pt(struct perf_evlist *evlist)
{ {
struct perf_evsel *evsel = perf_evlist__first(evlist); struct perf_evsel *evsel = perf_evlist__first(evlist);
...@@ -1375,6 +1380,7 @@ struct evlist_test { ...@@ -1375,6 +1380,7 @@ struct evlist_test {
const char *name; const char *name;
__u32 type; __u32 type;
const int id; const int id;
bool (*valid)(void);
int (*check)(struct perf_evlist *evlist); int (*check)(struct perf_evlist *evlist);
}; };
...@@ -1648,6 +1654,7 @@ static struct evlist_test test__events[] = { ...@@ -1648,6 +1654,7 @@ static struct evlist_test test__events[] = {
}, },
{ {
.name = "intel_pt//u", .name = "intel_pt//u",
.valid = test__intel_pt_valid,
.check = test__intel_pt, .check = test__intel_pt,
.id = 52, .id = 52,
}, },
...@@ -1686,17 +1693,24 @@ static struct terms_test test__terms[] = { ...@@ -1686,17 +1693,24 @@ static struct terms_test test__terms[] = {
static int test_event(struct evlist_test *e) static int test_event(struct evlist_test *e)
{ {
struct parse_events_error err = { .idx = 0, };
struct perf_evlist *evlist; struct perf_evlist *evlist;
int ret; int ret;
if (e->valid && !e->valid()) {
pr_debug("... SKIP");
return 0;
}
evlist = perf_evlist__new(); evlist = perf_evlist__new();
if (evlist == NULL) if (evlist == NULL)
return -ENOMEM; return -ENOMEM;
ret = parse_events(evlist, e->name, NULL); ret = parse_events(evlist, e->name, &err);
if (ret) { if (ret) {
pr_debug("failed to parse event '%s', err %d\n", pr_debug("failed to parse event '%s', err %d, str '%s'\n",
e->name, ret); e->name, ret, err.str);
parse_events_print_error(&err, e->name);
} else { } else {
ret = e->check(evlist); ret = e->check(evlist);
} }
...@@ -1714,10 +1728,11 @@ static int test_events(struct evlist_test *events, unsigned cnt) ...@@ -1714,10 +1728,11 @@ static int test_events(struct evlist_test *events, unsigned cnt)
for (i = 0; i < cnt; i++) { for (i = 0; i < cnt; i++) {
struct evlist_test *e = &events[i]; struct evlist_test *e = &events[i];
pr_debug("running test %d '%s'\n", e->id, e->name); pr_debug("running test %d '%s'", e->id, e->name);
ret1 = test_event(e); ret1 = test_event(e);
if (ret1) if (ret1)
ret2 = ret1; ret2 = ret1;
pr_debug("\n");
} }
return ret2; return ret2;
...@@ -1799,7 +1814,7 @@ static int test_pmu_events(void) ...@@ -1799,7 +1814,7 @@ static int test_pmu_events(void)
} }
while (!ret && (ent = readdir(dir))) { while (!ret && (ent = readdir(dir))) {
struct evlist_test e; struct evlist_test e = { .id = 0, };
char name[2 * NAME_MAX + 1 + 12 + 3]; char name[2 * NAME_MAX + 1 + 12 + 3];
/* Names containing . are special and cannot be used directly */ /* Names containing . are special and cannot be used directly */
......
...@@ -45,6 +45,7 @@ static int session_write_header(char *path) ...@@ -45,6 +45,7 @@ static int session_write_header(char *path)
perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY); perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY);
perf_header__set_feat(&session->header, HEADER_NRCPUS); perf_header__set_feat(&session->header, HEADER_NRCPUS);
perf_header__set_feat(&session->header, HEADER_ARCH);
session->header.data_size += DATA_SIZE; session->header.data_size += DATA_SIZE;
......
...@@ -146,8 +146,15 @@ getBPFObjectFromModule(llvm::Module *Module) ...@@ -146,8 +146,15 @@ getBPFObjectFromModule(llvm::Module *Module)
raw_svector_ostream ostream(*Buffer); raw_svector_ostream ostream(*Buffer);
legacy::PassManager PM; legacy::PassManager PM;
if (TargetMachine->addPassesToEmitFile(PM, ostream, bool NotAdded;
TargetMachine::CGFT_ObjectFile)) { #if CLANG_VERSION_MAJOR < 7
NotAdded = TargetMachine->addPassesToEmitFile(PM, ostream,
TargetMachine::CGFT_ObjectFile);
#else
NotAdded = TargetMachine->addPassesToEmitFile(PM, ostream, nullptr,
TargetMachine::CGFT_ObjectFile);
#endif
if (NotAdded) {
llvm::errs() << "TargetMachine can't emit a file of this type\n"; llvm::errs() << "TargetMachine can't emit a file of this type\n";
return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr);; return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr);;
} }
......
...@@ -2129,6 +2129,7 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) ...@@ -2129,6 +2129,7 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
int cpu_nr = ff->ph->env.nr_cpus_avail; int cpu_nr = ff->ph->env.nr_cpus_avail;
u64 size = 0; u64 size = 0;
struct perf_header *ph = ff->ph; struct perf_header *ph = ff->ph;
bool do_core_id_test = true;
ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu)); ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu));
if (!ph->env.cpu) if (!ph->env.cpu)
...@@ -2183,6 +2184,13 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) ...@@ -2183,6 +2184,13 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
return 0; return 0;
} }
/* On s390 the socket_id number is not related to the numbers of cpus.
* The socket_id number might be higher than the numbers of cpus.
* This depends on the configuration.
*/
if (ph->env.arch && !strncmp(ph->env.arch, "s390", 4))
do_core_id_test = false;
for (i = 0; i < (u32)cpu_nr; i++) { for (i = 0; i < (u32)cpu_nr; i++) {
if (do_read_u32(ff, &nr)) if (do_read_u32(ff, &nr))
goto free_cpu; goto free_cpu;
...@@ -2192,7 +2200,7 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) ...@@ -2192,7 +2200,7 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
if (do_read_u32(ff, &nr)) if (do_read_u32(ff, &nr))
goto free_cpu; goto free_cpu;
if (nr != (u32)-1 && nr > (u32)cpu_nr) { if (do_core_id_test && nr != (u32)-1 && nr > (u32)cpu_nr) {
pr_debug("socket_id number is too big." pr_debug("socket_id number is too big."
"You may need to upgrade the perf tool.\n"); "You may need to upgrade the perf tool.\n");
goto free_cpu; goto free_cpu;
...@@ -3456,7 +3464,7 @@ int perf_event__process_feature(struct perf_tool *tool, ...@@ -3456,7 +3464,7 @@ int perf_event__process_feature(struct perf_tool *tool,
pr_warning("invalid record type %d in pipe-mode\n", type); pr_warning("invalid record type %d in pipe-mode\n", type);
return 0; return 0;
} }
if (feat == HEADER_RESERVED || feat > HEADER_LAST_FEATURE) { if (feat == HEADER_RESERVED || feat >= HEADER_LAST_FEATURE) {
pr_warning("invalid record type %d in pipe-mode\n", type); pr_warning("invalid record type %d in pipe-mode\n", type);
return -1; return -1;
} }
......
...@@ -366,7 +366,7 @@ static int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf, ...@@ -366,7 +366,7 @@ static int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf,
if (len < offs) if (len < offs)
return INTEL_PT_NEED_MORE_BYTES; return INTEL_PT_NEED_MORE_BYTES;
byte = buf[offs++]; byte = buf[offs++];
payload |= (byte >> 1) << shift; payload |= ((uint64_t)byte >> 1) << shift;
} }
packet->type = INTEL_PT_CYC; packet->type = INTEL_PT_CYC;
......
...@@ -234,6 +234,74 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias, ...@@ -234,6 +234,74 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
return 0; return 0;
} }
static void perf_pmu_assign_str(char *name, const char *field, char **old_str,
char **new_str)
{
if (!*old_str)
goto set_new;
if (*new_str) { /* Have new string, check with old */
if (strcasecmp(*old_str, *new_str))
pr_debug("alias %s differs in field '%s'\n",
name, field);
zfree(old_str);
} else /* Nothing new --> keep old string */
return;
set_new:
*old_str = *new_str;
*new_str = NULL;
}
static void perf_pmu_update_alias(struct perf_pmu_alias *old,
struct perf_pmu_alias *newalias)
{
perf_pmu_assign_str(old->name, "desc", &old->desc, &newalias->desc);
perf_pmu_assign_str(old->name, "long_desc", &old->long_desc,
&newalias->long_desc);
perf_pmu_assign_str(old->name, "topic", &old->topic, &newalias->topic);
perf_pmu_assign_str(old->name, "metric_expr", &old->metric_expr,
&newalias->metric_expr);
perf_pmu_assign_str(old->name, "metric_name", &old->metric_name,
&newalias->metric_name);
perf_pmu_assign_str(old->name, "value", &old->str, &newalias->str);
old->scale = newalias->scale;
old->per_pkg = newalias->per_pkg;
old->snapshot = newalias->snapshot;
memcpy(old->unit, newalias->unit, sizeof(old->unit));
}
/* Delete an alias entry. */
static void perf_pmu_free_alias(struct perf_pmu_alias *newalias)
{
zfree(&newalias->name);
zfree(&newalias->desc);
zfree(&newalias->long_desc);
zfree(&newalias->topic);
zfree(&newalias->str);
zfree(&newalias->metric_expr);
zfree(&newalias->metric_name);
parse_events_terms__purge(&newalias->terms);
free(newalias);
}
/* Merge an alias, search in alias list. If this name is already
* present merge both of them to combine all information.
*/
static bool perf_pmu_merge_alias(struct perf_pmu_alias *newalias,
struct list_head *alist)
{
struct perf_pmu_alias *a;
list_for_each_entry(a, alist, list) {
if (!strcasecmp(newalias->name, a->name)) {
perf_pmu_update_alias(a, newalias);
perf_pmu_free_alias(newalias);
return true;
}
}
return false;
}
static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
char *desc, char *val, char *desc, char *val,
char *long_desc, char *topic, char *long_desc, char *topic,
...@@ -241,9 +309,11 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, ...@@ -241,9 +309,11 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
char *metric_expr, char *metric_expr,
char *metric_name) char *metric_name)
{ {
struct parse_events_term *term;
struct perf_pmu_alias *alias; struct perf_pmu_alias *alias;
int ret; int ret;
int num; int num;
char newval[256];
alias = malloc(sizeof(*alias)); alias = malloc(sizeof(*alias));
if (!alias) if (!alias)
...@@ -262,6 +332,27 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, ...@@ -262,6 +332,27 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
return ret; return ret;
} }
/* Scan event and remove leading zeroes, spaces, newlines, some
* platforms have terms specified as
* event=0x0091 (read from files ../<PMU>/events/<FILE>
* and terms specified as event=0x91 (read from JSON files).
*
* Rebuild string to make alias->str member comparable.
*/
memset(newval, 0, sizeof(newval));
ret = 0;
list_for_each_entry(term, &alias->terms, list) {
if (ret)
ret += scnprintf(newval + ret, sizeof(newval) - ret,
",");
if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM)
ret += scnprintf(newval + ret, sizeof(newval) - ret,
"%s=%#x", term->config, term->val.num);
else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
ret += scnprintf(newval + ret, sizeof(newval) - ret,
"%s=%s", term->config, term->val.str);
}
alias->name = strdup(name); alias->name = strdup(name);
if (dir) { if (dir) {
/* /*
...@@ -285,8 +376,9 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, ...@@ -285,8 +376,9 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
snprintf(alias->unit, sizeof(alias->unit), "%s", unit); snprintf(alias->unit, sizeof(alias->unit), "%s", unit);
} }
alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1; alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1;
alias->str = strdup(val); alias->str = strdup(newval);
if (!perf_pmu_merge_alias(alias, list))
list_add_tail(&alias->list, list); list_add_tail(&alias->list, list);
return 0; return 0;
...@@ -303,6 +395,9 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI ...@@ -303,6 +395,9 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
buf[ret] = 0; buf[ret] = 0;
/* Remove trailing newline from sysfs file */
rtrim(buf);
return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL, return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
NULL, NULL, NULL); NULL, NULL, NULL);
} }
......
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