Skip to content

Commit

Permalink
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
 "Various fixes.

  The -g perf report lockup you reported is only partially addressed,
  patches that fix the excessive runtime are still being worked on"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf/x86: Fix uncore PCI fixed counter handling
  uprobes: Fix utask->depth accounting in handle_trampoline()
  perf/x86: Add constraint for IVB CYCLE_ACTIVITY:CYCLES_LDM_PENDING
  perf: Fix up MMAP2 buffer space reservation
  perf tools: Add attr->mmap2 support
  perf kvm: Fix sample_type manipulation
  perf evlist: Fix id pos in perf_evlist__open()
  perf trace: Handle perf.data files with no tracepoints
  perf session: Separate progress bar update when processing events
  perf trace: Check if MAP_32BIT is defined
  perf hists: Fix formatting of long symbol names
  perf evlist: Fix parsing with no sample_id_all bit set
  perf tools: Add test for parsing with no sample_id_all bit
  perf trace: Check control+C more often
  • Loading branch information
torvalds committed Sep 12, 2013
2 parents b55ee28 + dbc33f7 commit 75acebf
Show file tree
Hide file tree
Showing 29 changed files with 381 additions and 82 deletions.
1 change: 1 addition & 0 deletions arch/x86/kernel/cpu/perf_event_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ static struct event_constraint intel_ivb_event_constraints[] __read_mostly =
INTEL_UEVENT_CONSTRAINT(0x0148, 0x4), /* L1D_PEND_MISS.PENDING */
INTEL_UEVENT_CONSTRAINT(0x0279, 0xf), /* IDQ.EMTPY */
INTEL_UEVENT_CONSTRAINT(0x019c, 0xf), /* IDQ_UOPS_NOT_DELIVERED.CORE */
INTEL_UEVENT_CONSTRAINT(0x02a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_LDM_PENDING */
INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */
INTEL_UEVENT_CONSTRAINT(0x06a3, 0xf), /* CYCLE_ACTIVITY.STALLS_LDM_PENDING */
Expand Down
6 changes: 4 additions & 2 deletions arch/x86/kernel/cpu/perf_event_intel_uncore.c
Original file line number Diff line number Diff line change
Expand Up @@ -2808,7 +2808,7 @@ uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *eve
return c;
}

if (event->hw.config == ~0ULL)
if (event->attr.config == UNCORE_FIXED_EVENT)
return &constraint_fixed;

