Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 156573
b: refs/heads/master
c: f413cdb
h: refs/heads/master
i:
  156571: e1da0c4
v: v3
  • Loading branch information
Frederic Weisbecker authored and Ingo Molnar committed Aug 9, 2009
1 parent 2069f07 commit 60d1db6
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 42 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3a6593050fbd8bbcaed3a44d01c31d907315c86c
refs/heads/master: f413cdb80ce00ec1a4d0ab949b5d96c81cae7f75
4 changes: 3 additions & 1 deletion trunk/include/linux/ftrace_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ enum print_line_t {
TRACE_TYPE_NO_CONSUME = 3 /* Handled but ask to not consume */
};


void tracing_generic_entry_update(struct trace_entry *entry,
unsigned long flags,
int pc);
struct ring_buffer_event *
trace_current_buffer_lock_reserve(int type, unsigned long len,
unsigned long flags, int pc);
Expand Down
9 changes: 8 additions & 1 deletion trunk/include/linux/perf_counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,9 @@ enum perf_counter_sample_format {
PERF_SAMPLE_CPU = 1U << 7,
PERF_SAMPLE_PERIOD = 1U << 8,
PERF_SAMPLE_STREAM_ID = 1U << 9,
PERF_SAMPLE_TP_RECORD = 1U << 10,

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

/*
Expand Down Expand Up @@ -413,6 +414,11 @@ struct perf_callchain_entry {
__u64 ip[PERF_MAX_STACK_DEPTH];
};

struct perf_tracepoint_record {
int size;
char *record;
};

struct task_struct;

/**
Expand Down Expand Up @@ -681,6 +687,7 @@ struct perf_sample_data {
struct pt_regs *regs;
u64 addr;
u64 period;
void *private;
};

extern int perf_counter_overflow(struct perf_counter *counter, int nmi,
Expand Down
130 changes: 96 additions & 34 deletions trunk/include/trace/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,15 +353,7 @@ static inline int ftrace_get_offsets_##call( \
/*
* Generate the functions needed for tracepoint perf_counter support.
*
* static void ftrace_profile_<call>(proto)
* {
* extern void perf_tpcounter_event(int, u64, u64);
* u64 __addr = 0, __count = 1;
*
* <assign> <-- here we expand the TP_perf_assign() macro
*
* perf_tpcounter_event(event_<call>.id, __addr, __count);
* }
* NOTE: The insertion profile callback (ftrace_profile_<call>) is defined later
*
* static int ftrace_profile_enable_<call>(struct ftrace_event_call *event_call)
* {
Expand All @@ -381,28 +373,10 @@ static inline int ftrace_get_offsets_##call( \
*
*/

#undef TP_fast_assign
#define TP_fast_assign(args...)

#undef TP_perf_assign
#define TP_perf_assign(args...) args

#undef __perf_addr
#define __perf_addr(a) __addr = (a)

#undef __perf_count
#define __perf_count(c) __count = (c)

#undef TRACE_EVENT
#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
\
static void ftrace_profile_##call(proto) \
{ \
extern void perf_tpcounter_event(int, u64, u64); \
u64 __addr = 0, __count = 1; \
{ assign; } \
perf_tpcounter_event(event_##call.id, __addr, __count); \
} \
static void ftrace_profile_##call(proto); \
\
static int ftrace_profile_enable_##call(struct ftrace_event_call *event_call) \
{ \
Expand All @@ -422,12 +396,6 @@ static void ftrace_profile_disable_##call(struct ftrace_event_call *event_call)\

#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)

#undef TP_fast_assign
#define TP_fast_assign(args...) args

#undef TP_perf_assign
#define TP_perf_assign(args...)

#endif

/*
Expand Down Expand Up @@ -647,5 +615,99 @@ __attribute__((section("_ftrace_events"))) event_##call = { \

#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)

/*
* Define the insertion callback to profile events
*
* The job is very similar to ftrace_raw_event_<call> except that we don't
* insert in the ring buffer but in a perf counter.
*
* static void ftrace_profile_<call>(proto)
* {
* struct ftrace_data_offsets_<call> __maybe_unused __data_offsets;
* struct ftrace_event_call *event_call = &event_<call>;
* extern void perf_tpcounter_event(int, u64, u64, void *, int);
* struct ftrace_raw_##call *entry;
* u64 __addr = 0, __count = 1;
* unsigned long irq_flags;
* int __entry_size;
* int __data_size;
* int pc;
*
* local_save_flags(irq_flags);
* pc = preempt_count();
*
* __data_size = ftrace_get_offsets_<call>(&__data_offsets, args);
* __entry_size = __data_size + sizeof(*entry);
*
* do {
* char raw_data[__entry_size]; <- allocate our sample in the stack
* struct trace_entry *ent;
*
* entry = (struct ftrace_raw_<call> *)raw_data;
* ent = &entry->ent;
* tracing_generic_entry_update(ent, irq_flags, pc);
* ent->type = event_call->id;
*
* <tstruct> <- do some jobs with dynamic arrays
*
* <assign> <- affect our values
*
* perf_tpcounter_event(event_call->id, __addr, __count, entry,
* __entry_size); <- submit them to perf counter
* } while (0);
*
* }
*/

#ifdef CONFIG_EVENT_PROFILE

#undef __perf_addr
#define __perf_addr(a) __addr = (a)

#undef __perf_count
#define __perf_count(c) __count = (c)

#undef TRACE_EVENT
#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
static void ftrace_profile_##call(proto) \
{ \
struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
struct ftrace_event_call *event_call = &event_##call; \
extern void perf_tpcounter_event(int, u64, u64, void *, int); \
struct ftrace_raw_##call *entry; \
u64 __addr = 0, __count = 1; \
unsigned long irq_flags; \
int __entry_size; \
int __data_size; \
int pc; \
\
local_save_flags(irq_flags); \
pc = preempt_count(); \
\
__data_size = ftrace_get_offsets_##call(&__data_offsets, args); \
__entry_size = ALIGN(__data_size + sizeof(*entry), sizeof(u64));\
\
do { \
char raw_data[__entry_size]; \
struct trace_entry *ent; \
\
entry = (struct ftrace_raw_##call *)raw_data; \
ent = &entry->ent; \
tracing_generic_entry_update(ent, irq_flags, pc); \
ent->type = event_call->id; \
\
tstruct \
\
{ assign; } \
\
perf_tpcounter_event(event_call->id, __addr, __count, entry,\
__entry_size); \
} while (0); \
\
}

#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
#endif /* CONFIG_EVENT_PROFILE */

#undef _TRACE_PROFILE_INIT

18 changes: 17 additions & 1 deletion trunk/kernel/perf_counter.c
Original file line number Diff line number Diff line change
Expand Up @@ -2646,6 +2646,7 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
u64 counter;
} group_entry;
struct perf_callchain_entry *callchain = NULL;
struct perf_tracepoint_record *tp;
int callchain_size = 0;
u64 time;
struct {
Expand Down Expand Up @@ -2714,6 +2715,11 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
header.size += sizeof(u64);
}

if (sample_type & PERF_SAMPLE_TP_RECORD) {
tp = data->private;
header.size += tp->size;
}

ret = perf_output_begin(&handle, counter, header.size, nmi, 1);
if (ret)
return;
Expand Down Expand Up @@ -2777,6 +2783,9 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
}
}

if (sample_type & PERF_SAMPLE_TP_RECORD)
perf_output_copy(&handle, tp->record, tp->size);

perf_output_end(&handle);
}

