aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (VMware) <rostedt@goodmis.org>2017-04-05 13:36:18 -0400
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2017-04-20 22:06:44 -0400
commit8d70725e452cac9796e9025ccd79c45ffcc4d109 (patch)
tree2db0703a73df7d182204b2d65d1c71a3d441a246
parenteee8ded131f15e0f5b1897c9c4a7687fabd28822 (diff)
ftrace: If the hash for a probe fails to update then free what was initialized
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>
-rw-r--r--kernel/trace/ftrace.c16
1 files changed, 15 insertions, 1 deletions
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,
4003 ret = ftrace_hash_move_and_update_ops(&ops->ops, orig_hash, 4003 ret = ftrace_hash_move_and_update_ops(&ops->ops, orig_hash,
4004 hash, 1); 4004 hash, 1);
4005 if (ret < 0) 4005 if (ret < 0)
4006 goto out_unlock; 4006 goto err_unlock;
4007 4007
4008 if (list_empty(&ops->list)) 4008 if (list_empty(&ops->list))
4009 list_add(&ops->list, &ftrace_func_probes); 4009 list_add(&ops->list, &ftrace_func_probes);
@@ -4021,6 +4021,20 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
4021 free_ftrace_hash(hash); 4021 free_ftrace_hash(hash);
4022 4022
4023 return ret; 4023 return ret;
4024
4025 err_unlock:
4026 if (!ops->free)
4027 goto out_unlock;
4028
4029 /* Failed to do the move, need to call the free functions */
4030 for (i = 0; i < size; i++) {
4031 hlist_for_each_entry(entry, &hash->buckets[i], hlist) {
4032 if (ftrace_lookup_ip(old_hash, entry->ip))
4033 continue;
4034 ops->free(ops, entry->ip, NULL);
4035 }
4036 }
4037 goto out_unlock;
4024} 4038}
4025 4039
4026int 4040int