Merge tag 'trace-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / kernel / trace / ftrace.c
index 9b44abb2c5a0bf585ff73de22c07031af35b76da..8a5c017bb50c141bfca4d8206ac2a1805d224185 100644 (file)
@@ -66,7 +66,7 @@
 
 static struct ftrace_ops ftrace_list_end __read_mostly = {
        .func           = ftrace_stub,
-       .flags          = FTRACE_OPS_FL_RECURSION_SAFE,
+       .flags          = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_STUB,
 };
 
 /* ftrace_enabled is a method to turn ftrace on or off */
@@ -694,7 +694,6 @@ int ftrace_profile_pages_init(struct ftrace_profile_stat *stat)
                free_page(tmp);
        }
 
-       free_page((unsigned long)stat->pages);
        stat->pages = NULL;
        stat->start = NULL;
 
@@ -755,7 +754,6 @@ ftrace_find_profiled_func(struct ftrace_profile_stat *stat, unsigned long ip)
 {
        struct ftrace_profile *rec;
        struct hlist_head *hhd;
-       struct hlist_node *n;
        unsigned long key;
 
        key = hash_long(ip, FTRACE_PROFILE_HASH_BITS);
@@ -764,7 +762,7 @@ ftrace_find_profiled_func(struct ftrace_profile_stat *stat, unsigned long ip)
        if (hlist_empty(hhd))
                return NULL;
 
-       hlist_for_each_entry_rcu(rec, n, hhd, node) {
+       hlist_for_each_entry_rcu(rec, hhd, node) {
                if (rec->ip == ip)
                        return rec;
        }
@@ -1047,6 +1045,19 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
 
 static struct pid * const ftrace_swapper_pid = &init_struct_pid;
 
+loff_t
+ftrace_filter_lseek(struct file *file, loff_t offset, int whence)
+{
+       loff_t ret;
+
+       if (file->f_mode & FMODE_READ)
+               ret = seq_lseek(file, offset, whence);
+       else
+               file->f_pos = ret = 1;
+
+       return ret;
+}
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 #ifndef CONFIG_FTRACE_MCOUNT_RECORD
@@ -1126,7 +1137,6 @@ ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip)
        unsigned long key;
        struct ftrace_func_entry *entry;
        struct hlist_head *hhd;
-       struct hlist_node *n;
 
        if (ftrace_hash_empty(hash))
                return NULL;
@@ -1138,7 +1148,7 @@ ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip)
 
        hhd = &hash->buckets[key];
 