if (type->constraints) {
Expand Down Expand Up @@ -3112,7 +3112,9 @@ static int uncore_pmu_event_init(struct perf_event *event)
*/
if (pmu->type->single_fixed && pmu->pmu_idx > 0)
return -EINVAL;
hwc->config = ~0ULL;

/* fixed counters have event field hardcoded to zero */
hwc->config = 0ULL;
} else {
hwc->config = event->attr.config & pmu->type->event_mask;
if (pmu->type->ops->hw_config) {
Expand Down
1 change: 1 addition & 0 deletions kernel/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -5039,6 +5039,7 @@ static void perf_event_mmap_output(struct perf_event *event,
mmap_event->event_id.header.size += sizeof(mmap_event->maj);
mmap_event->event_id.header.size += sizeof(mmap_event->min);
mmap_event->event_id.header.size += sizeof(mmap_event->ino);
mmap_event->event_id.header.size += sizeof(mmap_event->ino_generation);
}

perf_event_header__init_id(&mmap_event->event_id.header, &sample, event);
Expand Down
4 changes: 1 addition & 3 deletions kernel/events/uprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1682,12 +1682,10 @@ static bool handle_trampoline(struct pt_regs *regs)
tmp = ri;
ri = ri->next;
kfree(tmp);
utask->depth--;

if (!chained)
break;

utask->depth--;

BUG_ON(!ri);
}

Expand Down
3 changes: 2 additions & 1 deletion tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,8 @@ ifeq ($(ARCH),x86)
LIB_OBJS += $(OUTPUT)tests/perf-time-to-tsc.o
endif
LIB_OBJS += $(OUTPUT)tests/code-reading.o
LIB_OBJS += $(OUTPUT)tests/sample-parsing.o
LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o

BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
Expand Down Expand Up @@ -439,7 +441,6 @@ PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
ifneq ($(OUTPUT),)
CFLAGS += -I$(OUTPUT)
endif
LIB_OBJS += $(OUTPUT)tests/sample-parsing.o

ifdef NO_LIBELF
EXTLIBS := $(filter-out -lelf,$(EXTLIBS))
Expand Down
1 change: 1 addition & 0 deletions tools/perf/builtin-annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
.tool = {
.sample = process_sample_event,
.mmap = perf_event__process_mmap,
.mmap2 = perf_event__process_mmap2,
.comm = perf_event__process_comm,
.exit = perf_event__process_exit,
.fork = perf_event__process_fork,
Expand Down
15 changes: 15 additions & 0 deletions tools/perf/builtin-inject.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,19 @@ static int perf_event__repipe_mmap(struct perf_tool *tool,
return err;
}

static int perf_event__repipe_mmap2(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
struct machine *machine)
{
int err;

err = perf_event__process_mmap2(tool, event, sample, machine);
perf_event__repipe(tool, event, sample, machine);

return err;
}

static int perf_event__repipe_fork(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
Expand Down Expand Up @@ -339,6 +352,7 @@ static int __cmd_inject(struct perf_inject *inject)

if (inject->build_ids || inject->sched_stat) {
inject->tool.mmap = perf_event__repipe_mmap;
inject->tool.mmap2 = perf_event__repipe_mmap2;
inject->tool.fork = perf_event__repipe_fork;
inject->tool.tracing_data = perf_event__repipe_tracing_data;
}
Expand Down Expand Up @@ -390,6 +404,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
.tool = {
.sample = perf_event__repipe_sample,
.mmap = perf_event__repipe,
.mmap2 = perf_event__repipe,
.comm = perf_event__repipe,
.fork = perf_event__repipe,
.exit = perf_event__repipe,
Expand Down
18 changes: 9 additions & 9 deletions tools/perf/builtin-kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1165,16 +1165,16 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
struct perf_event_attr *attr = &pos->attr;

/* make sure these *are* set */
attr->sample_type |= PERF_SAMPLE_TID;
attr->sample_type |= PERF_SAMPLE_TIME;
attr->sample_type |= PERF_SAMPLE_CPU;
attr->sample_type |= PERF_SAMPLE_RAW;
perf_evsel__set_sample_bit(pos, TID);
perf_evsel__set_sample_bit(pos, TIME);
perf_evsel__set_sample_bit(pos, CPU);
perf_evsel__set_sample_bit(pos, RAW);
/* make sure these are *not*; want as small a sample as possible */
attr->sample_type &= ~PERF_SAMPLE_PERIOD;
attr->sample_type &= ~PERF_SAMPLE_IP;
attr->sample_type &= ~PERF_SAMPLE_CALLCHAIN;
attr->sample_type &= ~PERF_SAMPLE_ADDR;
attr->sample_type &= ~PERF_SAMPLE_READ;
perf_evsel__reset_sample_bit(pos, PERIOD);
perf_evsel__reset_sample_bit(pos, IP);
perf_evsel__reset_sample_bit(pos, CALLCHAIN);
perf_evsel__reset_sample_bit(pos, ADDR);
perf_evsel__reset_sample_bit(pos, READ);
attr->mmap = 0;
attr->comm = 0;
attr->task = 0;
Expand Down
1 change: 1 addition & 0 deletions tools/perf/builtin-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused)
.tool = {
.sample = process_sample_event,
.mmap = perf_event__process_mmap,
.mmap2 = perf_event__process_mmap2,
.comm = perf_event__process_comm,
.lost = perf_event__process_lost,
.fork = perf_event__process_fork,
Expand Down
1 change: 1 addition & 0 deletions tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
.tool = {
.sample = process_sample_event,
.mmap = perf_event__process_mmap,
.mmap2 = perf_event__process_mmap2,
.comm = perf_event__process_comm,
.exit = perf_event__process_exit,
.fork = perf_event__process_fork,
Expand Down
1 change: 1 addition & 0 deletions tools/perf/builtin-script.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
static struct perf_tool perf_script = {
.sample = process_sample_event,
.mmap = perf_event__process_mmap,
.mmap2 = perf_event__process_mmap2,
.comm = perf_event__process_comm,
.exit = perf_event__process_exit,
.fork = perf_event__process_fork,
Expand Down
5 changes: 5 additions & 0 deletions tools/perf/builtin-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,

P_MMAP_FLAG(SHARED);
P_MMAP_FLAG(PRIVATE);
#ifdef MAP_32BIT
P_MMAP_FLAG(32BIT);
#endif
P_MMAP_FLAG(ANONYMOUS);
P_MMAP_FLAG(DENYWRITE);
P_MMAP_FLAG(EXECUTABLE);
Expand Down Expand Up @@ -994,6 +996,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv)

handler = evsel->handler.func;
handler(trace, evsel, &sample);

if (done)
goto out_unmap_evlist;
}
}

Expand Down
4 changes: 4 additions & 0 deletions tools/perf/tests/builtin-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ static struct test {
.desc = "Test using a dummy software event to keep tracking",
.func = test__keep_tracking,
},
{
.desc = "Test parsing with no sample_id_all bit set",
.func = test__parse_no_sample_id_all,
},
{
.func = NULL,
},
Expand Down
108 changes: 108 additions & 0 deletions tools/perf/tests/parse-no-sample-id-all.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#include <sys/types.h>
#include <stddef.h>

#include "tests.h"

#include "event.h"
#include "evlist.h"
#include "header.h"
#include "util.h"

static int process_event(struct perf_evlist **pevlist, union perf_event *event)
{
struct perf_sample sample;

if (event->header.type == PERF_RECORD_HEADER_ATTR) {
if (perf_event__process_attr(NULL, event, pevlist)) {
pr_debug("perf_event__process_attr failed\n");
return -1;
}
return 0;
}

if (event->header.type >= PERF_RECORD_USER_TYPE_START)
return -1;

if (!*pevlist)
return -1;

if (perf_evlist__parse_sample(*pevlist, event, &sample)) {
pr_debug("perf_evlist__parse_sample failed\n");
return -1;
}

return 0;
}

static int process_events(union perf_event **events, size_t count)
{
struct perf_evlist *evlist = NULL;
int err = 0;
size_t i;

for (i = 0; i < count && !err; i++)
err = process_event(&evlist, events[i]);

if (evlist)
perf_evlist__delete(evlist);

return err;
}

struct test_attr_event {
struct attr_event attr;
u64 id;
};

/**
* test__parse_no_sample_id_all - test parsing with no sample_id_all bit set.
*
* This function tests parsing data produced on kernel's that do not support the
* sample_id_all bit. Without the sample_id_all bit, non-sample events (such as
* mmap events) do not have an id sample appended, and consequently logic
* designed to determine the id will not work. That case happens when there is
* more than one selected event, so this test processes three events: 2
* attributes representing the selected events and one mmap event.
*
* Return: %0 on success, %-1 if the test fails.
*/
int test__parse_no_sample_id_all(void)
{
int err;

struct test_attr_event event1 = {
.attr = {
.header = {
.type = PERF_RECORD_HEADER_ATTR,
.size = sizeof(struct test_attr_event),
},
},
.id = 1,
};
struct test_attr_event event2 = {
.attr = {
.header = {
.type = PERF_RECORD_HEADER_ATTR,
.size = sizeof(struct test_attr_event),
},
},
.id = 2,
};
struct mmap_event event3 = {
.header = {
.type = PERF_RECORD_MMAP,
.size = sizeof(struct mmap_event),
},
};
union perf_event *events[] = {
(union perf_event *)&event1,
(union perf_event *)&event2,
(union perf_event *)&event3,
};

err = process_events(events, ARRAY_SIZE(events));
if (err)
return -1;

return 0;
}
15 changes: 11 additions & 4 deletions tools/perf/tests/perf-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ int test__PERF_RECORD(void)
struct perf_sample sample;
const char *cmd = "sleep";
const char *argv[] = { cmd, "1", NULL, };
char *bname;
char *bname, *mmap_filename;
u64 prev_time = 0;
bool found_cmd_mmap = false,
found_libc_mmap = false,
Expand Down Expand Up @@ -212,6 +212,7 @@ int test__PERF_RECORD(void)

if ((type == PERF_RECORD_COMM ||
type == PERF_RECORD_MMAP ||
type == PERF_RECORD_MMAP2 ||
type == PERF_RECORD_FORK ||
type == PERF_RECORD_EXIT) &&
(pid_t)event->comm.pid != evlist->workload.pid) {
Expand All @@ -220,7 +221,8 @@ int test__PERF_RECORD(void)
}

if ((type == PERF_RECORD_COMM ||
type == PERF_RECORD_MMAP) &&
type == PERF_RECORD_MMAP ||
type == PERF_RECORD_MMAP2) &&
event->comm.pid != event->comm.tid) {
pr_debug("%s with different pid/tid!\n", name);
++errs;
Expand All @@ -236,7 +238,12 @@ int test__PERF_RECORD(void)
case PERF_RECORD_EXIT:
goto found_exit;
case PERF_RECORD_MMAP:
bname = strrchr(event->mmap.filename, '/');
mmap_filename = event->mmap.filename;
goto check_bname;
case PERF_RECORD_MMAP2:
mmap_filename = event->mmap2.filename;
check_bname:
bname = strrchr(mmap_filename, '/');
if (bname != NULL) {
if (!found_cmd_mmap)
found_cmd_mmap = !strcmp(bname + 1, cmd);
Expand All @@ -245,7 +252,7 @@ int test__PERF_RECORD(void)
if (!found_ld_mmap)
found_ld_mmap = !strncmp(bname + 1, "ld", 2);
} else if (!found_vdso_mmap)
found_vdso_mmap = !strcmp(event->mmap.filename, "[vdso]");
found_vdso_mmap = !strcmp(mmap_filename, "[vdso]");
break;

case PERF_RECORD_SAMPLE:
Expand Down
1 change: 1 addition & 0 deletions tools/perf/tests/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ int test__perf_time_to_tsc(void);
int test__code_reading(void);
int test__sample_parsing(void);
int test__keep_tracking(void);
int test__parse_no_sample_id_all(void);

#endif /* TESTS_H */
Loading

0 comments on commit 75acebf

Please sign in to comment.