Merge commit 'v2.6.30-rc3' into tracing/hw-branch-tracing
Conflicts:
arch/x86/kernel/ptrace.c
Merge reason: fix the conflict above, and also pick up the CONFIG_BROKEN
dependency change from upstream so that we can remove it
here.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
@@ -312,7 +312,7 @@ config KMEMTRACE
|
||||
and profile kernel code.
|
||||
|
||||
This requires an userspace application to use. See
|
||||
Documentation/vm/kmemtrace.txt for more information.
|
||||
Documentation/trace/kmemtrace.txt for more information.
|
||||
|
||||
Saying Y will make the kernel somewhat larger and slower. However,
|
||||
if you disable kmemtrace at run-time or boot-time, the performance
|
||||
@@ -403,7 +403,7 @@ config MMIOTRACE
|
||||
implementation and works via page faults. Tracing is disabled by
|
||||
default and can be enabled at run-time.
|
||||
|
||||
See Documentation/tracers/mmiotrace.txt.
|
||||
See Documentation/trace/mmiotrace.txt.
|
||||
If you are not helping to develop drivers, say N.
|
||||
|
||||
config MMIOTRACE_TEST
|
||||
|
||||
@@ -327,10 +327,10 @@ static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
|
||||
char *msg;
|
||||
struct blk_trace *bt;
|
||||
|
||||
if (count > BLK_TN_MAX_MSG)
|
||||
if (count >= BLK_TN_MAX_MSG)
|
||||
return -EINVAL;
|
||||
|
||||
msg = kmalloc(count, GFP_KERNEL);
|
||||
msg = kmalloc(count + 1, GFP_KERNEL);
|
||||
if (msg == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -339,6 +339,7 @@ static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
msg[count] = '\0';
|
||||
bt = filp->private_data;
|
||||
__trace_note_message(bt, "%s", msg);
|
||||
kfree(msg);
|
||||
@@ -642,7 +643,7 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
|
||||
if (blk_pc_request(rq)) {
|
||||
what |= BLK_TC_ACT(BLK_TC_PC);
|
||||
__blk_add_trace(bt, 0, rq->data_len, rw, what, rq->errors,
|
||||
sizeof(rq->cmd), rq->cmd);
|
||||
rq->cmd_len, rq->cmd);
|
||||
} else {
|
||||
what |= BLK_TC_ACT(BLK_TC_FS);
|
||||
__blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9,
|
||||
@@ -1376,12 +1377,12 @@ static int blk_trace_str2mask(const char *str)
|
||||
{
|
||||
int i;
|
||||
int mask = 0;
|
||||
char *s, *token;
|
||||
char *buf, *s, *token;
|
||||
|
||||
s = kstrdup(str, GFP_KERNEL);
|
||||
if (s == NULL)
|
||||
buf = kstrdup(str, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
s = strstrip(s);
|
||||
s = strstrip(buf);
|
||||
|
||||
while (1) {
|
||||
token = strsep(&s, ",");
|
||||
@@ -1402,7 +1403,7 @@ static int blk_trace_str2mask(const char *str)
|
||||
break;
|
||||
}
|
||||
}
|
||||
kfree(s);
|
||||
kfree(buf);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
+37
-20
@@ -30,6 +30,7 @@
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/splice.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/poll.h>
|
||||
@@ -147,8 +148,7 @@ static int __init set_ftrace_dump_on_oops(char *str)
|
||||
}
|
||||
__setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops);
|
||||
|
||||
long
|
||||
ns2usecs(cycle_t nsec)
|
||||
unsigned long long ns2usecs(cycle_t nsec)
|
||||
{
|
||||
nsec += 500;
|
||||
do_div(nsec, 1000);
|
||||
@@ -1632,7 +1632,11 @@ static void test_cpu_buff_start(struct trace_iterator *iter)
|
||||
return;
|
||||
|
||||
cpumask_set_cpu(iter->cpu, iter->started);
|
||||
trace_seq_printf(s, "##### CPU %u buffer started ####\n", iter->cpu);
|
||||
|
||||
/* Don't print started cpu buffer for the first entry of the trace */
|
||||
if (iter->idx > 1)
|
||||
trace_seq_printf(s, "##### CPU %u buffer started ####\n",
|
||||
iter->cpu);
|
||||
}
|
||||
|
||||
static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
|
||||
@@ -1867,6 +1871,11 @@ __tracing_open(struct inode *inode, struct file *file)
|
||||
if (current_trace)
|
||||
*iter->trace = *current_trace;
|
||||
|
||||
if (!alloc_cpumask_var(&iter->started, GFP_KERNEL))
|
||||
goto fail;
|
||||
|
||||
cpumask_clear(iter->started);
|
||||
|
||||
if (current_trace && current_trace->print_max)
|
||||
iter->tr = &max_tr;
|
||||
else
|
||||
@@ -1917,6 +1926,7 @@ __tracing_open(struct inode *inode, struct file *file)
|
||||
if (iter->buffer_iter[cpu])
|
||||
ring_buffer_read_finish(iter->buffer_iter[cpu]);
|
||||
}
|
||||
free_cpumask_var(iter->started);
|
||||
fail:
|
||||
mutex_unlock(&trace_types_lock);
|
||||
kfree(iter->trace);
|
||||
@@ -1960,6 +1970,7 @@ static int tracing_release(struct inode *inode, struct file *file)
|
||||
|
||||
seq_release(inode, file);
|
||||
mutex_destroy(&iter->mutex);
|
||||
free_cpumask_var(iter->started);
|
||||
kfree(iter->trace);
|
||||
kfree(iter);
|
||||
return 0;
|
||||
@@ -2358,9 +2369,9 @@ static const char readme_msg[] =
|
||||
"# mkdir /debug\n"
|
||||
"# mount -t debugfs nodev /debug\n\n"
|
||||
"# cat /debug/tracing/available_tracers\n"
|
||||
"wakeup preemptirqsoff preemptoff irqsoff ftrace sched_switch none\n\n"
|
||||
"wakeup preemptirqsoff preemptoff irqsoff function sched_switch nop\n\n"
|
||||
"# cat /debug/tracing/current_tracer\n"
|
||||
"none\n"
|
||||
"nop\n"
|
||||
"# echo sched_switch > /debug/tracing/current_tracer\n"
|
||||
"# cat /debug/tracing/current_tracer\n"
|
||||
"sched_switch\n"
|
||||
@@ -3266,19 +3277,13 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
|
||||
|
||||
info->tr = &global_trace;
|
||||
info->cpu = cpu;
|
||||
info->spare = ring_buffer_alloc_read_page(info->tr->buffer);
|
||||
info->spare = NULL;
|
||||
/* Force reading ring buffer for first read */
|
||||
info->read = (unsigned int)-1;
|
||||
if (!info->spare)
|
||||
goto out;
|
||||
|
||||
filp->private_data = info;
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
kfree(info);
|
||||
return -ENOMEM;
|
||||
return nonseekable_open(inode, filp);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@@ -3293,6 +3298,11 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
if (!info->spare)
|
||||
info->spare = ring_buffer_alloc_read_page(info->tr->buffer);
|
||||
if (!info->spare)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Do we have previous read data to read? */
|
||||
if (info->read < PAGE_SIZE)
|
||||
goto read;
|
||||
@@ -3331,7 +3341,8 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct ftrace_buffer_info *info = file->private_data;
|
||||
|
||||
ring_buffer_free_read_page(info->tr->buffer, info->spare);
|
||||
if (info->spare)
|
||||
ring_buffer_free_read_page(info->tr->buffer, info->spare);
|
||||
kfree(info);
|
||||
|
||||
return 0;
|
||||
@@ -3417,14 +3428,19 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
|
||||
int size, i;
|
||||
size_t ret;
|
||||
|
||||
/*
|
||||
* We can't seek on a buffer input
|
||||
*/
|
||||
if (unlikely(*ppos))
|
||||
return -ESPIPE;
|
||||
if (*ppos & (PAGE_SIZE - 1)) {
|
||||
WARN_ONCE(1, "Ftrace: previous read must page-align\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (len & (PAGE_SIZE - 1)) {
|
||||
WARN_ONCE(1, "Ftrace: splice_read should page-align\n");
|
||||
if (len < PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
len &= PAGE_MASK;
|
||||
}
|
||||
|
||||
for (i = 0; i < PIPE_BUFFERS && len; i++, len -= size) {
|
||||
for (i = 0; i < PIPE_BUFFERS && len; i++, len -= PAGE_SIZE) {
|
||||
struct page *page;
|
||||
int r;
|
||||
|
||||
@@ -3463,6 +3479,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
|
||||
spd.partial[i].offset = 0;
|
||||
spd.partial[i].private = (unsigned long)ref;
|
||||
spd.nr_pages++;
|
||||
*ppos += PAGE_SIZE;
|
||||
}
|
||||
|
||||
spd.nr_pages = i;
|
||||
|
||||
@@ -604,7 +604,7 @@ extern int trace_selftest_startup_hw_branches(struct tracer *trace,
|
||||
#endif /* CONFIG_FTRACE_STARTUP_TEST */
|
||||
|
||||
extern void *head_page(struct trace_array_cpu *data);
|
||||
extern long ns2usecs(cycle_t nsec);
|
||||
extern unsigned long long ns2usecs(cycle_t nsec);
|
||||
extern int
|
||||
trace_vbprintk(unsigned long ip, const char *fmt, va_list args);
|
||||
extern int
|
||||
|
||||
@@ -155,6 +155,13 @@ static enum print_line_t trace_branch_print(struct trace_iterator *iter,
|
||||
return TRACE_TYPE_HANDLED;
|
||||
}
|
||||
|
||||
static void branch_print_header(struct seq_file *s)
|
||||
{
|
||||
seq_puts(s, "# TASK-PID CPU# TIMESTAMP CORRECT"
|
||||
" FUNC:FILE:LINE\n");
|
||||
seq_puts(s, "# | | | | | "
|
||||
" |\n");
|
||||
}
|
||||
|
||||
static struct trace_event trace_branch_event = {
|
||||
.type = TRACE_BRANCH,
|
||||
@@ -169,6 +176,7 @@ static struct tracer branch_trace __read_mostly =
|
||||
#ifdef CONFIG_FTRACE_SELFTEST
|
||||
.selftest = trace_selftest_startup_branch,
|
||||
#endif /* CONFIG_FTRACE_SELFTEST */
|
||||
.print_header = branch_print_header,
|
||||
};
|
||||
|
||||
__init static int init_branch_tracer(void)
|
||||
|
||||
@@ -503,6 +503,7 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
||||
|
||||
if (copy_from_user(&buf, ubuf, cnt))
|
||||
return -EFAULT;
|
||||
buf[cnt] = '\0';
|
||||
|
||||
pred = kzalloc(sizeof(*pred), GFP_KERNEL);
|
||||
if (!pred)
|
||||
@@ -520,9 +521,10 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
||||
return cnt;
|
||||
}
|
||||
|
||||
if (filter_add_pred(call, pred)) {
|
||||
err = filter_add_pred(call, pred);
|
||||
if (err < 0) {
|
||||
filter_free_pred(pred);
|
||||
return -EINVAL;
|
||||
return err;
|
||||
}
|
||||
|
||||
*ppos += cnt;
|
||||
@@ -569,6 +571,7 @@ subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
||||
|
||||
if (copy_from_user(&buf, ubuf, cnt))
|
||||
return -EFAULT;
|
||||
buf[cnt] = '\0';
|
||||
|
||||
pred = kzalloc(sizeof(*pred), GFP_KERNEL);
|
||||
if (!pred)
|
||||
@@ -586,10 +589,11 @@ subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
||||
return cnt;
|
||||
}
|
||||
|
||||
if (filter_add_subsystem_pred(system, pred)) {
|
||||
err = filter_add_subsystem_pred(system, pred);
|
||||
if (err < 0) {
|
||||
filter_free_subsystem_preds(system);
|
||||
filter_free_pred(pred);
|
||||
return -EINVAL;
|
||||
return err;
|
||||
}
|
||||
|
||||
*ppos += cnt;
|
||||
|
||||
@@ -215,7 +215,7 @@ static int __filter_add_pred(struct ftrace_event_call *call,
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
static int is_string_field(const char *type)
|
||||
@@ -319,7 +319,7 @@ int filter_add_subsystem_pred(struct event_subsystem *system,
|
||||
}
|
||||
|
||||
if (i == MAX_FILTER_PRED)
|
||||
return -EINVAL;
|
||||
return -ENOSPC;
|
||||
|
||||
events_for_each(call) {
|
||||
int err;
|
||||
@@ -410,16 +410,22 @@ int filter_parse(char **pbuf, struct filter_pred *pred)
|
||||
}
|
||||
}
|
||||
|
||||
if (!val_str) {
|
||||
pred->field_name = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pred->field_name = kstrdup(pred->field_name, GFP_KERNEL);
|
||||
if (!pred->field_name)
|
||||
return -ENOMEM;
|
||||
|
||||
pred->val = simple_strtoull(val_str, &tmp, 10);
|
||||
pred->val = simple_strtoull(val_str, &tmp, 0);
|
||||
if (tmp == val_str) {
|
||||
pred->str_val = kstrdup(val_str, GFP_KERNEL);
|
||||
if (!pred->str_val)
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else if (*tmp != '\0')
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -105,10 +105,10 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
|
||||
return 0;
|
||||
|
||||
#undef __entry
|
||||
#define __entry "REC"
|
||||
#define __entry REC
|
||||
|
||||
#undef TP_printk
|
||||
#define TP_printk(fmt, args...) "%s, %s\n", #fmt, #args
|
||||
#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
|
||||
|
||||
#undef TP_fast_assign
|
||||
#define TP_fast_assign(args...) args
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
#undef TRACE_FIELD_ZERO_CHAR
|
||||
#define TRACE_FIELD_ZERO_CHAR(item) \
|
||||
ret = trace_seq_printf(s, "\tfield: char " #item ";\t" \
|
||||
ret = trace_seq_printf(s, "\tfield:char " #item ";\t" \
|
||||
"offset:%u;\tsize:0;\n", \
|
||||
(unsigned int)offsetof(typeof(field), item)); \
|
||||
if (!ret) \
|
||||
|
||||
@@ -423,7 +423,7 @@ int trace_print_lat_context(struct trace_iterator *iter)
|
||||
|
||||
trace_find_cmdline(entry->pid, comm);
|
||||
|
||||
ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08lx]"
|
||||
ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08llx]"
|
||||
" %ld.%03ldms (+%ld.%03ldms): ", comm,
|
||||
entry->pid, iter->cpu, entry->flags,
|
||||
entry->preempt_count, iter->idx,
|
||||
|
||||
@@ -186,6 +186,12 @@ static enum print_line_t power_print_line(struct trace_iterator *iter)
|
||||
return TRACE_TYPE_UNHANDLED;
|
||||
}
|
||||
|
||||
static void power_print_header(struct seq_file *s)
|
||||
{
|
||||
seq_puts(s, "# TIMESTAMP STATE EVENT\n");
|
||||
seq_puts(s, "# | | |\n");
|
||||
}
|
||||
|
||||
static struct tracer power_tracer __read_mostly =
|
||||
{
|
||||
.name = "power",
|
||||
@@ -194,6 +200,7 @@ static struct tracer power_tracer __read_mostly =
|
||||
.stop = stop_power_trace,
|
||||
.reset = power_trace_reset,
|
||||
.print_line = power_print_line,
|
||||
.print_header = power_print_header,
|
||||
};
|
||||
|
||||
static int init_power_trace(void)
|
||||
|
||||
@@ -62,6 +62,9 @@ probe_sched_wakeup(struct rq *__rq, struct task_struct *wakee, int success)
|
||||
pc = preempt_count();
|
||||
tracing_record_cmdline(current);
|
||||
|
||||
if (sched_stopped)
|
||||
return;
|
||||
|
||||
local_irq_save(flags);
|
||||
cpu = raw_smp_processor_id();
|
||||
data = ctx_trace->data[cpu];
|
||||
|
||||
@@ -154,7 +154,7 @@ probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
|
||||
if (unlikely(!tracer_enabled || next != wakeup_task))
|
||||
goto out_unlock;
|
||||
|
||||
trace_function(wakeup_trace, CALLER_ADDR1, CALLER_ADDR2, flags, pc);
|
||||
trace_function(wakeup_trace, CALLER_ADDR0, CALLER_ADDR1, flags, pc);
|
||||
tracing_sched_switch_trace(wakeup_trace, prev, next, flags, pc);
|
||||
|
||||
/*
|
||||
@@ -257,6 +257,12 @@ probe_wakeup(struct rq *rq, struct task_struct *p, int success)
|
||||
data = wakeup_trace->data[wakeup_cpu];
|
||||
data->preempt_timestamp = ftrace_now(cpu);
|
||||
tracing_sched_wakeup_trace(wakeup_trace, p, current, flags, pc);
|
||||
|
||||
/*
|
||||
* We must be careful in using CALLER_ADDR2. But since wake_up
|
||||
* is not called by an assembly function (where as schedule is)
|
||||
* it should be safe to use it here.
|
||||
*/
|
||||
trace_function(wakeup_trace, CALLER_ADDR1, CALLER_ADDR2, flags, pc);
|
||||
|
||||
out_locked:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <trace/syscall.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <asm/syscall.h>
|
||||
|
||||
#include "trace_output.h"
|
||||
|
||||
Reference in New Issue
Block a user