perf/urgent fixes:
perf bench: (Jiri Olsa): . Fix NUMA report output code handling of less than 1s runtimes. perf script: (Ravi Bangoria) . Add missing output fields in a 'perf script -h' hint. . Fix crash because of missing evsel->priv. . Fix crash caused by accessing feat_ops[HEADER_LAST_FEATURE], which is just a end of features header marker. perf stat: (Thomas Richter) . Remove duplicate event counting perf test: . Wire parsing error handling in 'parse events' test (Jiri Olsa) . Fix 'session topology' test on s/390 (Thomas Richter) eBPF: (Yonghong Song) . Fix a clang 7.0 compilation error when building perf linking with libclang intel-pt: (Adrian Hunter) . Fix packet decoding of CYC packets. Copies of kernel files: (Arnaldo Carvalho de Melo) . Synchronize drm/drm.h UAPI . Update x86's syscall_64.tbl, adding support for 'io_pgetevents' and 'rseq' in 'perf trace'. . Update powerpc uapi/asm/unistd.h, adding support for the 'rseq' syscall. . Update if_link.h and bpf.h, no effect on tool features. PowerPC: (Sandipan Das) . Fix crash if callchain is empty. s/390: (Thomas Richter) . Support random socked_id assignment in the perf header. . Support s390 random socket_id assignment in perf.data file. . Make PMU alias definitions taken from sysfs and JSON files comparable by normalizing them wrt spaces and newlines. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEELb9bqkb7Te0zijNb1lAW81NSqkAFAlsxGm0ACgkQ1lAW81NS qkCgLg/+JIm0GDKnYiLNRGEduw5nTy0+KHwE84Zo2GnW8BzCGzMnsFQNgKM0+xjb tMrZ9uFG3zieNisVRCyDoXQvvmlsr0kggqUGDNSZJa7Cx2bX28GW3X2cVrqbV9zm 12ubPClk65lJ7WN3ti3gqzEbkKwoP6/KbIdAgwIhwCobVczw2eNgvYnB6ycWjh4D 3Ly7CLjzYI05QgGDoZntv9PkN7MQ9zil7lQjGc8FzMeeCxXuikVaOVywGda8FIyl bdXMyVYQZ+fmGZ/Vxs1gwouLsm+734ad1SY0vwR9FK0gvFlRD2Ls4kROmNjpAxqj 68PHg5T8Bw9zz1MKQ02BK1Qzb+kAWWBMhOkKGnZWoG/lvQABbVpIMSuo8FqppjQ4 adUjxvxnFYIkeRiWneyv2/ezmDtWxjnwYE3SIMjwSJH1R1rSVqoJ6qot0TKRXXnt UyF8mHTlVkPbOpYW9aZKFuYA5e7qdUQTLjhrbStE9U8YKLE4vlnkYdZpK9anJlzz tPrM9rKGjszZuceRJFCWvoL01h73b3KsScW2GieyakxcFdldDcgTPDpNsoVwjGl7 YQwrJkuRW/M0yLYyZ7LYqBW1exCSayRC1L4cxZgP12xzEsxhg+MlLLxturF62F5Y qERgDmeG8bcUmhpltHo8MIY3OAk1TNBtRdzWMEwOTxjybh93NOM= =96FW -----END PGP SIGNATURE----- Merge tag 'perf-urgent-for-mingo-4.18-20180625' 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 bench: (Jiri Olsa): - Fix NUMA report output code handling of less than 1s runtimes. perf script: (Ravi Bangoria) - Add missing output fields in a 'perf script -h' hint. - Fix crash because of missing evsel->priv. - Fix crash caused by accessing feat_ops[HEADER_LAST_FEATURE], which is just a end of features header marker. perf stat: (Thomas Richter) - Remove duplicate event counting perf test: - Wire parsing error handling in 'parse events' test (Jiri Olsa) - Fix 'session topology' test on s/390 (Thomas Richter) eBPF: (Yonghong Song) - Fix a clang 7.0 compilation error when building perf linking with libclang intel-pt: (Adrian Hunter) - Fix packet decoding of CYC packets. Copies of kernel files: (Arnaldo Carvalho de Melo) - Synchronize drm/drm.h UAPI - Update x86's syscall_64.tbl, adding support for 'io_pgetevents' and 'rseq' in 'perf trace'. - Update powerpc uapi/asm/unistd.h, adding support for the 'rseq' syscall. - Update if_link.h and bpf.h, no effect on tool features. PowerPC: (Sandipan Das) - Fix crash if callchain is empty. s/390: (Thomas Richter) - Support random socked_id assignment in the perf header. - Support s390 random socket_id assignment in perf.data file. - Make PMU alias definitions taken from sysfs and JSON files comparable by normalizing them wrt spaces and newlines. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
7959804107
@ -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_ */
|
||||||
|
@ -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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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)
|
||||||
|
@ -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 @@
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@ out_put:
|
|||||||
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)
|
|||||||
.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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
.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)
|
|||||||
"+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)
|
|||||||
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 {
|
|||||||
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[] = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.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[] = {
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,9 +376,10 @@ 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);
|
||||||
|
|
||||||
list_add_tail(&alias->list, list);
|
if (!perf_pmu_merge_alias(alias, 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
|
|||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user