Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 245538
b: refs/heads/master
c: cdbe61b
h: refs/heads/master
v: v3
  • Loading branch information
Steven Rostedt authored and Steven Rostedt committed May 18, 2011
1 parent 6be2160 commit 5ff97e1
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 8 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: b848914ce39589d89ee0078a6d1ef452b464729e
refs/heads/master: cdbe61bfe70440939e457fb4a8d0995eaaed17de
1 change: 1 addition & 0 deletions trunk/include/linux/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct ftrace_hash;
enum {
FTRACE_OPS_FL_ENABLED = 1 << 0,
FTRACE_OPS_FL_GLOBAL = 1 << 1,
FTRACE_OPS_FL_DYNAMIC = 1 << 2,
};

struct ftrace_ops {
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ extern char *get_options(const char *str, int nints, int *ints);
extern unsigned long long memparse(const char *ptr, char **retptr);

extern int core_kernel_text(unsigned long addr);
extern int core_kernel_data(unsigned long addr);
extern int __kernel_text_address(unsigned long addr);
extern int kernel_text_address(unsigned long addr);
extern int func_ptr_is_kernel_text(void *ptr);
Expand Down
8 changes: 8 additions & 0 deletions trunk/kernel/extable.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ int core_kernel_text(unsigned long addr)
return 0;
}

int core_kernel_data(unsigned long addr)
{
if (addr >= (unsigned long)_sdata &&
addr < (unsigned long)_edata)
return 1;
return 0;
}

int __kernel_text_address(unsigned long addr)
{
if (core_kernel_text(addr))
Expand Down
37 changes: 30 additions & 7 deletions trunk/kernel/trace/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,14 @@ static void update_ftrace_function(void)

update_global_ops();

/*
* If we are at the end of the list and this ops is
* not dynamic, then have the mcount trampoline call
* the function directly
*/
if (ftrace_ops_list == &ftrace_list_end ||
ftrace_ops_list->next == &ftrace_list_end)
(ftrace_ops_list->next == &ftrace_list_end &&
!(ftrace_ops_list->flags & FTRACE_OPS_FL_DYNAMIC)))
func = ftrace_ops_list->func;
else
func = ftrace_ops_list_func;
Expand Down Expand Up @@ -250,6 +256,9 @@ static int __register_ftrace_function(struct ftrace_ops *ops)
if (WARN_ON(ops->flags & FTRACE_OPS_FL_ENABLED))
return -EBUSY;

if (!core_kernel_data((unsigned long)ops))
ops->flags |= FTRACE_OPS_FL_DYNAMIC;

if (ops->flags & FTRACE_OPS_FL_GLOBAL) {
int first = ftrace_global_list == &ftrace_list_end;
add_ftrace_ops(&ftrace_global_list, ops);
Expand Down Expand Up @@ -293,6 +302,13 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
if (ftrace_enabled)
update_ftrace_function();

/*
* Dynamic ops may be freed, we must make sure that all
* callers are done before leaving this function.
*/
if (ops->flags & FTRACE_OPS_FL_DYNAMIC)
synchronize_sched();

return 0;
}

Expand Down Expand Up @@ -1225,6 +1241,9 @@ ftrace_hash_move(struct ftrace_hash **dst, struct ftrace_hash *src)
* the filter_hash does not exist or is empty,
* AND
* the ip is not in the ops->notrace_hash.
*
* This needs to be called with preemption disabled as
* the hashes are freed with call_rcu_sched().
*/
static int
ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip)
Expand All @@ -1233,9 +1252,6 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip)
struct ftrace_hash *notrace_hash;
int ret;

/* The hashes are freed with call_rcu_sched() */
preempt_disable_notrace();

filter_hash = rcu_dereference_raw(ops->filter_hash);
notrace_hash = rcu_dereference_raw(ops->notrace_hash);

Expand All @@ -1246,7 +1262,6 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip)
ret = 1;
else
ret = 0;
preempt_enable_notrace();

return ret;
}
Expand Down Expand Up @@ -3425,14 +3440,20 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip)
static void
ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip)
{
/* see comment above ftrace_global_list_func */
struct ftrace_ops *op = rcu_dereference_raw(ftrace_ops_list);
struct ftrace_ops *op;

/*
* Some of the ops may be dynamically allocated,
* they must be freed after a synchronize_sched().
*/
preempt_disable_notrace();
op = rcu_dereference_raw(ftrace_ops_list);
while (op != &ftrace_list_end) {
if (ftrace_ops_test(op, ip))
op->func(ip, parent_ip);
op = rcu_dereference_raw(op->next);
};
preempt_enable_notrace();
}

static void clear_ftrace_swapper(void)
Expand Down Expand Up @@ -3743,6 +3764,7 @@ int register_ftrace_function(struct ftrace_ops *ops)
mutex_unlock(&ftrace_lock);
return ret;
}
EXPORT_SYMBOL_GPL(register_ftrace_function);

/**
* unregister_ftrace_function - unregister a function for profiling.
Expand All @@ -3762,6 +3784,7 @@ int unregister_ftrace_function(struct ftrace_ops *ops)

return ret;
}
EXPORT_SYMBOL_GPL(unregister_ftrace_function);

int
ftrace_enable_sysctl(struct ctl_table *table, int write,
Expand Down

0 comments on commit 5ff97e1

Please sign in to comment.