Merge branch 'master' into for-2.6.35
Conflicts: fs/ext3/fsync.c Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
@@ -117,9 +117,12 @@ static cpumask_var_t __read_mostly tracing_buffer_mask;
|
||||
*
|
||||
* It is default off, but you can enable it with either specifying
|
||||
* "ftrace_dump_on_oops" in the kernel command line, or setting
|
||||
* /proc/sys/kernel/ftrace_dump_on_oops to true.
|
||||
* /proc/sys/kernel/ftrace_dump_on_oops
|
||||
* Set 1 if you want to dump buffers of all CPUs
|
||||
* Set 2 if you want to dump the buffer of the CPU that triggered oops
|
||||
*/
|
||||
int ftrace_dump_on_oops;
|
||||
|
||||
enum ftrace_dump_mode ftrace_dump_on_oops;
|
||||
|
||||
static int tracing_set_tracer(const char *buf);
|
||||
|
||||
@@ -139,8 +142,17 @@ __setup("ftrace=", set_cmdline_ftrace);
|
||||
|
||||
static int __init set_ftrace_dump_on_oops(char *str)
|
||||
{
|
||||
ftrace_dump_on_oops = 1;
|
||||
return 1;
|
||||
if (*str++ != '=' || !*str) {
|
||||
ftrace_dump_on_oops = DUMP_ALL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp("orig_cpu", str)) {
|
||||
ftrace_dump_on_oops = DUMP_ORIG;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
__setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops);
|
||||
|
||||
@@ -1545,7 +1557,8 @@ static void trace_iterator_increment(struct trace_iterator *iter)
|
||||
}
|
||||
|
||||
static struct trace_entry *
|
||||
peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts)
|
||||
peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts,
|
||||
unsigned long *lost_events)
|
||||
{
|
||||
struct ring_buffer_event *event;
|
||||
struct ring_buffer_iter *buf_iter = iter->buffer_iter[cpu];
|
||||
@@ -1556,7 +1569,8 @@ peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts)
|
||||
if (buf_iter)
|
||||
event = ring_buffer_iter_peek(buf_iter, ts);
|
||||
else
|
||||
event = ring_buffer_peek(iter->tr->buffer, cpu, ts);
|
||||
event = ring_buffer_peek(iter->tr->buffer, cpu, ts,
|
||||
lost_events);
|
||||
|
||||
ftrace_enable_cpu();
|
||||
|
||||
@@ -1564,10 +1578,12 @@ peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts)
|
||||
}
|
||||
|
||||
static struct trace_entry *
|
||||
__find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
|
||||
__find_next_entry(struct trace_iterator *iter, int *ent_cpu,
|
||||
unsigned long *missing_events, u64 *ent_ts)
|
||||
{
|
||||
struct ring_buffer *buffer = iter->tr->buffer;
|
||||
struct trace_entry *ent, *next = NULL;
|
||||
unsigned long lost_events = 0, next_lost = 0;
|
||||
int cpu_file = iter->cpu_file;
|
||||
u64 next_ts = 0, ts;
|
||||
int next_cpu = -1;
|
||||
@@ -1580,7 +1596,7 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
|
||||
if (cpu_file > TRACE_PIPE_ALL_CPU) {
|
||||
if (ring_buffer_empty_cpu(buffer, cpu_file))
|
||||
return NULL;
|
||||
ent = peek_next_entry(iter, cpu_file, ent_ts);
|
||||
ent = peek_next_entry(iter, cpu_file, ent_ts, missing_events);
|
||||
if (ent_cpu)
|
||||
*ent_cpu = cpu_file;
|
||||
|
||||
@@ -1592,7 +1608,7 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
|
||||
if (ring_buffer_empty_cpu(buffer, cpu))
|
||||
continue;
|
||||
|
||||
ent = peek_next_entry(iter, cpu, &ts);
|
||||
ent = peek_next_entry(iter, cpu, &ts, &lost_events);
|
||||
|
||||
/*
|
||||
* Pick the entry with the smallest timestamp:
|
||||
@@ -1601,6 +1617,7 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
|
||||
next = ent;
|
||||
next_cpu = cpu;
|
||||
next_ts = ts;
|
||||
next_lost = lost_events;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1610,6 +1627,9 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
|
||||
if (ent_ts)
|
||||
*ent_ts = next_ts;
|
||||
|
||||
if (missing_events)
|
||||
*missing_events = next_lost;
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
@@ -1617,13 +1637,14 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
|
||||
struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
|
||||
int *ent_cpu, u64 *ent_ts)
|
||||
{
|
||||
return __find_next_entry(iter, ent_cpu, ent_ts);
|
||||
return __find_next_entry(iter, ent_cpu, NULL, ent_ts);
|
||||
}
|
||||
|
||||
/* Find the next real entry, and increment the iterator to the next entry */
|
||||
static void *find_next_entry_inc(struct trace_iterator *iter)
|
||||
{
|
||||
iter->ent = __find_next_entry(iter, &iter->cpu, &iter->ts);
|
||||
iter->ent = __find_next_entry(iter, &iter->cpu,
|
||||
&iter->lost_events, &iter->ts);
|
||||
|
||||
if (iter->ent)
|
||||
trace_iterator_increment(iter);
|
||||
@@ -1635,7 +1656,8 @@ static void trace_consume(struct trace_iterator *iter)
|
||||
{
|
||||
/* Don't allow ftrace to trace into the ring buffers */
|
||||
ftrace_disable_cpu();
|
||||
ring_buffer_consume(iter->tr->buffer, iter->cpu, &iter->ts);
|
||||
ring_buffer_consume(iter->tr->buffer, iter->cpu, &iter->ts,
|
||||
&iter->lost_events);
|
||||
ftrace_enable_cpu();
|
||||
}
|
||||
|
||||
@@ -1786,7 +1808,7 @@ static void print_func_help_header(struct seq_file *m)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
print_trace_header(struct seq_file *m, struct trace_iterator *iter)
|
||||
{
|
||||
unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
|
||||
@@ -1995,7 +2017,7 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
|
||||
return event ? event->binary(iter, 0) : TRACE_TYPE_HANDLED;
|
||||
}
|
||||
|
||||
static int trace_empty(struct trace_iterator *iter)
|
||||
int trace_empty(struct trace_iterator *iter)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
@@ -2030,6 +2052,10 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter)
|
||||
{
|
||||
enum print_line_t ret;
|
||||
|
||||
if (iter->lost_events)
|
||||
trace_seq_printf(&iter->seq, "CPU:%d [LOST %lu EVENTS]\n",
|
||||
iter->cpu, iter->lost_events);
|
||||
|
||||
if (iter->trace && iter->trace->print_line) {
|
||||
ret = iter->trace->print_line(iter);
|
||||
if (ret != TRACE_TYPE_UNHANDLED)
|
||||
@@ -2058,6 +2084,23 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter)
|
||||
return print_trace_fmt(iter);
|
||||
}
|
||||
|
||||
void trace_default_header(struct seq_file *m)
|
||||
{
|
||||
struct trace_iterator *iter = m->private;
|
||||
|
||||
if (iter->iter_flags & TRACE_FILE_LAT_FMT) {
|
||||
/* print nothing if the buffers are empty */
|
||||
if (trace_empty(iter))
|
||||
return;
|
||||
print_trace_header(m, iter);
|
||||
if (!(trace_flags & TRACE_ITER_VERBOSE))
|
||||
print_lat_help_header(m);
|
||||
} else {
|
||||
if (!(trace_flags & TRACE_ITER_VERBOSE))
|
||||
print_func_help_header(m);
|
||||
}
|
||||
}
|
||||
|
||||
static int s_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct trace_iterator *iter = v;
|
||||
@@ -2070,17 +2113,9 @@ static int s_show(struct seq_file *m, void *v)
|
||||
}
|
||||
if (iter->trace && iter->trace->print_header)
|
||||
iter->trace->print_header(m);
|
||||
else if (iter->iter_flags & TRACE_FILE_LAT_FMT) {
|
||||
/* print nothing if the buffers are empty */
|
||||
if (trace_empty(iter))
|
||||
return 0;
|
||||
print_trace_header(m, iter);
|
||||
if (!(trace_flags & TRACE_ITER_VERBOSE))
|
||||
print_lat_help_header(m);
|
||||
} else {
|
||||
if (!(trace_flags & TRACE_ITER_VERBOSE))
|
||||
print_func_help_header(m);
|
||||
}
|
||||
else
|
||||
trace_default_header(m);
|
||||
|
||||
} else if (iter->leftover) {
|
||||
/*
|
||||
* If we filled the seq_file buffer earlier, we
|
||||
@@ -2166,15 +2201,20 @@ __tracing_open(struct inode *inode, struct file *file)
|
||||
|
||||
if (iter->cpu_file == TRACE_PIPE_ALL_CPU) {
|
||||
for_each_tracing_cpu(cpu) {
|
||||
|
||||
iter->buffer_iter[cpu] =
|
||||
ring_buffer_read_start(iter->tr->buffer, cpu);
|
||||
ring_buffer_read_prepare(iter->tr->buffer, cpu);
|
||||
}
|
||||
ring_buffer_read_prepare_sync();
|
||||
for_each_tracing_cpu(cpu) {
|
||||
ring_buffer_read_start(iter->buffer_iter[cpu]);
|
||||
tracing_iter_reset(iter, cpu);
|
||||
}
|
||||
} else {
|
||||
cpu = iter->cpu_file;
|
||||
iter->buffer_iter[cpu] =
|
||||
ring_buffer_read_start(iter->tr->buffer, cpu);
|
||||
ring_buffer_read_prepare(iter->tr->buffer, cpu);
|
||||
ring_buffer_read_prepare_sync();
|
||||
ring_buffer_read_start(iter->buffer_iter[cpu]);
|
||||
tracing_iter_reset(iter, cpu);
|
||||
}
|
||||
|
||||
@@ -4336,7 +4376,7 @@ static int trace_panic_handler(struct notifier_block *this,
|
||||
unsigned long event, void *unused)
|
||||
{
|
||||
if (ftrace_dump_on_oops)
|
||||
ftrace_dump();
|
||||
ftrace_dump(ftrace_dump_on_oops);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
@@ -4353,7 +4393,7 @@ static int trace_die_handler(struct notifier_block *self,
|
||||
switch (val) {
|
||||
case DIE_OOPS:
|
||||
if (ftrace_dump_on_oops)
|
||||
ftrace_dump();
|
||||
ftrace_dump(ftrace_dump_on_oops);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -4394,7 +4434,8 @@ trace_printk_seq(struct trace_seq *s)
|
||||
trace_seq_init(s);
|
||||
}
|
||||
|
||||
static void __ftrace_dump(bool disable_tracing)
|
||||
static void
|
||||
__ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode)
|
||||
{
|
||||
static arch_spinlock_t ftrace_dump_lock =
|
||||
(arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
|
||||
@@ -4427,12 +4468,25 @@ static void __ftrace_dump(bool disable_tracing)
|
||||
/* don't look at user memory in panic mode */
|
||||
trace_flags &= ~TRACE_ITER_SYM_USEROBJ;
|
||||
|
||||
printk(KERN_TRACE "Dumping ftrace buffer:\n");
|
||||
|
||||
/* Simulate the iterator */
|
||||
iter.tr = &global_trace;
|
||||
iter.trace = current_trace;
|
||||
iter.cpu_file = TRACE_PIPE_ALL_CPU;
|
||||
|
||||
switch (oops_dump_mode) {
|
||||
case DUMP_ALL:
|
||||
iter.cpu_file = TRACE_PIPE_ALL_CPU;
|
||||
break;
|
||||
case DUMP_ORIG:
|
||||
iter.cpu_file = raw_smp_processor_id();
|
||||
break;
|
||||
case DUMP_NONE:
|
||||
goto out_enable;
|
||||
default:
|
||||
printk(KERN_TRACE "Bad dumping mode, switching to all CPUs dump\n");
|
||||
iter.cpu_file = TRACE_PIPE_ALL_CPU;
|
||||
}
|
||||
|
||||
printk(KERN_TRACE "Dumping ftrace buffer:\n");
|
||||
|
||||
/*
|
||||
* We need to stop all tracing on all CPUS to read the
|
||||
@@ -4471,6 +4525,7 @@ static void __ftrace_dump(bool disable_tracing)
|
||||
else
|
||||
printk(KERN_TRACE "---------------------------------\n");
|
||||
|
||||
out_enable:
|
||||
/* Re-enable tracing if requested */
|
||||
if (!disable_tracing) {
|
||||
trace_flags |= old_userobj;
|
||||
@@ -4487,9 +4542,9 @@ static void __ftrace_dump(bool disable_tracing)
|
||||
}
|
||||
|
||||
/* By default: disable tracing after the dump */
|
||||
void ftrace_dump(void)
|
||||
void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
|
||||
{
|
||||
__ftrace_dump(true);
|
||||
__ftrace_dump(true, oops_dump_mode);
|
||||
}
|
||||
|
||||
__init static int tracer_alloc_buffers(void)
|
||||
|
Reference in New Issue
Block a user