u64 last_in_cyc_cnt;
u64 last_br_insn_cnt;
u64 last_br_cyc_cnt;
+ unsigned int cbr_seen;
char insn[INTEL_PT_INSN_BUF_SZ];
};
ptq->cpu = queue->cpu;
ptq->tid = queue->tid;
+ ptq->cbr_seen = UINT_MAX;
+
if (pt->sampling_mode && !pt->snapshot_mode &&
pt->timeless_decoding)
ptq->step_through_buffers = true;
pt->num_events++ < pt->synth_opts.initial_skip;
}
+/*
+ * Cannot count CBR as skipped because it won't go away until cbr == cbr_seen.
+ * Also ensure CBR is first non-skipped event by allowing for 4 more samples
+ * from this decoder state.
+ */
+static inline bool intel_pt_skip_cbr_event(struct intel_pt *pt)
+{
+ return pt->synth_opts.initial_skip &&
+ pt->num_events + 4 < pt->synth_opts.initial_skip;
+}
+
static void intel_pt_prep_a_sample(struct intel_pt_queue *ptq,
union perf_event *event,
struct perf_sample *sample)
struct perf_synth_intel_cbr raw;
u32 flags;
- if (intel_pt_skip_event(pt))
+ if (intel_pt_skip_cbr_event(pt))
return 0;
+ ptq->cbr_seen = ptq->state->cbr;
+
intel_pt_prep_p_sample(pt, ptq, event, &sample);
sample.id = ptq->pt->cbr_id;
}
#define INTEL_PT_PWR_EVT (INTEL_PT_MWAIT_OP | INTEL_PT_PWR_ENTRY | \
- INTEL_PT_EX_STOP | INTEL_PT_PWR_EXIT | \
- INTEL_PT_CBR_CHG)
+ INTEL_PT_EX_STOP | INTEL_PT_PWR_EXIT)
static int intel_pt_sample(struct intel_pt_queue *ptq)
{
return err;
}
- if (pt->sample_pwr_events && (state->type & INTEL_PT_PWR_EVT)) {
- if (state->type & INTEL_PT_CBR_CHG) {
+ if (pt->sample_pwr_events) {
+ if (ptq->state->cbr != ptq->cbr_seen) {
err = intel_pt_synth_cbr_sample(ptq);
if (err)
return err;
}
- if (state->type & INTEL_PT_MWAIT_OP) {
- err = intel_pt_synth_mwait_sample(ptq);
- if (err)
- return err;
- }
- if (state->type & INTEL_PT_PWR_ENTRY) {
- err = intel_pt_synth_pwre_sample(ptq);
- if (err)
- return err;
- }
- if (state->type & INTEL_PT_EX_STOP) {
- err = intel_pt_synth_exstop_sample(ptq);
- if (err)
- return err;
- }
- if (state->type & INTEL_PT_PWR_EXIT) {
- err = intel_pt_synth_pwrx_sample(ptq);
- if (err)
- return err;
+ if (state->type & INTEL_PT_PWR_EVT) {
+ if (state->type & INTEL_PT_MWAIT_OP) {
+ err = intel_pt_synth_mwait_sample(ptq);
+ if (err)
+ return err;
+ }
+ if (state->type & INTEL_PT_PWR_ENTRY) {
+ err = intel_pt_synth_pwre_sample(ptq);
+ if (err)
+ return err;
+ }
+ if (state->type & INTEL_PT_EX_STOP) {
+ err = intel_pt_synth_exstop_sample(ptq);
+ if (err)
+ return err;
+ }
+ if (state->type & INTEL_PT_PWR_EXIT) {
+ err = intel_pt_synth_pwrx_sample(ptq);
+ if (err)
+ return err;
+ }
}
}