diff options
author | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2017-04-05 13:36:18 -0400 |
---|---|---|
committer | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2017-04-20 22:06:44 -0400 |
commit | 8d70725e452cac9796e9025ccd79c45ffcc4d109 (patch) | |
tree | 2db0703a73df7d182204b2d65d1c71a3d441a246 | |
parent | eee8ded131f15e0f5b1897c9c4a7687fabd28822 (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.c | 16 |
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 | ||
4026 | int | 4040 | int |