Skip to content

Commit

Permalink
perf/core: Add weighted samples
Browse files Browse the repository at this point in the history
For some events it's useful to weight sample with a hardware
provided number. This expresses how expensive the action the
sample represent was.  This allows the profiler to scale
the samples to be more informative to the programmer.

There is already the period which is used similarly, but it
means something different, so I chose to not overload it.
Instead a new sample type for WEIGHT is added.

Can be used for multiple things. Initially it is used for TSX
abort costs and profiling by memory latencies (so to make
expensive load appear higher up in the histograms). The concept
is quite generic and can be extended to many other kinds of
events or architectures, as long as the hardware provides
suitable auxillary values. In principle it could be also used
for software tracepoints.

This adds the generic glue. A new optional sample format for a
64-bit weight value.

Signed-off-by: Andi Kleen <[email protected]>
Signed-off-by: Stephane Eranian <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
Andi Kleen authored and acmel committed Apr 1, 2013
1 parent 9fac2cf commit c3feedf
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 1 deletion.
2 changes: 2 additions & 0 deletions include/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,7 @@ struct perf_sample_data {
struct perf_branch_stack *br_stack;
struct perf_regs_user regs_user;
u64 stack_user_size;
u64 weight;
};

static inline void perf_sample_data_init(struct perf_sample_data *data,
Expand All @@ -586,6 +587,7 @@ static inline void perf_sample_data_init(struct perf_sample_data *data,
data->regs_user.abi = PERF_SAMPLE_REGS_ABI_NONE;
data->regs_user.regs = NULL;
data->stack_user_size = 0;
data->weight = 0;
}

extern void perf_output_sample(struct perf_output_handle *handle,
Expand Down
6 changes: 5 additions & 1 deletion include/uapi/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,10 @@ enum perf_event_sample_format {
PERF_SAMPLE_BRANCH_STACK = 1U << 11,
PERF_SAMPLE_REGS_USER = 1U << 12,
PERF_SAMPLE_STACK_USER = 1U << 13,
PERF_SAMPLE_WEIGHT = 1U << 14,

PERF_SAMPLE_MAX = 1U << 15, /* non-ABI */

PERF_SAMPLE_MAX = 1U << 14, /* non-ABI */
};

/*
Expand Down Expand Up @@ -588,6 +590,8 @@ enum perf_event_type {
* { u64 size;
* char data[size];
* u64 dyn_size; } && PERF_SAMPLE_STACK_USER
*
* { u64 weight; } && PERF_SAMPLE_WEIGHT
* };
*/
PERF_RECORD_SAMPLE = 9,
Expand Down
6 changes: 6 additions & 0 deletions kernel/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,9 @@ static void perf_event__header_size(struct perf_event *event)
if (sample_type & PERF_SAMPLE_PERIOD)
size += sizeof(data->period);

if (sample_type & PERF_SAMPLE_WEIGHT)
size += sizeof(data->weight);

if (sample_type & PERF_SAMPLE_READ)
size += event->read_size;

Expand Down Expand Up @@ -4193,6 +4196,9 @@ void perf_output_sample(struct perf_output_handle *handle,
perf_output_sample_ustack(handle,
data->stack_user_size,
data->regs_user.regs);

if (sample_type & PERF_SAMPLE_WEIGHT)
perf_output_put(handle, data->weight);
}

void perf_prepare_sample(struct perf_event_header *header,
Expand Down

0 comments on commit c3feedf

Please sign in to comment.