Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 121218
b: refs/heads/master
c: 83a8df6
h: refs/heads/master
v: v3
  • Loading branch information
Frederic Weisbecker authored and Ingo Molnar committed Nov 27, 2008
1 parent fb8987e commit 0464b79
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 26 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: c072c24975ec4f0ccfcb6f5c8a8040b6eb75ef8f
refs/heads/master: 83a8df618eb04bd2819a758f3b409b1449862434
8 changes: 2 additions & 6 deletions trunk/Documentation/ftrace.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1251,11 +1251,7 @@ These are the only wild cards which are supported.

<match>*<match> will not work.

Note: It is better to use quotes to enclose the wild cards, otherwise
the shell may expand the parameters into names of files in the local
directory.

# echo 'hrtimer_*' > /debug/tracing/set_ftrace_filter
# echo hrtimer_* > /debug/tracing/set_ftrace_filter

Produces:

Expand Down Expand Up @@ -1310,7 +1306,7 @@ Again, now we want to append.
# echo sys_nanosleep > /debug/tracing/set_ftrace_filter
# cat /debug/tracing/set_ftrace_filter
sys_nanosleep
# echo 'hrtimer_*' >> /debug/tracing/set_ftrace_filter
# echo hrtimer_* >> /debug/tracing/set_ftrace_filter
# cat /debug/tracing/set_ftrace_filter
hrtimer_run_queues
hrtimer_run_pending
Expand Down
27 changes: 17 additions & 10 deletions trunk/kernel/trace/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,7 @@ enum {
#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */

struct ftrace_iterator {
loff_t pos;
struct ftrace_page *pg;
unsigned idx;
unsigned flags;
Expand All @@ -810,8 +811,6 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
iter->pg = iter->pg->next;
iter->idx = 0;
goto retry;
} else {
iter->idx = -1;
}
} else {
rec = &iter->pg->records[iter->idx++];
Expand All @@ -834,22 +833,22 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
}
spin_unlock(&ftrace_lock);

iter->pos = *pos;

return rec;
}

static void *t_start(struct seq_file *m, loff_t *pos)
{
struct ftrace_iterator *iter = m->private;
void *p = NULL;
loff_t l = -1;

if (*pos > 0) {
if (iter->idx < 0)
return p;
(*pos)--;
iter->idx--;
}
if (*pos > iter->pos)
*pos = iter->pos;

p = t_next(m, p, pos);
l = *pos;
p = t_next(m, p, &l);

return p;
}
Expand All @@ -860,15 +859,21 @@ static void t_stop(struct seq_file *m, void *p)

static int t_show(struct seq_file *m, void *v)
{
struct ftrace_iterator *iter = m->private;
struct dyn_ftrace *rec = v;
char str[KSYM_SYMBOL_LEN];
int ret = 0;

if (!rec)
return 0;

kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);

seq_printf(m, "%s\n", str);
ret = seq_printf(m, "%s\n", str);
if (ret < 0) {
iter->pos--;
iter->idx--;
}

return 0;
}
Expand All @@ -894,6 +899,7 @@ ftrace_avail_open(struct inode *inode, struct file *file)
return -ENOMEM;

iter->pg = ftrace_pages_start;
iter->pos = 0;

