[for-next][PATCH 25/33] ftrace: If the hash for a probe fails to update then free what was initialized

From: Steven Rostedt
Date: Fri Apr 21 2017 - 17:39:34 EST


From: "Steven Rostedt (VMware)" <rostedt@xxxxxxxxxxx>

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@xxxxxxxxxxx>
---
kernel/trace/ftrace.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 493c7ff7e860..8394055e6793 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -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
--
2.10.2