RE: [PATCH V8 7/8] perf, x86: introduce PERF_RECORD_LOST_SAMPLES

From: Liang, Kan
Date: Thu May 07 2015 - 09:56:22 EST



>
>
> So I changed it slightly to the below; changes are:
>
> - record 'lost' events to all set bits; after all we really do not
> know which event this sample belonged to, only logging to the first
> set bit seems 'wrong'.

If so, the same dropped sample will be count multiple times. It's hard to know
the exact number of dropped samples.

>
> - dropped the @id field from the record, it is already included in the
> @sample_id values.
> ---
> Subject: perf, x86: introduce PERF_RECORD_LOST_SAMPLES
> From: Kan Liang <kan.liang@xxxxxxxxx>
> Date: Wed, 6 May 2015 15:33:53 -0400
>
> After enlarging the PEBS interrupt threshold, there may be some mixed up
> PEBS samples which are discarded by kernel. This patch drives the kernel to
> emit a PERF_RECORD_LOST_SAMPLES record with the number of possible
> discards when it is impossible to demux the samples. It makes sure the
> user is not left in the dark about such discards.
>
> Cc: acme@xxxxxxxxxxxxx
> Cc: eranian@xxxxxxxxxx
> Cc: andi@xxxxxxxxxxxxxx
> Cc: mingo@xxxxxxxxxx
> Signed-off-by: Kan Liang <kan.liang@xxxxxxxxx>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
> Link: http://lkml.kernel.org/r/1430940834-8964-8-git-send-email-
> kan.liang@xxxxxxxxx
> ---
> arch/x86/kernel/cpu/perf_event_intel_ds.c | 22 ++++++++++++++++----
> include/linux/perf_event.h | 3 ++
> include/uapi/linux/perf_event.h | 12 ++++++++++
> kernel/events/core.c | 33
> ++++++++++++++++++++++++++++++
> 4 files changed, 66 insertions(+), 4 deletions(-)
>
> --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
> +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
> @@ -1124,8 +1124,9 @@ static void intel_pmu_drain_pebs_nhm(str
> struct debug_store *ds = cpuc->ds;
> struct perf_event *event;
> void *base, *at, *top;
> - int bit;
> short counts[MAX_PEBS_EVENTS] = {};
> + short error[MAX_PEBS_EVENTS] = {};
> + int bit, i;
>
> if (!x86_pmu.pebs_active)
> return;
> @@ -1169,20 +1170,33 @@ static void intel_pmu_drain_pebs_nhm(str
> /* slow path */
> pebs_status = p->status & cpuc->pebs_enabled;
> pebs_status &= (1ULL << MAX_PEBS_EVENTS) - 1;
> - if (pebs_status != (1 << bit))
> + if (pebs_status != (1 << bit)) {
> + for (i = 0; 1 < MAX_PEBS_EVENTS; i++) {
> + if (pebs_status & (1 << i))
> + error[i]++;
> + }
> continue;
> + }
> }
> counts[bit]++;
> }
>
> for (bit = 0; bit < x86_pmu.max_pebs_events; bit++) {
> - if (counts[bit] == 0)
> + if ((counts[bit] == 0) && (error[bit] == 0))
> continue;
> +
> event = cpuc->events[bit];
> WARN_ON_ONCE(!event);
> 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]);
> + }
> }
> }
>
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -747,6 +747,9 @@ perf_event__output_id_sample(struct perf
> struct perf_output_handle *handle,
> 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) {
> return event->attr.sample_period != 0;
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -800,6 +800,18 @@ enum perf_event_type {
> */
> 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 */
> };
>
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -5947,6 +5947,39 @@ void perf_event_aux_event(struct perf_ev }
>
> /*
> + * 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
> */
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo
> info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/