void intel_bts_enable_local(void) { struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); if (bts->handle.event && bts->started) __bts_event_start(bts->handle.event); }
static void bts_event_start(struct perf_event *event, int flags) { struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); struct bts_buffer *buf; buf = perf_aux_output_begin(&bts->handle, event); if (!buf) goto fail_stop; if (bts_buffer_reset(buf, &bts->handle)) goto fail_end_stop; bts->ds_back.bts_buffer_base = cpuc->ds->bts_buffer_base; bts->ds_back.bts_absolute_maximum = cpuc->ds->bts_absolute_maximum; bts->ds_back.bts_interrupt_threshold = cpuc->ds->bts_interrupt_threshold; event->hw.itrace_started = 1; event->hw.state = 0; __bts_event_start(event); return; fail_end_stop: perf_aux_output_end(&bts->handle, 0, false); fail_stop: event->hw.state = PERF_HES_STOPPED; }
static void bts_event_start(struct perf_event *event, int flags) { struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); __bts_event_start(event); /* PMI handler: this counter is running and likely generating PMIs */ ACCESS_ONCE(bts->started) = 1; }
void intel_bts_enable_local(void) { struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); int state = READ_ONCE(bts->state); /* * Here we transition from INACTIVE to ACTIVE; * if we instead are STOPPED from the interrupt handler, * stay that way. Can't be ACTIVE here though. */ if (WARN_ON_ONCE(state == BTS_STATE_ACTIVE)) return; if (state == BTS_STATE_STOPPED) return; if (bts->handle.event) __bts_event_start(bts->handle.event); }