* return address is actually off by one word, and we
* need to adjust for that.
*/
- if (ftrace_find_direct_func(self_addr + MCOUNT_INSN_SIZE)) {
- self_addr = *parent;
- parent++;
+ if (ftrace_direct_func_count) {
+ if (ftrace_find_direct_func(self_addr + MCOUNT_INSN_SIZE)) {
+ self_addr = *parent;
+ parent++;
+ }
}
/*
#endif /* CONFIG_FUNCTION_TRACER */
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+extern int ftrace_direct_func_count;
int register_ftrace_direct(unsigned long ip, unsigned long addr);
int unregister_ftrace_direct(unsigned long ip, unsigned long addr);
struct ftrace_direct_func *ftrace_find_direct_func(unsigned long addr);
#else
+# define ftrace_direct_func_count 0
static inline int register_ftrace_direct(unsigned long ip, unsigned long addr)
{
return -ENODEV;
/* Protected by rcu_tasks for reading, and direct_mutex for writing */
static struct ftrace_hash *direct_functions = EMPTY_HASH;
static DEFINE_MUTEX(direct_mutex);
+int ftrace_direct_func_count;
/*
* Search the direct_functions hash to see if the given instruction pointer
direct->addr = addr;
direct->count = 0;
list_add_rcu(&direct->next, &ftrace_direct_funcs);
+ ftrace_direct_func_count++;
}
entry->ip = ip;
if (free_hash)
free_ftrace_hash(free_hash);
free_hash = NULL;
+ ftrace_direct_func_count--;
}
} else {
if (!direct->count)
list_del_rcu(&direct->next);
synchronize_rcu_tasks();
kfree(direct);
+ ftrace_direct_func_count--;
}
}
out_unlock: