提交 3cace81e 编写于 作者: I Ingo Molnar

Merge tag 'perf-urgent-for-mingo-20160815' of...

Merge tag 'perf-urgent-for-mingo-20160815' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent

Pull perf/urgent fixes from Arnaldo Carvalho de Melo:

- Fix occasional decoding errors when tracing system-wide with
  Intel PT (Adrian Hunter)

- Fix ip compression in Intel PT for some specific packet types not
  present on current hardware (Adrian Hunter)

- Fix annotation of objects with debuginfo files (Anton Blanchard)

- Fix build on Fedora Rawhide (25) wrt using the right header to
  get the major() & minor() definitions in the jitdump code, now
  it is deprecated getting those using sys/types.h, one has to use
  sys/sysmacros.h (Arnaldo Carvalho de Melo)

- Sync arm64/s390 kvm related header files (Arnaldo Carvalho de Melo)

- Check for dup and fdopen failures in 'perf probe' (Colin Ian King,
  Arnaldo Carvalho de Melo)

- Fix showing callchains in pipe mode, i.e.

    perf record -g -o - workload | perf script

  now shows callchains (He Kuang)

- Show proper message when the scripts directory points to some
  invalid location in 'perf script --list' (He Kuang)

- Fix 'perf mem -t store' to record 'cpu/mem-stores/P' events
  again (Jiri Olsa)

