mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
perf/core improvements and fixes:
Fixes: - Fix concat_probe_trace_events() in 'perf probe', it should dereference a pointer, not test its value (Ravi Bangoria) User visible: - Handle partial AUX records, checking if 'kvm_intel.ko' is loaded and if its 'vmm_exclusive' parameter is set to 0, suggesting tweaking it to reduce gaps (Alexander Shishkin) Infrastructure: - Sync the kvm.h, cpufeatures.h and perf_event.h tools/ headers copies with the kernel (Arnaldo Carvalho de Melo, Alexander Shishkin) - 'perf lock' subcommands should include common options, using OPT_PARENT() (Changbin Du) - Ditto for 'perf timechart' (Arnaldo Carvalho de Melo) Documentation: Correct 'perf stat --no-aggr' description (Ravi Bangoria) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJY0H3tAAoJENZQFvNTUqpAiTAP/3RgOPnX7Cd8mK2e5bb9aRGF LRvx3pGJuFgUrt+EBk3xVr3HamMJFAPOhPo26qwR4sUJMwP4MrmE1Jlo2x9//oer WXO9nnGf3Y1r7x3CAEHXPp3Qt9MHWas9lXeFqOeFbqI55rZr5j6Q8SRt4iYaxq/N 5WtcZthsTvBCb8HgDhzX2sjoKDMyue1eRBgXSLECKcm9SVk1omtcMEoUl+4sw0mR zlk6ehzimSF1BOsNRi8tNkQnxGAJ92drlUpVl5wNQwRA67kmOmQcqKWsGiv//yvH Qmovpzpt9qrN0rQFwKGxR+SPJGSI/TtB8qNwc8riA+vzZGDIvUfxNlswAjuS0hpE 61cnc0+P1GBZY3wBCRN8LhyuXKN3sqE0wRlC7k+FGA9Ft51GXKepuLRCwSSpKMnb OZwhQf3a1U4taT392nhQ/TjLJgZrr3ZVGotadS9fykhTWQx4DNgDVoIJAq9oItTY xHVqmrvr6Ky5VSJN+h7aAWGVmkxs49mp5Da+3QODTCFzezci4gxr7BgB03bU1q8d 4fGr/ho13frISzV35FTvASDM4/zAN2mI9iYfpOyx52HC7sLH2cKM6oBhV8QEo/WE wGP7uFEQeziow82kaLoi/pGPDyiXNc8aQPrjgkZhShItyhBmXtQqXTQKii/VpkEy sOppAe5+13UKw+x0iQzo =DmuJ -----END PGP SIGNATURE----- Merge tag 'perf-core-for-mingo-4.12-20170320' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: Fixes: - Fix concat_probe_trace_events() in 'perf probe', it should dereference a pointer, not test its value (Ravi Bangoria) User visible changes: - Handle partial AUX records, checking if 'kvm_intel.ko' is loaded and if its 'vmm_exclusive' parameter is set to 0, suggesting tweaking it to reduce gaps (Alexander Shishkin) Infrastructure changes: - Sync the kvm.h, cpufeatures.h and perf_event.h tools/ headers copies with the kernel (Arnaldo Carvalho de Melo, Alexander Shishkin) - 'perf lock' subcommands should include common options, using OPT_PARENT() (Changbin Du) - Ditto for 'perf timechart' (Arnaldo Carvalho de Melo) Documentation changes: Correct 'perf stat --no-aggr' description (Ravi Bangoria) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
267dd0a07e
14 changed files with 130 additions and 28 deletions
|
@ -181,10 +181,23 @@ struct kvm_arch_memory_slot {
|
|||
#define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
|
||||
#define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32
|
||||
#define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
|
||||
#define KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT 32
|
||||
#define KVM_DEV_ARM_VGIC_V3_MPIDR_MASK \
|
||||
(0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
|
||||
#define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
|
||||
#define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
|
||||
#define KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0xffff)
|
||||
#define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
|
||||
#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
|
||||
#define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
|
||||
#define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6
|
||||
#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
|
||||
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10
|
||||
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
|
||||
(0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
|
||||
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff
|
||||
#define VGIC_LEVEL_INFO_LINE_LEVEL 0
|
||||
|
||||
#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
|
||||
|
||||
/* KVM_IRQ_LINE irq field index values */
|
||||
|
|
|
@ -201,10 +201,23 @@ struct kvm_arch_memory_slot {
|
|||
#define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
|
||||
#define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32
|
||||
#define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
|
||||
#define KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT 32
|
||||
#define KVM_DEV_ARM_VGIC_V3_MPIDR_MASK \
|
||||
(0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
|
||||
#define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
|
||||
#define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
|
||||
#define KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0xffff)
|
||||
#define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
|
||||
#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
|
||||
#define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
|
||||
#define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6
|
||||
#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
|
||||
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10
|
||||
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
|
||||
(0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
|
||||
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff
|
||||
#define VGIC_LEVEL_INFO_LINE_LEVEL 0
|
||||
|
||||
#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
|
||||
|
||||
/* Device Control API on vcpu fd */
|
||||
|
|
|
@ -413,6 +413,26 @@ struct kvm_get_htab_header {
|
|||
__u16 n_invalid;
|
||||
};
|
||||
|
||||
/* For KVM_PPC_CONFIGURE_V3_MMU */
|
||||
struct kvm_ppc_mmuv3_cfg {
|
||||
__u64 flags;
|
||||
__u64 process_table; /* second doubleword of partition table entry */
|
||||
};
|
||||
|
||||
/* Flag values for KVM_PPC_CONFIGURE_V3_MMU */
|
||||
#define KVM_PPC_MMUV3_RADIX 1 /* 1 = radix mode, 0 = HPT */
|
||||
#define KVM_PPC_MMUV3_GTSE 2 /* global translation shootdown enb. */
|
||||
|
||||
/* For KVM_PPC_GET_RMMU_INFO */
|
||||
struct kvm_ppc_rmmu_info {
|
||||
struct kvm_ppc_radix_geom {
|
||||
__u8 page_shift;
|
||||
__u8 level_bits[4];
|
||||
__u8 pad[3];
|
||||
} geometries[8];
|
||||
__u32 ap_encodings[8];
|
||||
};
|
||||
|
||||
/* Per-vcpu XICS interrupt controller state */
|
||||
#define KVM_REG_PPC_ICP_STATE (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c)
|
||||
|
||||
|
@ -613,5 +633,7 @@ struct kvm_get_htab_header {
|
|||
#define KVM_XICS_LEVEL_SENSITIVE (1ULL << 40)
|
||||
#define KVM_XICS_MASKED (1ULL << 41)
|
||||
#define KVM_XICS_PENDING (1ULL << 42)
|
||||
#define KVM_XICS_PRESENTED (1ULL << 43)
|
||||
#define KVM_XICS_QUEUED (1ULL << 44)
|
||||
|
||||
#endif /* __LINUX_KVM_POWERPC_H */
|
||||
|
|
|
@ -289,7 +289,8 @@
|
|||
#define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */
|
||||
#define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
|
||||
#define X86_FEATURE_AVX512_VPOPCNTDQ (16*32+14) /* POPCNT for vectors of DW/QW */
|
||||
#define X86_FEATURE_RDPID (16*32+ 22) /* RDPID instruction */
|
||||
#define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */
|
||||
#define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */
|
||||
|
||||
/* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */
|
||||
#define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */
|
||||
|
|
|
@ -915,6 +915,7 @@ enum perf_callchain_context {
|
|||
*/
|
||||
#define PERF_AUX_FLAG_TRUNCATED 0x01 /* record was truncated to fit */
|
||||
#define PERF_AUX_FLAG_OVERWRITE 0x02 /* snapshot from overwrite mode */
|
||||
#define PERF_AUX_FLAG_PARTIAL 0x04 /* record contains gaps */
|
||||
|
||||
#define PERF_FLAG_FD_NO_GROUP (1UL << 0)
|
||||
#define PERF_FLAG_FD_OUTPUT (1UL << 1)
|
||||
|
|
|
@ -439,6 +439,35 @@ int sysfs__read_str(const char *entry, char **buf, size_t *sizep)
|
|||
return filename__read_str(path, buf, sizep);
|
||||
}
|
||||
|
||||
int sysfs__read_bool(const char *entry, bool *value)
|
||||
{
|
||||
char *buf;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
ret = sysfs__read_str(entry, &buf, &size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (buf[0]) {
|
||||
case '1':
|
||||
case 'y':
|
||||
case 'Y':
|
||||
*value = true;
|
||||
break;
|
||||
case '0':
|
||||
case 'n':
|
||||
case 'N':
|
||||
*value = false;
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
int sysctl__read_int(const char *sysctl, int *value)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
|
|
@ -37,4 +37,5 @@ int sysctl__read_int(const char *sysctl, int *value);
|
|||
int sysfs__read_int(const char *entry, int *value);
|
||||
int sysfs__read_ull(const char *entry, unsigned long long *value);
|
||||
int sysfs__read_str(const char *entry, char **buf, size_t *sizep);
|
||||
int sysfs__read_bool(const char *entry, bool *value);
|
||||
#endif /* __API_FS__ */
|
||||
|
|
|
@ -94,8 +94,7 @@ to activate system-wide monitoring. Default is to count on all CPUs.
|
|||
|
||||
-A::
|
||||
--no-aggr::
|
||||
Do not aggregate counts across all monitored CPUs in system-wide mode (-a).
|
||||
This option is only valid in system-wide mode.
|
||||
Do not aggregate counts across all monitored CPUs.
|
||||
|
||||
-n::
|
||||
--null::
|
||||
|
|
|
@ -948,27 +948,29 @@ static int __cmd_record(int argc, const char **argv)
|
|||
|
||||
int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
{
|
||||
const struct option lock_options[] = {
|
||||
OPT_STRING('i', "input", &input_name, "file", "input file name"),
|
||||
OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"),
|
||||
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"),
|
||||
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
const struct option info_options[] = {
|
||||
OPT_BOOLEAN('t', "threads", &info_threads,
|
||||
"dump thread list in perf.data"),
|
||||
OPT_BOOLEAN('m', "map", &info_map,
|
||||
"map of lock instances (address:name table)"),
|
||||
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
|
||||
OPT_END()
|
||||
};
|
||||
const struct option lock_options[] = {
|
||||
OPT_STRING('i', "input", &input_name, "file", "input file name"),
|
||||
OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"),
|
||||
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"),
|
||||
OPT_END()
|
||||
OPT_PARENT(lock_options)
|
||||
};
|
||||
|
||||
const struct option report_options[] = {
|
||||
OPT_STRING('k', "key", &sort_key, "acquired",
|
||||
"key for sorting (acquired / contended / avg_wait / wait_total / wait_max / wait_min)"),
|
||||
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
|
||||
/* TODO: type */
|
||||
OPT_END()
|
||||
OPT_PARENT(lock_options)
|
||||
};
|
||||
|
||||
const char * const info_usage[] = {
|
||||
"perf lock info [<options>]",
|
||||
NULL
|
||||
|
|
|
@ -1933,6 +1933,11 @@ int cmd_timechart(int argc, const char **argv,
|
|||
.merge_dist = 1000,
|
||||
};
|
||||
const char *output_name = "output.svg";
|
||||
const struct option timechart_common_options[] = {
|
||||
OPT_BOOLEAN('P', "power-only", &tchart.power_only, "output power data only"),
|
||||
OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only, "output processes data only"),
|
||||
OPT_END()
|
||||
};
|
||||
const struct option timechart_options[] = {
|
||||
OPT_STRING('i', "input", &input_name, "file", "input file name"),
|
||||
OPT_STRING('o', "output", &output_name, "file", "output file name"),
|
||||
|
@ -1940,9 +1945,6 @@ int cmd_timechart(int argc, const char **argv,
|
|||
OPT_CALLBACK(0, "highlight", NULL, "duration or task name",
|
||||
"highlight tasks. Pass duration in ns or process name.",
|
||||
parse_highlight),
|
||||
OPT_BOOLEAN('P', "power-only", &tchart.power_only, "output power data only"),
|
||||
OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only,
|
||||
"output processes data only"),
|
||||
OPT_CALLBACK('p', "process", NULL, "process",
|
||||
"process selector. Pass a pid or process name.",
|
||||
parse_process),
|
||||
|
@ -1962,22 +1964,18 @@ int cmd_timechart(int argc, const char **argv,
|
|||
"merge events that are merge-dist us apart",
|
||||
parse_time),
|
||||
OPT_BOOLEAN('f', "force", &tchart.force, "don't complain, do it"),
|
||||
OPT_END()
|
||||
OPT_PARENT(timechart_common_options),
|
||||
};
|
||||
const char * const timechart_subcommands[] = { "record", NULL };
|
||||
const char *timechart_usage[] = {
|
||||
"perf timechart [<options>] {record}",
|
||||
NULL
|
||||
};
|
||||
|
||||
const struct option timechart_record_options[] = {
|
||||
OPT_BOOLEAN('P', "power-only", &tchart.power_only, "output power data only"),
|
||||
OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only,
|
||||
"output processes data only"),
|
||||
OPT_BOOLEAN('I', "io-only", &tchart.io_only,
|
||||
"record only IO data"),
|
||||
OPT_BOOLEAN('g', "callchain", &tchart.with_backtrace, "record callchain"),
|
||||
OPT_END()
|
||||
OPT_PARENT(timechart_common_options),
|
||||
};
|
||||
const char * const timechart_record_usage[] = {
|
||||
"perf timechart record [<options>]",
|
||||
|
|
|
@ -1288,11 +1288,12 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
|
|||
|
||||
size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp)
|
||||
{
|
||||
return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s]\n",
|
||||
return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s%s]\n",
|
||||
event->aux.aux_offset, event->aux.aux_size,
|
||||
event->aux.flags,
|
||||
event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "",
|
||||
event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "");
|
||||
event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "",
|
||||
event->aux.flags & PERF_AUX_FLAG_PARTIAL ? "P" : "");
|
||||
}
|
||||
|
||||
size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
|
||||
|
|
|
@ -276,6 +276,7 @@ struct events_stats {
|
|||
u64 total_lost;
|
||||
u64 total_lost_samples;
|
||||
u64 total_aux_lost;
|
||||
u64 total_aux_partial;
|
||||
u64 total_invalid_chains;
|
||||
u32 nr_events[PERF_RECORD_HEADER_MAX];
|
||||
u32 nr_non_filtered_samples;
|
||||
|
|
|
@ -3048,7 +3048,7 @@ concat_probe_trace_events(struct probe_trace_event **tevs, int *ntevs,
|
|||
struct probe_trace_event *new_tevs;
|
||||
int ret = 0;
|
||||
|
||||
if (ntevs == 0) {
|
||||
if (*ntevs == 0) {
|
||||
*tevs = *tevs2;
|
||||
*ntevs = ntevs2;
|
||||
*tevs2 = NULL;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <traceevent/event-parse.h>
|
||||
#include <api/fs/fs.h>
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <unistd.h>
|
||||
|
@ -1260,9 +1261,12 @@ static int machines__deliver_event(struct machines *machines,
|
|||
case PERF_RECORD_UNTHROTTLE:
|
||||
return tool->unthrottle(tool, event, sample, machine);
|
||||
case PERF_RECORD_AUX:
|
||||
if (tool->aux == perf_event__process_aux &&
|
||||
(event->aux.flags & PERF_AUX_FLAG_TRUNCATED))
|
||||
evlist->stats.total_aux_lost += 1;
|
||||
if (tool->aux == perf_event__process_aux) {
|
||||
if (event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
|
||||
evlist->stats.total_aux_lost += 1;
|
||||
if (event->aux.flags & PERF_AUX_FLAG_PARTIAL)
|
||||
evlist->stats.total_aux_partial += 1;
|
||||
}
|
||||
return tool->aux(tool, event, sample, machine);
|
||||
case PERF_RECORD_ITRACE_START:
|
||||
return tool->itrace_start(tool, event, sample, machine);
|
||||
|
@ -1555,6 +1559,23 @@ static void perf_session__warn_about_errors(const struct perf_session *session)
|
|||
stats->nr_events[PERF_RECORD_AUX]);
|
||||
}
|
||||
|
||||
if (session->tool->aux == perf_event__process_aux &&
|
||||
stats->total_aux_partial != 0) {
|
||||
bool vmm_exclusive = false;
|
||||
|
||||
(void)sysfs__read_bool("module/kvm_intel/parameters/vmm_exclusive",
|
||||
&vmm_exclusive);
|
||||
|
||||
ui__warning("AUX data had gaps in it %" PRIu64 " times out of %u!\n\n"
|
||||
"Are you running a KVM guest in the background?%s\n\n",
|
||||
stats->total_aux_partial,
|
||||
stats->nr_events[PERF_RECORD_AUX],
|
||||
vmm_exclusive ?
|
||||
"\nReloading kvm_intel module with vmm_exclusive=0\n"
|
||||
"will reduce the gaps to only guest's timeslices." :
|
||||
"");
|
||||
}
|
||||
|
||||
if (stats->nr_unknown_events != 0) {
|
||||
ui__warning("Found %u unknown events!\n\n"
|
||||
"Is this an older tool processing a perf.data "
|
||||
|
|
Loading…
Reference in a new issue