ftrace: If the hash for a probe fails to update then free what was initialized
authorSteven Rostedt (VMware) <rostedt@goodmis.org>
Wed, 5 Apr 2017 17:36:18 +0000 (13:36 -0400)
committerSteven Rostedt (VMware) <rostedt@goodmis.org>
Fri, 21 Apr 2017 02:06:44 +0000 (22:06 -0400)
If the ftrace_hash_move_and_update_ops() fails, and an ops->free() function
exists, then it needs to be called on all the ops that were added by this
registration.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
kernel/trace/ftrace.c

index 493c7ff7e8606d83e6b4389575375a00fd41af71..8394055e679370c655e4a35a922d2f8d722b17d3 100644 (file)
@@ -4003,7 +4003,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
        ret = ftrace_hash_move_and_update_ops(&ops->ops, orig_hash,
                                                      hash, 1);
        if (ret < 0)
-               goto out_unlock;
+               goto err_unlock;
 
        if (list_empty(&ops->list))
                list_add(&ops->list, &ftrace_func_probes);
@@ -4021,6 +4021,20 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
        free_ftrace_hash(hash);
 
        return ret;
+
+ err_unlock:
+       if (!ops->free)
+               goto out_unlock;
+
+       /* Failed to do the move, need to call the free functions */
+       for (i = 0; i < size; i++) {
+               hlist_for_each_entry(entry, &hash->buckets[i], hlist) {
+                       if (ftrace_lookup_ip(old_hash, entry->ip))
+                               continue;
+                       ops->free(ops, entry->ip, NULL);
+               }
+       }
+       goto out_unlock;
 }
 
 int