- Fix ppc64le build failure when libelf is not present (Ravi Bangoria)
Signed-off-by: NArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: NIngo Molnar <mingo@kernel.org>
......@@ -87,9 +87,11 @@ struct kvm_regs {
/* Supported VGICv3 address types */
#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
#define KVM_VGIC_ITS_ADDR_TYPE 4
#define KVM_VGIC_V3_DIST_SIZE SZ_64K
#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
#define KVM_VGIC_V3_ITS_SIZE (2 * SZ_64K)
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
......
......@@ -93,6 +93,47 @@ struct kvm_s390_vm_cpu_machine {
__u64 fac_list[256];
};
#define KVM_S390_VM_CPU_PROCESSOR_FEAT 2
#define KVM_S390_VM_CPU_MACHINE_FEAT 3
#define KVM_S390_VM_CPU_FEAT_NR_BITS 1024
#define KVM_S390_VM_CPU_FEAT_ESOP 0
#define KVM_S390_VM_CPU_FEAT_SIEF2 1
#define KVM_S390_VM_CPU_FEAT_64BSCAO 2
#define KVM_S390_VM_CPU_FEAT_SIIF 3
#define KVM_S390_VM_CPU_FEAT_GPERE 4
#define KVM_S390_VM_CPU_FEAT_GSLS 5
#define KVM_S390_VM_CPU_FEAT_IB 6
#define KVM_S390_VM_CPU_FEAT_CEI 7
#define KVM_S390_VM_CPU_FEAT_IBS 8
#define KVM_S390_VM_CPU_FEAT_SKEY 9
#define KVM_S390_VM_CPU_FEAT_CMMA 10
#define KVM_S390_VM_CPU_FEAT_PFMFI 11
#define KVM_S390_VM_CPU_FEAT_SIGPIF 12
struct kvm_s390_vm_cpu_feat {
__u64 feat[16];
};
#define KVM_S390_VM_CPU_PROCESSOR_SUBFUNC 4
#define KVM_S390_VM_CPU_MACHINE_SUBFUNC 5
/* for "test bit" instructions MSB 0 bit ordering, for "query" raw blocks */
struct kvm_s390_vm_cpu_subfunc {
__u8 plo[32]; /* always */
__u8 ptff[16]; /* with TOD-clock steering */
__u8 kmac[16]; /* with MSA */
__u8 kmc[16]; /* with MSA */
__u8 km[16]; /* with MSA */
__u8 kimd[16]; /* with MSA */
__u8 klmd[16]; /* with MSA */
__u8 pckmo[16]; /* with MSA3 */
__u8 kmctr[16]; /* with MSA4 */
__u8 kmf[16]; /* with MSA4 */
__u8 kmo[16]; /* with MSA4 */
__u8 pcc[16]; /* with MSA4 */
__u8 ppno[16]; /* with MSA5 */
__u8 reserved[1824];
};
/* kvm attributes for crypto */
#define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0
#define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1
......
......@@ -140,6 +140,7 @@
exit_code_ipa0(0xB2, 0x4c, "TAR"), \
exit_code_ipa0(0xB2, 0x50, "CSP"), \
exit_code_ipa0(0xB2, 0x54, "MVPG"), \
exit_code_ipa0(0xB2, 0x56, "STHYI"), \
exit_code_ipa0(0xB2, 0x58, "BSG"), \
exit_code_ipa0(0xB2, 0x5a, "BSA"), \
exit_code_ipa0(0xB2, 0x5f, "CHSC"), \
......
......@@ -97,6 +97,7 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
}
}
#ifdef HAVE_LIBELF_SUPPORT
void arch__post_process_probe_trace_events(struct perf_probe_event *pev,
int ntevs)
{
......@@ -118,5 +119,6 @@ void arch__post_process_probe_trace_events(struct perf_probe_event *pev,
}
}
}
#endif /* HAVE_LIBELF_SUPPORT */
#endif
......@@ -501,7 +501,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
struct intel_pt_recording *ptr =
container_of(itr, struct intel_pt_recording, itr);
struct perf_pmu *intel_pt_pmu = ptr->intel_pt_pmu;
bool have_timing_info;
bool have_timing_info, need_immediate = false;
struct perf_evsel *evsel, *intel_pt_evsel = NULL;
const struct cpu_map *cpus = evlist->cpus;
bool privileged = geteuid() == 0 || perf_event_paranoid() < 0;
......@@ -655,6 +655,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
ptr->have_sched_switch = 3;
} else {
opts->record_switch_events = true;
need_immediate = true;
if (cpu_wide)
ptr->have_sched_switch = 3;
else
......@@ -700,6 +701,9 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
tracking_evsel->attr.freq = 0;
tracking_evsel->attr.sample_period = 1;
if (need_immediate)
tracking_evsel->immediate = true;
/* In per-cpu case, always need the time of mmap events etc */
if (!cpu_map__empty(cpus)) {
perf_evsel__set_sample_bit(tracking_evsel, TIME);
......
......@@ -88,6 +88,9 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
if (mem->operation & MEM_OPERATION_LOAD)
perf_mem_events[PERF_MEM_EVENTS__LOAD].record = true;
if (mem->operation & MEM_OPERATION_STORE)
perf_mem_events[PERF_MEM_EVENTS__STORE].record = true;
if (perf_mem_events[PERF_MEM_EVENTS__LOAD].record)
rec_argv[i++] = "-W";
......
......@@ -371,14 +371,16 @@ static int perf_session__check_output_opt(struct perf_session *session)
if (!no_callchain) {
bool use_callchain = false;
bool not_pipe = false;
evlist__for_each_entry(session->evlist, evsel) {
not_pipe = true;
if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
use_callchain = true;
break;
}
}
if (!use_callchain)
if (not_pipe && !use_callchain)
symbol_conf.use_callchain = false;
}
......@@ -1690,8 +1692,13 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
scripts_dir = opendir(scripts_path);
if (!scripts_dir)
return -1;
if (!scripts_dir) {
fprintf(stdout,
"open(%s) failed.\n"
"Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",
scripts_path);
exit(-1);
}
for_each_lang(scripts_path, scripts_dir, lang_dirent) {
snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
......
......@@ -123,8 +123,6 @@ struct intel_pt_decoder {
bool have_calc_cyc_to_tsc;
int exec_mode;
unsigned int insn_bytes;
uint64_t sign_bit;
uint64_t sign_bits;
uint64_t period;
enum intel_pt_period_type period_type;
uint64_t tot_insn_cnt;
......@@ -191,9 +189,6 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
decoder->data = params->data;
decoder->return_compression = params->return_compression;
decoder->sign_bit = (uint64_t)1 << 47;
decoder->sign_bits = ~(((uint64_t)1 << 48) - 1);
decoder->period = params->period;
decoder->period_type = params->period_type;
......@@ -362,21 +357,30 @@ int intel_pt__strerror(int code, char *buf, size_t buflen)
return 0;
}
static uint64_t intel_pt_calc_ip(struct intel_pt_decoder *decoder,
const struct intel_pt_pkt *packet,
static uint64_t intel_pt_calc_ip(const struct intel_pt_pkt *packet,
uint64_t last_ip)
{
uint64_t ip;
switch (packet->count) {
case 2:
case 1:
ip = (last_ip & (uint64_t)0xffffffffffff0000ULL) |
packet->payload;
break;
case 4:
case 2:
ip = (last_ip & (uint64_t)0xffffffff00000000ULL) |
packet->payload;
break;
case 3:
ip = packet->payload;
/* Sign-extend 6-byte ip */
if (ip & (uint64_t)0x800000000000ULL)
ip |= (uint64_t)0xffff000000000000ULL;
break;
case 4:
ip = (last_ip & (uint64_t)0xffff000000000000ULL) |
packet->payload;
break;
case 6:
ip = packet->payload;
break;
......@@ -384,16 +388,12 @@ static uint64_t intel_pt_calc_ip(struct intel_pt_decoder *decoder,
return 0;
}
if (ip & decoder->sign_bit)
return ip | decoder->sign_bits;
return ip;
}
static inline void intel_pt_set_last_ip(struct intel_pt_decoder *decoder)
{
decoder->last_ip = intel_pt_calc_ip(decoder, &decoder->packet,
decoder->last_ip);
decoder->last_ip = intel_pt_calc_ip(&decoder->packet, decoder->last_ip);
}
static inline void intel_pt_set_ip(struct intel_pt_decoder *decoder)
......@@ -1657,6 +1657,12 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)
}
}
static inline bool intel_pt_have_ip(struct intel_pt_decoder *decoder)
{
return decoder->last_ip || decoder->packet.count == 0 ||
decoder->packet.count == 3 || decoder->packet.count == 6;
}
/* Walk PSB+ packets to get in sync. */
static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
{
......@@ -1677,8 +1683,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
case INTEL_PT_FUP:
decoder->pge = true;
if (decoder->last_ip || decoder->packet.count == 6 ||
decoder->packet.count == 0) {
if (intel_pt_have_ip(decoder)) {
uint64_t current_ip = decoder->ip;
intel_pt_set_ip(decoder);
......@@ -1767,8 +1772,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
case INTEL_PT_TIP_PGE:
case INTEL_PT_TIP:
decoder->pge = decoder->packet.type != INTEL_PT_TIP_PGD;
if (decoder->last_ip || decoder->packet.count == 6 ||
decoder->packet.count == 0)
if (intel_pt_have_ip(decoder))
intel_pt_set_ip(decoder);
if (decoder->ip)
return 0;
......@@ -1776,9 +1780,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
case INTEL_PT_FUP:
if (decoder->overflow) {
if (decoder->last_ip ||
decoder->packet.count == 6 ||
decoder->packet.count == 0)
if (intel_pt_have_ip(decoder))
intel_pt_set_ip(decoder);
if (decoder->ip)
return 0;
......
......@@ -292,36 +292,46 @@ static int intel_pt_get_ip(enum intel_pt_pkt_type type, unsigned int byte,
const unsigned char *buf, size_t len,
struct intel_pt_pkt *packet)
{
switch (byte >> 5) {
int ip_len;
packet->count = byte >> 5;
switch (packet->count) {
case 0:
packet->count = 0;
ip_len = 0;
break;
case 1:
if (len < 3)
return INTEL_PT_NEED_MORE_BYTES;
packet->count = 2;
ip_len = 2;
packet->payload = le16_to_cpu(*(uint16_t *)(buf + 1));
break;
case 2:
if (len < 5)
return INTEL_PT_NEED_MORE_BYTES;
packet->count = 4;
ip_len = 4;
packet->payload = le32_to_cpu(*(uint32_t *)(buf + 1));
break;
case 3:
case 6:
case 4:
if (len < 7)
return INTEL_PT_NEED_MORE_BYTES;
packet->count = 6;
ip_len = 6;
memcpy_le64(&packet->payload, buf + 1, 6);
break;
case 6:
if (len < 9)
return INTEL_PT_NEED_MORE_BYTES;
ip_len = 8;
packet->payload = le64_to_cpu(*(uint64_t *)(buf + 1));
break;
default:
return INTEL_PT_BAD_PACKET;
}
packet->type = type;
return packet->count + 1;
return ip_len + 1;
}
static int intel_pt_get_mode(const unsigned char *buf, size_t len,
......
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
......
......@@ -133,7 +133,7 @@ int probe_file__open_both(int *kfd, int *ufd, int flag)
/* Get raw string list of current kprobe_events or uprobe_events */
struct strlist *probe_file__get_rawlist(int fd)
{
int ret, idx;
int ret, idx, fddup;
FILE *fp;
char buf[MAX_CMDLEN];
char *p;
......@@ -143,8 +143,17 @@ struct strlist *probe_file__get_rawlist(int fd)
return NULL;
sl = strlist__new(NULL, NULL);
if (sl == NULL)
return NULL;
fddup = dup(fd);
if (fddup < 0)
goto out_free_sl;
fp = fdopen(fddup, "r");
if (!fp)
goto out_close_fddup;
fp = fdopen(dup(fd), "r");
while (!feof(fp)) {
p = fgets(buf, MAX_CMDLEN, fp);
if (!p)
......@@ -156,13 +165,21 @@ struct strlist *probe_file__get_rawlist(int fd)
ret = strlist__add(sl, buf);
if (ret < 0) {
pr_debug("strlist__add failed (%d)\n", ret);
strlist__delete(sl);
return NULL;
goto out_close_fp;
}
}
fclose(fp);
return sl;
out_close_fp:
fclose(fp);
goto out_free_sl;
out_close_fddup:
close(fddup);
out_free_sl:
strlist__delete(sl);
return NULL;
}
static struct strlist *__probe_file__get_namelist(int fd, bool include_group)
......@@ -447,12 +464,17 @@ static int probe_cache__load(struct probe_cache *pcache)
{
struct probe_cache_entry *entry = NULL;
char buf[MAX_CMDLEN], *p;
int ret = 0;
int ret = 0, fddup;
FILE *fp;
fp = fdopen(dup(pcache->fd), "r");
if (!fp)
fddup = dup(pcache->fd);
if (fddup < 0)
return -errno;
fp = fdopen(fddup, "r");
if (!fp) {
close(fddup);
return -EINVAL;
}
while (!feof(fp)) {
if (!fgets(buf, MAX_CMDLEN, fp))
......
......@@ -837,7 +837,8 @@ int dso__load_sym(struct dso *dso, struct map *map,
sec = syms_ss->symtab;
shdr = syms_ss->symshdr;
if (elf_section_by_name(elf, &ehdr, &tshdr, ".text", NULL))
if (elf_section_by_name(runtime_ss->elf, &runtime_ss->ehdr, &tshdr,
".text", NULL))
dso->text_offset = tshdr.sh_addr - tshdr.sh_offset;
if (runtime_ss->opdsec)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册