提交 f38b0dbb 编写于 作者: K Kan Liang 提交者: Ingo Molnar

perf/x86/intel: Introduce PERF_RECORD_LOST_SAMPLES

After enlarging the PEBS interrupt threshold, there may be some mixed up
PEBS samples which are discarded by the kernel.

This patch makes the kernel emit a PERF_RECORD_LOST_SAMPLES record with
the number of possible discarded records when it is impossible to demux
the samples.

It makes sure the user is not left in the dark about such discards.
Signed-off-by: NKan Liang <kan.liang@intel.com>
Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: acme@infradead.org
Cc: eranian@google.com
Link: http://lkml.kernel.org/r/1431285195-14269-8-git-send-email-kan.liang@intel.comSigned-off-by: NIngo Molnar <mingo@kernel.org>
上级 15617499
...@@ -1126,6 +1126,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) ...@@ -1126,6 +1126,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
void *base, *at, *top; void *base, *at, *top;
int bit; int bit;
short counts[MAX_PEBS_EVENTS] = {}; short counts[MAX_PEBS_EVENTS] = {};
short error[MAX_PEBS_EVENTS] = {};
if (!x86_pmu.pebs_active) if (!x86_pmu.pebs_active)
return; return;
...@@ -1169,20 +1170,33 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) ...@@ -1169,20 +1170,33 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
/* slow path */ /* slow path */
pebs_status = p->status & cpuc->pebs_enabled; pebs_status = p->status & cpuc->pebs_enabled;
pebs_status &= (1ULL << MAX_PEBS_EVENTS) - 1; pebs_status &= (1ULL << MAX_PEBS_EVENTS) - 1;
if (pebs_status != (1 << bit)) if (pebs_status != (1 << bit)) {
u8 i;
for_each_set_bit(i, (unsigned long *)&pebs_status,
MAX_PEBS_EVENTS)
error[i]++;
continue; continue;
} }
}
counts[bit]++; counts[bit]++;
} }
for (bit = 0; bit < x86_pmu.max_pebs_events; bit++) { for (bit = 0; bit < x86_pmu.max_pebs_events; bit++) {
if (counts[bit] == 0) if ((counts[bit] == 0) && (error[bit] == 0))
continue; continue;
event = cpuc->events[bit]; event = cpuc->events[bit];
WARN_ON_ONCE(!event); WARN_ON_ONCE(!event);
WARN_ON_ONCE(!event->attr.precise_ip); WARN_ON_ONCE(!event->attr.precise_ip);
__intel_pmu_pebs_event(event, iregs, base, top, bit, counts[bit]); /* log dropped samples number */
if (error[bit])
perf_log_lost_samples(event, error[bit]);
if (counts[bit]) {
__intel_pmu_pebs_event(event, iregs, base,
top, bit, counts[bit]);
}
} }
} }
......
...@@ -743,6 +743,9 @@ perf_event__output_id_sample(struct perf_event *event, ...@@ -743,6 +743,9 @@ perf_event__output_id_sample(struct perf_event *event,
struct perf_output_handle *handle, struct perf_output_handle *handle,
struct perf_sample_data *sample); struct perf_sample_data *sample);
extern void
perf_log_lost_samples(struct perf_event *event, u64 lost);
static inline bool is_sampling_event(struct perf_event *event) static inline bool is_sampling_event(struct perf_event *event)
{ {
return event->attr.sample_period != 0; return event->attr.sample_period != 0;
......
...@@ -802,6 +802,18 @@ enum perf_event_type { ...@@ -802,6 +802,18 @@ enum perf_event_type {
*/ */
PERF_RECORD_ITRACE_START = 12, PERF_RECORD_ITRACE_START = 12,
/*
* Records the dropped/lost sample number.
*
* struct {
* struct perf_event_header header;
*
* u64 lost;
* struct sample_id sample_id;
* };
*/
PERF_RECORD_LOST_SAMPLES = 13,
PERF_RECORD_MAX, /* non-ABI */ PERF_RECORD_MAX, /* non-ABI */
}; };
......
...@@ -5974,6 +5974,39 @@ void perf_event_aux_event(struct perf_event *event, unsigned long head, ...@@ -5974,6 +5974,39 @@ void perf_event_aux_event(struct perf_event *event, unsigned long head,
perf_output_end(&handle); perf_output_end(&handle);
} }
/*
* Lost/dropped samples logging
*/
void perf_log_lost_samples(struct perf_event *event, u64 lost)
{
struct perf_output_handle handle;
struct perf_sample_data sample;
int ret;
struct {
struct perf_event_header header;
u64 lost;
} lost_samples_event = {
.header = {
.type = PERF_RECORD_LOST_SAMPLES,
.misc = 0,
.size = sizeof(lost_samples_event),
},
.lost = lost,
};
perf_event_header__init_id(&lost_samples_event.header, &sample, event);
ret = perf_output_begin(&handle, event,
lost_samples_event.header.size);
if (ret)
return;
perf_output_put(&handle, lost_samples_event);
perf_event__output_id_sample(event, &handle, &sample);
perf_output_end(&handle);
}
/* /*
* IRQ throttle logging * IRQ throttle logging
*/ */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册