Skip to content

Commit

Permalink
Merge branch 'tracing-fixes-for-linus' of git://git.kernel.org/pub/sc…
Browse files Browse the repository at this point in the history
…m/linux/kernel/git/tip/linux-2.6-tip

* 'tracing-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  tracing: Remove comparing of NULL to va_list in trace_array_vprintk()
  tracing: Fix function graph trace_pipe to properly display failed entries
  tracing: Add full state to trace_seq
  tracing: Buffer the output of seq_file in case of filled buffer
  tracing: Only call pipe_close if pipe_close is defined
  tracing: Add pipe_close interface
  • Loading branch information
torvalds committed Dec 12, 2009
2 parents 6f696eb + 788d70d commit df7147b
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 59 deletions.
1 change: 1 addition & 0 deletions include/linux/ftrace_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ struct trace_iterator {
/* The below is zeroed out in pipe_read */
struct trace_seq seq;
struct trace_entry *ent;
int leftover;
int cpu;
u64 ts;

Expand Down
7 changes: 5 additions & 2 deletions include/linux/trace_seq.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ struct trace_seq {
unsigned char buffer[PAGE_SIZE];
unsigned int len;
unsigned int readpos;
int full;
};

static inline void
trace_seq_init(struct trace_seq *s)
{
s->len = 0;
s->readpos = 0;
s->full = 0;
}

/*
Expand All @@ -33,7 +35,7 @@ extern int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
__attribute__ ((format (printf, 2, 0)));
extern int
trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary);
extern void trace_print_seq(struct seq_file *m, struct trace_seq *s);
extern int trace_print_seq(struct seq_file *m, struct trace_seq *s);
extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
size_t cnt);
extern int trace_seq_puts(struct trace_seq *s, const char *str);
Expand All @@ -55,8 +57,9 @@ trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
return 0;
}

static inline void trace_print_seq(struct seq_file *m, struct trace_seq *s)
static inline int trace_print_seq(struct seq_file *m, struct trace_seq *s)
{
return 0;
}
static inline ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
size_t cnt)
Expand Down
57 changes: 48 additions & 9 deletions kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1361,11 +1361,7 @@ int trace_array_vprintk(struct trace_array *tr,
pause_graph_tracing();
raw_local_irq_save(irq_flags);
__raw_spin_lock(&trace_buf_lock);
if (args == NULL) {
strncpy(trace_buf, fmt, TRACE_BUF_SIZE);
len = strlen(trace_buf);
} else
len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);

size = sizeof(*entry) + len + 1;
buffer = tr->buffer;
Expand Down Expand Up @@ -1516,6 +1512,8 @@ static void *s_next(struct seq_file *m, void *v, loff_t *pos)
int i = (int)*pos;
void *ent;

WARN_ON_ONCE(iter->leftover);

(*pos)++;

/* can't go backwards */
Expand Down Expand Up @@ -1614,8 +1612,16 @@ static void *s_start(struct seq_file *m, loff_t *pos)
;

} else {
l = *pos - 1;
p = s_next(m, p, &l);
/*
* If we overflowed the seq_file before, then we want
* to just reuse the trace_seq buffer again.
*/
if (iter->leftover)
p = iter;
else {
l = *pos - 1;
p = s_next(m, p, &l);
}
}

trace_event_read_lock();
Expand Down Expand Up @@ -1923,6 +1929,7 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter)
static int s_show(struct seq_file *m, void *v)
{
struct trace_iterator *iter = v;
int ret;

if (iter->ent == NULL) {
if (iter->tr) {
Expand All @@ -1942,9 +1949,27 @@ static int s_show(struct seq_file *m, void *v)
if (!(trace_flags & TRACE_ITER_VERBOSE))
print_func_help_header(m);
}
} else if (iter->leftover) {
/*
* If we filled the seq_file buffer earlier, we
* want to just show it now.
*/
ret = trace_print_seq(m, &iter->seq);

/* ret should this time be zero, but you never know */
iter->leftover = ret;

} else {
print_trace_line(iter);
trace_print_seq(m, &iter->seq);
ret = trace_print_seq(m, &iter->seq);
/*
* If we overflow the seq_file buffer, then it will
* ask us for this data again at start up.
* Use that instead.
* ret is 0 if seq_file write succeeded.
* -1 otherwise.
*/
iter->leftover = ret;
}

return 0;
Expand Down Expand Up @@ -2898,6 +2923,10 @@ static int tracing_release_pipe(struct inode *inode, struct file *file)
else
cpumask_clear_cpu(iter->cpu_file, tracing_reader_cpumask);


if (iter->trace->pipe_close)
iter->trace->pipe_close(iter);

mutex_unlock(&trace_types_lock);

free_cpumask_var(iter->started);
Expand Down Expand Up @@ -3320,6 +3349,16 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
return cnt;
}

static int mark_printk(const char *fmt, ...)
{
int ret;
va_list args;
va_start(args, fmt);
ret = trace_vprintk(0, fmt, args);
va_end(args);
return ret;
}

static ssize_t
tracing_mark_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *fpos)
Expand All @@ -3346,7 +3385,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
} else
buf[cnt] = '\0';

cnt = trace_vprintk(0, buf, NULL);
cnt = mark_printk("%s", buf);
kfree(buf);
*fpos += cnt;

Expand Down
2 changes: 2 additions & 0 deletions kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ struct tracer_flags {
* @pipe_open: called when the trace_pipe file is opened
* @wait_pipe: override how the user waits for traces on trace_pipe
* @close: called when the trace file is released
* @pipe_close: called when the trace_pipe file is released
* @read: override the default read callback on trace_pipe
* @splice_read: override the default splice_read callback on trace_pipe
* @selftest: selftest to run on boot (see trace_selftest.c)
Expand All @@ -290,6 +291,7 @@ struct tracer {
void (*pipe_open)(struct trace_iterator *iter);
void (*wait_pipe)(struct trace_iterator *iter);
void (*close)(struct trace_iterator *iter);
void (*pipe_close)(struct trace_iterator *iter);
ssize_t (*read)(struct trace_iterator *iter,
struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos);
Expand Down
Loading

0 comments on commit df7147b

Please sign in to comment.