ret = seq_open(file, &show_ftrace_seq_ops);
if (!ret) {
Expand Down Expand Up @@ -980,6 +986,7 @@ ftrace_regex_open(struct inode *inode, struct file *file, int enable)

if (file->f_mode & FMODE_READ) {
iter->pg = ftrace_pages_start;
iter->pos = 0;
iter->flags = enable ? FTRACE_ITER_FILTER :
FTRACE_ITER_NOTRACE;

Expand Down
168 changes: 159 additions & 9 deletions trunk/kernel/trace/trace_functions_graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
#include "trace.h"

#define TRACE_GRAPH_INDENT 2
/* Spaces between function call and time duration */
#define TRACE_GRAPH_TIMESPACE_ENTRY " "
/* Spaces between function call and closing braces */
#define TRACE_GRAPH_TIMESPACE_RET " "

#define TRACE_GRAPH_PRINT_OVERRUN 0x1
static struct tracer_opt trace_opts[] = {
Expand Down Expand Up @@ -63,26 +67,130 @@ static int verif_pid(struct trace_seq *s, pid_t pid, int cpu)
last_pid[cpu] = pid;
comm = trace_find_cmdline(pid);

return trace_seq_printf(s, "\nCPU[%03d]"
return trace_seq_printf(s, "\nCPU[%03d] "
" ------------8<---------- thread %s-%d"
" ------------8<----------\n\n",
cpu, comm, pid);
}

static bool
trace_branch_is_leaf(struct trace_iterator *iter,
struct ftrace_graph_ent_entry *curr)
{
struct ring_buffer_iter *ring_iter;
struct ring_buffer_event *event;
struct ftrace_graph_ret_entry *next;

ring_iter = iter->buffer_iter[iter->cpu];

if (!ring_iter)
return false;

event = ring_buffer_iter_peek(iter->buffer_iter[iter->cpu], NULL);

if (!event)
return false;

next = ring_buffer_event_data(event);

if (next->ent.type != TRACE_GRAPH_RET)
return false;

if (curr->ent.pid != next->ent.pid ||
curr->graph_ent.func != next->ret.func)
return false;

return true;
}


static inline int
print_graph_duration(unsigned long long duration, struct trace_seq *s)
{
unsigned long nsecs_rem = do_div(duration, 1000);
return trace_seq_printf(s, "+ %llu.%lu us\n", duration, nsecs_rem);
}

/* Signal a overhead of time execution to the output */
static int
print_graph_overhead(unsigned long long duration, struct trace_seq *s)
{
/* Duration exceeded 100 msecs */
if (duration > 100000ULL)
return trace_seq_printf(s, "! ");

/* Duration exceeded 10 msecs */
if (duration > 10000ULL)
return trace_seq_printf(s, "+ ");

return trace_seq_printf(s, " ");
}

/* Case of a leaf function on its call entry */
static enum print_line_t
print_graph_entry(struct ftrace_graph_ent *call, struct trace_seq *s,
struct trace_entry *ent, int cpu)
print_graph_entry_leaf(struct trace_iterator *iter,
struct ftrace_graph_ent_entry *entry, struct trace_seq *s)
{
struct ftrace_graph_ret_entry *ret_entry;
struct ftrace_graph_ret *graph_ret;
struct ring_buffer_event *event;
struct ftrace_graph_ent *call;
unsigned long long duration;
int i;
int ret;

if (!verif_pid(s, ent->pid, cpu))
event = ring_buffer_read(iter->buffer_iter[iter->cpu], NULL);
ret_entry = ring_buffer_event_data(event);
graph_ret = &ret_entry->ret;
call = &entry->graph_ent;
duration = graph_ret->rettime - graph_ret->calltime;

/* Overhead */
ret = print_graph_overhead(duration, s);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

ret = trace_seq_printf(s, "CPU[%03d] ", cpu);
/* Function */
for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) {
ret = trace_seq_printf(s, " ");
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
}

ret = seq_print_ip_sym(s, call->func, 0);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

ret = trace_seq_printf(s, "();");
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

/* Duration */
ret = trace_seq_printf(s, TRACE_GRAPH_TIMESPACE_ENTRY);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

ret = print_graph_duration(duration, s);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

return TRACE_TYPE_HANDLED;
}

static enum print_line_t
print_graph_entry_nested(struct ftrace_graph_ent_entry *entry,
struct trace_seq *s)
{
int i;
int ret;
struct ftrace_graph_ent *call = &entry->graph_ent;

/* No overhead */
ret = trace_seq_printf(s, " ");
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

/* Function */
for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) {
ret = trace_seq_printf(s, " ");
if (!ret)
Expand All @@ -93,26 +201,62 @@ print_graph_entry(struct ftrace_graph_ent *call, struct trace_seq *s,
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

ret = trace_seq_printf(s, "() {\n");
ret = trace_seq_printf(s, "() {");
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

/* No duration to print at this state */
ret = trace_seq_printf(s, TRACE_GRAPH_TIMESPACE_ENTRY "-\n");
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

return TRACE_TYPE_HANDLED;
}

static enum print_line_t
print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
struct trace_iterator *iter, int cpu)
{
int ret;
struct trace_entry *ent = iter->ent;

if (!verif_pid(s, ent->pid, cpu))
return TRACE_TYPE_PARTIAL_LINE;

ret = trace_seq_printf(s, "CPU[%03d] ", cpu);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

if (trace_branch_is_leaf(iter, field))
return print_graph_entry_leaf(iter, field, s);
else
return print_graph_entry_nested(field, s);

}

static enum print_line_t
print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
struct trace_entry *ent, int cpu)
{
int i;
int ret;
unsigned long long duration = trace->rettime - trace->calltime;

/* Pid */
if (!verif_pid(s, ent->pid, cpu))
return TRACE_TYPE_PARTIAL_LINE;

/* Cpu */
ret = trace_seq_printf(s, "CPU[%03d] ", cpu);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

/* Overhead */
ret = print_graph_overhead(duration, s);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

/* Closing brace */
for (i = 0; i < trace->depth * TRACE_GRAPH_INDENT; i++) {
ret = trace_seq_printf(s, " ");
if (!ret)
Expand All @@ -123,10 +267,16 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

ret = trace_seq_printf(s, "%llu\n", trace->rettime - trace->calltime);
/* Duration */
ret = trace_seq_printf(s, TRACE_GRAPH_TIMESPACE_RET);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

ret = print_graph_duration(duration, s);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

/* Overrun */
if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERRUN) {
ret = trace_seq_printf(s, " (Overruns: %lu)\n",
trace->overrun);
Expand All @@ -146,7 +296,7 @@ print_graph_function(struct trace_iterator *iter)
case TRACE_GRAPH_ENT: {
struct ftrace_graph_ent_entry *field;
trace_assign_type(field, entry);
return print_graph_entry(&field->graph_ent, s, entry,
return print_graph_entry(field, s, iter,
iter->cpu);
}
case TRACE_GRAPH_RET: {
Expand All @@ -160,7 +310,7 @@ print_graph_function(struct trace_iterator *iter)
}

static struct tracer graph_trace __read_mostly = {
.name = "function-graph",
.name = "function_graph",
.init = graph_trace_init,
.reset = graph_trace_reset,
.print_line = print_graph_function,
Expand Down

0 comments on commit 0464b79

Please sign in to comment.