Expand Down Expand Up @@ -3703,11 +3712,18 @@ static const struct pmu perf_ops_task_clock = {
};

#ifdef CONFIG_EVENT_PROFILE
void perf_tpcounter_event(int event_id, u64 addr, u64 count)
void perf_tpcounter_event(int event_id, u64 addr, u64 count, void *record,
int entry_size)
{
struct perf_tracepoint_record tp = {
.size = entry_size,
.record = record,
};

struct perf_sample_data data = {
.regs = get_irq_regs(),
.addr = addr,
.private = &tp,
};

if (!data.regs)
Expand Down
1 change: 1 addition & 0 deletions trunk/kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
(need_resched() ? TRACE_FLAG_NEED_RESCHED : 0);
}
EXPORT_SYMBOL_GPL(tracing_generic_entry_update);

struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
int type,
Expand Down
4 changes: 0 additions & 4 deletions trunk/kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,10 +438,6 @@ struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
int *ent_cpu, u64 *ent_ts);

void tracing_generic_entry_update(struct trace_entry *entry,
unsigned long flags,
int pc);

void default_wait_pipe(struct trace_iterator *iter);
void poll_wait_pipe(struct trace_iterator *iter);

Expand Down
1 change: 1 addition & 0 deletions trunk/tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ static void create_counter(int counter, int cpu, pid_t pid)
if (call_graph)
attr->sample_type |= PERF_SAMPLE_CALLCHAIN;


attr->mmap = track;
attr->comm = track;
attr->inherit = (cpu < 0) && inherit;
Expand Down

0 comments on commit 60d1db6

Please sign in to comment.