-       hlist_for_each_entry_rcu(entry, n, hhd, hlist) {
+       hlist_for_each_entry_rcu(entry, hhd, hlist) {
                if (entry->ip == ip)
                        return entry;
        }
@@ -1195,7 +1205,7 @@ remove_hash_entry(struct ftrace_hash *hash,
 static void ftrace_hash_clear(struct ftrace_hash *hash)
 {
        struct hlist_head *hhd;
-       struct hlist_node *tp, *tn;
+       struct hlist_node *tn;
        struct ftrace_func_entry *entry;
        int size = 1 << hash->size_bits;
        int i;
@@ -1205,7 +1215,7 @@ static void ftrace_hash_clear(struct ftrace_hash *hash)
 
        for (i = 0; i < size; i++) {
                hhd = &hash->buckets[i];
-               hlist_for_each_entry_safe(entry, tp, tn, hhd, hlist)
+               hlist_for_each_entry_safe(entry, tn, hhd, hlist)
                        free_hash_entry(hash, entry);
        }
        FTRACE_WARN_ON(hash->count);
@@ -1268,7 +1278,6 @@ alloc_and_copy_ftrace_hash(int size_bits, struct ftrace_hash *hash)
 {
        struct ftrace_func_entry *entry;
        struct ftrace_hash *new_hash;
-       struct hlist_node *tp;
        int size;
        int ret;
        int i;
@@ -1283,7 +1292,7 @@ alloc_and_copy_ftrace_hash(int size_bits, struct ftrace_hash *hash)
 
        size = 1 << hash->size_bits;
        for (i = 0; i < size; i++) {
-               hlist_for_each_entry(entry, tp, &hash->buckets[i], hlist) {
+               hlist_for_each_entry(entry, &hash->buckets[i], hlist) {
                        ret = add_hash_entry(new_hash, entry->ip);
                        if (ret < 0)
                                goto free_hash;
@@ -1309,7 +1318,7 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable,
                 struct ftrace_hash **dst, struct ftrace_hash *src)
 {
        struct ftrace_func_entry *entry;
-       struct hlist_node *tp, *tn;
+       struct hlist_node *tn;
        struct hlist_head *hhd;
        struct ftrace_hash *old_hash;
        struct ftrace_hash *new_hash;
@@ -1354,7 +1363,7 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable,
        size = 1 << src->size_bits;
        for (i = 0; i < size; i++) {
                hhd = &src->buckets[i];
-               hlist_for_each_entry_safe(entry, tp, tn, hhd, hlist) {
+               hlist_for_each_entry_safe(entry, tn, hhd, hlist) {
                        remove_hash_entry(src, entry);
                        __add_hash_entry(new_hash, entry);
                }
@@ -2604,7 +2613,7 @@ static void ftrace_filter_reset(struct ftrace_hash *hash)
  * routine, you can use ftrace_filter_write() for the write
  * routine if @flag has FTRACE_ITER_FILTER set, or
  * ftrace_notrace_write() if @flag has FTRACE_ITER_NOTRACE set.
- * ftrace_regex_lseek() should be used as the lseek routine, and
+ * ftrace_filter_lseek() should be used as the lseek routine, and
  * release must call ftrace_regex_release().
  */
 int
@@ -2688,19 +2697,6 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
                                 inode, file);
 }
 
-loff_t
-ftrace_regex_lseek(struct file *file, loff_t offset, int whence)
-{
-       loff_t ret;
-
-       if (file->f_mode & FMODE_READ)
-               ret = seq_lseek(file, offset, whence);
-       else
-               file->f_pos = ret = 1;
-
-       return ret;
-}
-
 static int ftrace_match(char *str, char *regex, int len, int type)
 {
        int matched = 0;
@@ -2889,7 +2885,6 @@ static void function_trace_probe_call(unsigned long ip, unsigned long parent_ip,
 {
        struct ftrace_func_probe *entry;
        struct hlist_head *hhd;
-       struct hlist_node *n;
        unsigned long key;
 
        key = hash_long(ip, FTRACE_HASH_BITS);
@@ -2905,7 +2900,7 @@ static void function_trace_probe_call(unsigned long ip, unsigned long parent_ip,
         * on the hash. rcu_read_lock is too dangerous here.
         */
        preempt_disable_notrace();
-       hlist_for_each_entry_rcu(entry, n, hhd, node) {
+       hlist_for_each_entry_rcu(entry, hhd, node) {
                if (entry->ip == ip)
                        entry->ops->func(ip, parent_ip, &entry->data);
        }
@@ -3081,7 +3076,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
        struct ftrace_hash **orig_hash = &trace_probe_ops.filter_hash;
        struct list_head free_list;
        struct ftrace_hash *hash;
-       struct hlist_node *n, *tmp;
+       struct hlist_node *tmp;
        char str[KSYM_SYMBOL_LEN];
        int type = MATCH_FULL;
        int i, len = 0;
@@ -3112,7 +3107,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
        for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
                struct hlist_head *hhd = &ftrace_func_hash[i];
 
-               hlist_for_each_entry_safe(entry, n, tmp, hhd, node) {
+               hlist_for_each_entry_safe(entry, tmp, hhd, node) {
 
                        /* break up if statements for readability */
                        if ((flags & PROBE_TEST_FUNC) && entry->ops != ops)
@@ -3614,7 +3609,7 @@ static const struct file_operations ftrace_filter_fops = {
        .open = ftrace_filter_open,
        .read = seq_read,
        .write = ftrace_filter_write,
-       .llseek = ftrace_regex_lseek,
+       .llseek = ftrace_filter_lseek,
        .release = ftrace_regex_release,
 };
 
@@ -3622,7 +3617,7 @@ static const struct file_operations ftrace_notrace_fops = {
        .open = ftrace_notrace_open,
        .read = seq_read,
        .write = ftrace_notrace_write,
-       .llseek = ftrace_regex_lseek,
+       .llseek = ftrace_filter_lseek,
        .release = ftrace_regex_release,
 };
 
@@ -3828,8 +3823,8 @@ static const struct file_operations ftrace_graph_fops = {
        .open           = ftrace_graph_open,
        .read           = seq_read,
        .write          = ftrace_graph_write,
+       .llseek         = ftrace_filter_lseek,
        .release        = ftrace_graph_release,
-       .llseek         = seq_lseek,
 };
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
@@ -4175,7 +4170,8 @@ ftrace_ops_control_func(unsigned long ip, unsigned long parent_ip,
        preempt_disable_notrace();
        trace_recursion_set(TRACE_CONTROL_BIT);
        do_for_each_ftrace_op(op, ftrace_control_list) {
-               if (!ftrace_function_local_disabled(op) &&
+               if (!(op->flags & FTRACE_OPS_FL_STUB) &&
+                   !ftrace_function_local_disabled(op) &&
                    ftrace_ops_test(op, ip))
                        op->func(ip, parent_ip, op, regs);
        } while_for_each_ftrace_op(op);
@@ -4483,7 +4479,7 @@ static const struct file_operations ftrace_pid_fops = {
        .open           = ftrace_pid_open,
        .write          = ftrace_pid_write,
        .read           = seq_read,
-       .llseek         = seq_lseek,
+       .llseek         = ftrace_filter_lseek,
        .release        = ftrace_pid_release,
 };
 
@@ -4599,12 +4595,8 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
                ftrace_startup_sysctl();
 
                /* we are starting ftrace again */
-               if (ftrace_ops_list != &ftrace_list_end) {
-                       if (ftrace_ops_list->next == &ftrace_list_end)
-                               ftrace_trace_function = ftrace_ops_list->func;
-                       else
-                               ftrace_trace_function = ftrace_ops_list_func;
-               }
+               if (ftrace_ops_list != &ftrace_list_end)
+                       update_ftrace_function();
 
        } else {
                /* stopping ftrace calls (just send to ftrace_stub) */