Commit 95763dd5 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'tracing-fixes-for-linus' of...

Merge branch 'tracing-fixes-for-linus' of git://git.kernel.org/pub/scm/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:
  ftrace: fix dyn ftrace filter selection
  ftrace: make filtered functions effective on setting
  ftrace: fix set_ftrace_filter
  trace: introduce missing mutex_unlock()
  tracing: kernel/trace/trace.c: introduce missing kfree()
parents 0260da16 6d5b43a6
...@@ -326,96 +326,89 @@ ftrace_record_ip(unsigned long ip) ...@@ -326,96 +326,89 @@ ftrace_record_ip(unsigned long ip)
static int static int
__ftrace_replace_code(struct dyn_ftrace *rec, __ftrace_replace_code(struct dyn_ftrace *rec,
unsigned char *old, unsigned char *new, int enable) unsigned char *nop, int enable)
{ {
unsigned long ip, fl; unsigned long ip, fl;
unsigned char *call, *old, *new;
ip = rec->ip; ip = rec->ip;
if (ftrace_filtered && enable) {
/* /*
* If filtering is on: * If this record is not to be traced and
* it is not enabled then do nothing.
* *
* If this record is set to be filtered and * If this record is not to be traced and
* is enabled then do nothing. * it is enabled then disabled it.
* *
* If this record is set to be filtered and
* it is not enabled, enable it.
*
* If this record is not set to be filtered
* and it is not enabled do nothing.
*
* If this record is set not to trace then
* do nothing.
*
* If this record is set not to trace and
* it is enabled then disable it.
*
* If this record is not set to be filtered and
* it is enabled, disable it.
*/ */
if (rec->flags & FTRACE_FL_NOTRACE) {
fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_NOTRACE | if (rec->flags & FTRACE_FL_ENABLED)
FTRACE_FL_ENABLED); rec->flags &= ~FTRACE_FL_ENABLED;
else
if ((fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED)) ||
(fl == (FTRACE_FL_FILTER | FTRACE_FL_NOTRACE)) ||
!fl || (fl == FTRACE_FL_NOTRACE))
return 0; return 0;
} else if (ftrace_filtered && enable) {
/* /*
* If it is enabled disable it, * Filtering is on:
* otherwise enable it!
*/ */
if (fl & FTRACE_FL_ENABLED) {
/* swap new and old */
new = old;
old = ftrace_call_replace(ip, FTRACE_ADDR);
rec->flags &= ~FTRACE_FL_ENABLED;
} else {
new = ftrace_call_replace(ip, FTRACE_ADDR);
rec->flags |= FTRACE_FL_ENABLED;
}
} else {
if (enable) { fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_ENABLED);
/*
* If this record is set not to trace and is /* Record is filtered and enabled, do nothing */
* not enabled, do nothing. if (fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED))
*/
fl = rec->flags & (FTRACE_FL_NOTRACE | FTRACE_FL_ENABLED);
if (fl == FTRACE_FL_NOTRACE)
return 0; return 0;
new = ftrace_call_replace(ip, FTRACE_ADDR); /* Record is not filtered and is not enabled do nothing */
} else if (!fl)
old = ftrace_call_replace(ip, FTRACE_ADDR); return 0;
/* Record is not filtered but enabled, disable it */
if (fl == FTRACE_FL_ENABLED)
rec->flags &= ~FTRACE_FL_ENABLED;
else
/* Otherwise record is filtered but not enabled, enable it */
rec->flags |= FTRACE_FL_ENABLED;
} else {
/* Disable or not filtered */
if (enable) { if (enable) {
/* if record is enabled, do nothing */
if (rec->flags & FTRACE_FL_ENABLED) if (rec->flags & FTRACE_FL_ENABLED)
return 0; return 0;
rec->flags |= FTRACE_FL_ENABLED; rec->flags |= FTRACE_FL_ENABLED;
} else { } else {
/* if record is not enabled do nothing */
if (!(rec->flags & FTRACE_FL_ENABLED)) if (!(rec->flags & FTRACE_FL_ENABLED))
return 0; return 0;
rec->flags &= ~FTRACE_FL_ENABLED; rec->flags &= ~FTRACE_FL_ENABLED;
} }
} }
call = ftrace_call_replace(ip, FTRACE_ADDR);
if (rec->flags & FTRACE_FL_ENABLED) {
old = nop;
new = call;
} else {
old = call;
new = nop;
}
return ftrace_modify_code(ip, old, new); return ftrace_modify_code(ip, old, new);
} }
static void ftrace_replace_code(int enable) static void ftrace_replace_code(int enable)
{ {
int i, failed; int i, failed;
unsigned char *new = NULL, *old = NULL; unsigned char *nop = NULL;
struct dyn_ftrace *rec; struct dyn_ftrace *rec;
struct ftrace_page *pg; struct ftrace_page *pg;
if (enable) nop = ftrace_nop_replace();
old = ftrace_nop_replace();
else
new = ftrace_nop_replace();
for (pg = ftrace_pages_start; pg; pg = pg->next) { for (pg = ftrace_pages_start; pg; pg = pg->next) {
for (i = 0; i < pg->index; i++) { for (i = 0; i < pg->index; i++) {
...@@ -433,7 +426,7 @@ static void ftrace_replace_code(int enable) ...@@ -433,7 +426,7 @@ static void ftrace_replace_code(int enable)
unfreeze_record(rec); unfreeze_record(rec);
} }
failed = __ftrace_replace_code(rec, old, new, enable); failed = __ftrace_replace_code(rec, nop, enable);
if (failed && (rec->flags & FTRACE_FL_CONVERTED)) { if (failed && (rec->flags & FTRACE_FL_CONVERTED)) {
rec->flags |= FTRACE_FL_FAILED; rec->flags |= FTRACE_FL_FAILED;
if ((system_state == SYSTEM_BOOTING) || if ((system_state == SYSTEM_BOOTING) ||
...@@ -534,7 +527,6 @@ static void ftrace_startup(void) ...@@ -534,7 +527,6 @@ static void ftrace_startup(void)
mutex_lock(&ftrace_start_lock); mutex_lock(&ftrace_start_lock);
ftrace_start++; ftrace_start++;
if (ftrace_start == 1)
command |= FTRACE_ENABLE_CALLS; command |= FTRACE_ENABLE_CALLS;
if (saved_ftrace_func != ftrace_trace_function) { if (saved_ftrace_func != ftrace_trace_function) {
...@@ -734,6 +726,9 @@ t_next(struct seq_file *m, void *v, loff_t *pos) ...@@ -734,6 +726,9 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
((iter->flags & FTRACE_ITER_FAILURES) && ((iter->flags & FTRACE_ITER_FAILURES) &&
!(rec->flags & FTRACE_FL_FAILED)) || !(rec->flags & FTRACE_FL_FAILED)) ||
((iter->flags & FTRACE_ITER_FILTER) &&
!(rec->flags & FTRACE_FL_FILTER)) ||
((iter->flags & FTRACE_ITER_NOTRACE) && ((iter->flags & FTRACE_ITER_NOTRACE) &&
!(rec->flags & FTRACE_FL_NOTRACE))) { !(rec->flags & FTRACE_FL_NOTRACE))) {
rec = NULL; rec = NULL;
...@@ -1186,7 +1181,7 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable) ...@@ -1186,7 +1181,7 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
mutex_lock(&ftrace_sysctl_lock); mutex_lock(&ftrace_sysctl_lock);
mutex_lock(&ftrace_start_lock); mutex_lock(&ftrace_start_lock);
if (iter->filtered && ftrace_start && ftrace_enabled) if (ftrace_start && ftrace_enabled)
ftrace_run_update_code(FTRACE_ENABLE_CALLS); ftrace_run_update_code(FTRACE_ENABLE_CALLS);
mutex_unlock(&ftrace_start_lock); mutex_unlock(&ftrace_start_lock);
mutex_unlock(&ftrace_sysctl_lock); mutex_unlock(&ftrace_sysctl_lock);
......
...@@ -617,6 +617,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) ...@@ -617,6 +617,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
list_del_init(&page->list); list_del_init(&page->list);
free_buffer_page(page); free_buffer_page(page);
} }
mutex_unlock(&buffer->mutex);
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -1936,6 +1936,7 @@ __tracing_open(struct inode *inode, struct file *file, int *ret) ...@@ -1936,6 +1936,7 @@ __tracing_open(struct inode *inode, struct file *file, int *ret)
ring_buffer_read_finish(iter->buffer_iter[cpu]); ring_buffer_read_finish(iter->buffer_iter[cpu]);
} }
mutex_unlock(&trace_types_lock); mutex_unlock(&trace_types_lock);
kfree(iter);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment