Skip to content

Commit

Permalink
perf, x86: Less disastrous PEBS/BTS buffer allocation failure
Browse files Browse the repository at this point in the history
Currently PEBS/BTS buffers are allocated when we instantiate the first
event, when this fails everything fails.

This is a problem because esp. BTS tries to allocate a rather large
buffer (64K), which can easily fail.

This patch changes the logic such that when either buffer allocation
fails, we simply don't allow events that would use these facilities,
but continue functioning for all other events.

This logic comes from a much larger patch proposed by Stephane.

Suggested-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Stephane Eranian <eranian@google.com>
LKML-Reference: <20101019134808.354429461@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Oct 22, 2010
1 parent 5553be2 commit 6809b6e
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 16 deletions.
5 changes: 3 additions & 2 deletions arch/x86/kernel/cpu/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ struct x86_pmu {
* Intel DebugStore bits
*/
int bts, pebs;
int bts_active, pebs_active;
int pebs_record_size;
void (*drain_pebs)(struct pt_regs *regs);
struct event_constraint *pebs_constraints;
Expand Down Expand Up @@ -478,7 +479,7 @@ static int x86_setup_perfctr(struct perf_event *event)
if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
(hwc->sample_period == 1)) {
/* BTS is not supported by this architecture. */
if (!x86_pmu.bts)
if (!x86_pmu.bts_active)
return -EOPNOTSUPP;

/* BTS is currently only allowed for user-mode. */
Expand All @@ -497,7 +498,7 @@ static int x86_pmu_hw_config(struct perf_event *event)
int precise = 0;

/* Support for constant skid */
if (x86_pmu.pebs) {
if (x86_pmu.pebs_active) {
precise++;

/* Support for IP fixup */
Expand Down
58 changes: 44 additions & 14 deletions arch/x86/kernel/cpu/perf_event_intel_ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,36 +193,66 @@ static void release_ds_buffers(void)

static int reserve_ds_buffers(void)
{
int cpu, err = 0;
int bts_err = 0, pebs_err = 0;
int cpu;

x86_pmu.bts_active = 0;
x86_pmu.pebs_active = 0;

if (!x86_pmu.bts && !x86_pmu.pebs)
return 0;

if (!x86_pmu.bts)
bts_err = 1;

if (!x86_pmu.pebs)
pebs_err = 1;

get_online_cpus();

for_each_possible_cpu(cpu) {
if (alloc_ds_buffer(cpu))
break;
if (alloc_ds_buffer(cpu)) {
bts_err = 1;
pebs_err = 1;
}

if (alloc_bts_buffer(cpu))
break;
if (!bts_err && alloc_bts_buffer(cpu))
bts_err = 1;

if (!pebs_err && alloc_pebs_buffer(cpu))
pebs_err = 1;

if (alloc_pebs_buffer(cpu))
if (bts_err && pebs_err)
break;
}

if (bts_err) {
for_each_possible_cpu(cpu)
release_bts_buffer(cpu);
}

err = 0;
if (pebs_err) {
for_each_possible_cpu(cpu)
release_pebs_buffer(cpu);
}

if (err)
release_ds_buffers();
else {
if (bts_err && pebs_err) {
for_each_possible_cpu(cpu)
release_ds_buffer(cpu);
} else {
if (x86_pmu.bts && !bts_err)
x86_pmu.bts_active = 1;

if (x86_pmu.pebs && !pebs_err)
x86_pmu.pebs_active = 1;

for_each_online_cpu(cpu)
init_debug_store_on_cpu(cpu);
}

put_online_cpus();

return err;
return 0;
}

/*
Expand Down Expand Up @@ -287,7 +317,7 @@ static int intel_pmu_drain_bts_buffer(void)
if (!event)
return 0;

if (!ds)
if (!x86_pmu.bts_active)
return 0;

at = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
Expand Down Expand Up @@ -557,7 +587,7 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
struct pebs_record_core *at, *top;
int n;

if (!ds || !x86_pmu.pebs)
if (!x86_pmu.pebs_active)
return;

at = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
Expand Down Expand Up @@ -599,7 +629,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
u64 status = 0;
int bit, n;

if (!ds || !x86_pmu.pebs)
if (!x86_pmu.pebs_active)
return;

at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
Expand Down

0 comments on commit 6809b6e

Please sign in to comment.