ftrace: add wakeup events to sched tracer
Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
e309b41dd6
commit
57422797dc
5 changed files with 88 additions and 5 deletions
|
@ -57,7 +57,7 @@ static struct trace_array max_tr;
|
||||||
static DEFINE_PER_CPU(struct trace_array_cpu, max_data);
|
static DEFINE_PER_CPU(struct trace_array_cpu, max_data);
|
||||||
|
|
||||||
static int tracer_enabled = 1;
|
static int tracer_enabled = 1;
|
||||||
static unsigned long trace_nr_entries = 16384UL;
|
static unsigned long trace_nr_entries = 65536UL;
|
||||||
|
|
||||||
static struct tracer *trace_types __read_mostly;
|
static struct tracer *trace_types __read_mostly;
|
||||||
static struct tracer *current_trace __read_mostly;
|
static struct tracer *current_trace __read_mostly;
|
||||||
|
@ -87,6 +87,7 @@ enum trace_type {
|
||||||
|
|
||||||
TRACE_FN,
|
TRACE_FN,
|
||||||
TRACE_CTX,
|
TRACE_CTX,
|
||||||
|
TRACE_WAKE,
|
||||||
TRACE_SPECIAL,
|
TRACE_SPECIAL,
|
||||||
|
|
||||||
__TRACE_LAST_TYPE
|
__TRACE_LAST_TYPE
|
||||||
|
@ -711,6 +712,30 @@ tracing_sched_switch_trace(struct trace_array *tr,
|
||||||
wake_up (&trace_wait);
|
wake_up (&trace_wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tracing_sched_wakeup_trace(struct trace_array *tr,
|
||||||
|
struct trace_array_cpu *data,
|
||||||
|
struct task_struct *wakee, struct task_struct *curr,
|
||||||
|
unsigned long flags)
|
||||||
|
{
|
||||||
|
struct trace_entry *entry;
|
||||||
|
unsigned long irq_flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&data->lock, irq_flags);
|
||||||
|
entry = tracing_get_trace_entry(tr, data);
|
||||||
|
tracing_generic_entry_update(entry, flags);
|
||||||
|
entry->type = TRACE_WAKE;
|
||||||
|
entry->ctx.prev_pid = curr->pid;
|
||||||
|
entry->ctx.prev_prio = curr->prio;
|
||||||
|
entry->ctx.prev_state = curr->state;
|
||||||
|
entry->ctx.next_pid = wakee->pid;
|
||||||
|
entry->ctx.next_prio = wakee->prio;
|
||||||
|
spin_unlock_irqrestore(&data->lock, irq_flags);
|
||||||
|
|
||||||
|
if (!(trace_flags & TRACE_ITER_BLOCK))
|
||||||
|
wake_up(&trace_wait);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FTRACE
|
#ifdef CONFIG_FTRACE
|
||||||
static void
|
static void
|
||||||
function_trace_call(unsigned long ip, unsigned long parent_ip)
|
function_trace_call(unsigned long ip, unsigned long parent_ip)
|
||||||
|
@ -1183,13 +1208,14 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
|
||||||
trace_seq_puts(s, ")\n");
|
trace_seq_puts(s, ")\n");
|
||||||
break;
|
break;
|
||||||
case TRACE_CTX:
|
case TRACE_CTX:
|
||||||
|
case TRACE_WAKE:
|
||||||
S = entry->ctx.prev_state < sizeof(state_to_char) ?
|
S = entry->ctx.prev_state < sizeof(state_to_char) ?
|
||||||
state_to_char[entry->ctx.prev_state] : 'X';
|
state_to_char[entry->ctx.prev_state] : 'X';
|
||||||
comm = trace_find_cmdline(entry->ctx.next_pid);
|
comm = trace_find_cmdline(entry->ctx.next_pid);
|
||||||
trace_seq_printf(s, " %d:%d:%c --> %d:%d %s\n",
|
trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d %s\n",
|
||||||
entry->ctx.prev_pid,
|
entry->ctx.prev_pid,
|
||||||
entry->ctx.prev_prio,
|
entry->ctx.prev_prio,
|
||||||
S,
|
S, entry->type == TRACE_CTX ? "==>" : " +",
|
||||||
entry->ctx.next_pid,
|
entry->ctx.next_pid,
|
||||||
entry->ctx.next_prio,
|
entry->ctx.next_prio,
|
||||||
comm);
|
comm);
|
||||||
|
@ -1256,12 +1282,14 @@ static int print_trace_fmt(struct trace_iterator *iter)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case TRACE_CTX:
|
case TRACE_CTX:
|
||||||
|
case TRACE_WAKE:
|
||||||
S = entry->ctx.prev_state < sizeof(state_to_char) ?
|
S = entry->ctx.prev_state < sizeof(state_to_char) ?
|
||||||
state_to_char[entry->ctx.prev_state] : 'X';
|
state_to_char[entry->ctx.prev_state] : 'X';
|
||||||
ret = trace_seq_printf(s, " %d:%d:%c ==> %d:%d\n",
|
ret = trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d\n",
|
||||||
entry->ctx.prev_pid,
|
entry->ctx.prev_pid,
|
||||||
entry->ctx.prev_prio,
|
entry->ctx.prev_prio,
|
||||||
S,
|
S,
|
||||||
|
entry->type == TRACE_CTX ? "==>" : " +",
|
||||||
entry->ctx.next_pid,
|
entry->ctx.next_pid,
|
||||||
entry->ctx.next_prio);
|
entry->ctx.next_prio);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
@ -1301,8 +1329,11 @@ static int print_raw_fmt(struct trace_iterator *iter)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case TRACE_CTX:
|
case TRACE_CTX:
|
||||||
|
case TRACE_WAKE:
|
||||||
S = entry->ctx.prev_state < sizeof(state_to_char) ?
|
S = entry->ctx.prev_state < sizeof(state_to_char) ?
|
||||||
state_to_char[entry->ctx.prev_state] : 'X';
|
state_to_char[entry->ctx.prev_state] : 'X';
|
||||||
|
if (entry->type == TRACE_WAKE)
|
||||||
|
S = '+';
|
||||||
ret = trace_seq_printf(s, "%d %d %c %d %d\n",
|
ret = trace_seq_printf(s, "%d %d %c %d %d\n",
|
||||||
entry->ctx.prev_pid,
|
entry->ctx.prev_pid,
|
||||||
entry->ctx.prev_prio,
|
entry->ctx.prev_prio,
|
||||||
|
@ -1355,8 +1386,11 @@ static int print_hex_fmt(struct trace_iterator *iter)
|
||||||
SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip);
|
SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip);
|
||||||
break;
|
break;
|
||||||
case TRACE_CTX:
|
case TRACE_CTX:
|
||||||
|
case TRACE_WAKE:
|
||||||
S = entry->ctx.prev_state < sizeof(state_to_char) ?
|
S = entry->ctx.prev_state < sizeof(state_to_char) ?
|
||||||
state_to_char[entry->ctx.prev_state] : 'X';
|
state_to_char[entry->ctx.prev_state] : 'X';
|
||||||
|
if (entry->type == TRACE_WAKE)
|
||||||
|
S = '+';
|
||||||
SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_pid);
|
SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_pid);
|
||||||
SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_prio);
|
SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_prio);
|
||||||
SEQ_PUT_HEX_FIELD_RET(s, S);
|
SEQ_PUT_HEX_FIELD_RET(s, S);
|
||||||
|
|
|
@ -164,6 +164,12 @@ void tracing_sched_switch_trace(struct trace_array *tr,
|
||||||
struct task_struct *next,
|
struct task_struct *next,
|
||||||
unsigned long flags);
|
unsigned long flags);
|
||||||
void tracing_record_cmdline(struct task_struct *tsk);
|
void tracing_record_cmdline(struct task_struct *tsk);
|
||||||
|
|
||||||
|
void tracing_sched_wakeup_trace(struct trace_array *tr,
|
||||||
|
struct trace_array_cpu *data,
|
||||||
|
struct task_struct *wakee,
|
||||||
|
struct task_struct *cur,
|
||||||
|
unsigned long flags);
|
||||||
void trace_special(struct trace_array *tr,
|
void trace_special(struct trace_array *tr,
|
||||||
struct trace_array_cpu *data,
|
struct trace_array_cpu *data,
|
||||||
unsigned long arg1,
|
unsigned long arg1,
|
||||||
|
@ -194,11 +200,17 @@ extern cycle_t ftrace_now(int cpu);
|
||||||
#ifdef CONFIG_SCHED_TRACER
|
#ifdef CONFIG_SCHED_TRACER
|
||||||
extern void
|
extern void
|
||||||
wakeup_sched_switch(struct task_struct *prev, struct task_struct *next);
|
wakeup_sched_switch(struct task_struct *prev, struct task_struct *next);
|
||||||
|
extern void
|
||||||
|
wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr);
|
||||||
#else
|
#else
|
||||||
static inline void
|
static inline void
|
||||||
wakeup_sched_switch(struct task_struct *prev, struct task_struct *next)
|
wakeup_sched_switch(struct task_struct *prev, struct task_struct *next)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
static inline void
|
||||||
|
wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr)
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_CONTEXT_SWITCH_TRACER
|
#ifdef CONFIG_CONTEXT_SWITCH_TRACER
|
||||||
|
|
|
@ -41,6 +41,29 @@ ctx_switch_func(struct task_struct *prev, struct task_struct *next)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wakeup_func(struct task_struct *wakee, struct task_struct *curr)
|
||||||
|
{
|
||||||
|
struct trace_array *tr = ctx_trace;
|
||||||
|
struct trace_array_cpu *data;
|
||||||
|
unsigned long flags;
|
||||||
|
long disabled;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
if (!tracer_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
cpu = raw_smp_processor_id();
|
||||||
|
data = tr->data[cpu];
|
||||||
|
disabled = atomic_inc_return(&data->disabled);
|
||||||
|
|
||||||
|
if (likely(disabled == 1))
|
||||||
|
tracing_sched_wakeup_trace(tr, data, wakee, curr, flags);
|
||||||
|
|
||||||
|
atomic_dec(&data->disabled);
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next)
|
void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next)
|
||||||
{
|
{
|
||||||
tracing_record_cmdline(prev);
|
tracing_record_cmdline(prev);
|
||||||
|
@ -57,6 +80,19 @@ void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next)
|
||||||
wakeup_sched_switch(prev, next);
|
wakeup_sched_switch(prev, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr)
|
||||||
|
{
|
||||||
|
tracing_record_cmdline(curr);
|
||||||
|
|
||||||
|
wakeup_func(wakee, curr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chain to the wakeup tracer (this is a NOP if disabled):
|
||||||
|
*/
|
||||||
|
wakeup_sched_wakeup(wakee, curr);
|
||||||
|
}
|
||||||
|
|
||||||
static void sched_switch_reset(struct trace_array *tr)
|
static void sched_switch_reset(struct trace_array *tr)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
|
@ -202,7 +202,7 @@ wakeup_check_start(struct trace_array *tr, struct task_struct *p,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr)
|
wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr)
|
||||||
{
|
{
|
||||||
if (likely(!tracer_enabled))
|
if (likely(!tracer_enabled))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -8,6 +8,7 @@ static inline int trace_valid_entry(struct trace_entry *entry)
|
||||||
switch (entry->type) {
|
switch (entry->type) {
|
||||||
case TRACE_FN:
|
case TRACE_FN:
|
||||||
case TRACE_CTX:
|
case TRACE_CTX:
|
||||||
|
case TRACE_WAKE:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue