aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2014-07-24 15:33:41 -0400
committerSteven Rostedt <rostedt@goodmis.org>2014-09-10 10:48:42 -0400
commit3296fc4e2509fa8870923ed52e7990040b151847 (patch)
treec89a3b63489c66a2472d08465ef54fe8c163b1e0 /kernel/trace/ftrace.c
parentf7aad4e1a8221210db7eb434349cc6fe87aeee8c (diff)
ftrace: Remove freeing of old_hash from ftrace_hash_move()
ftrace_hash_move() currently frees the old hash that is passed to it after replacing the pointer with the new hash. Instead of having the function do that chore, have the caller perform the free. This lets the ftrace_hash_move() be used a bit more freely, which is needed for changing the way the trampoline logic is done. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 708aea493d96..2c4eef49b1af 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1316,7 +1316,6 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable,
1316 struct ftrace_func_entry *entry; 1316 struct ftrace_func_entry *entry;
1317 struct hlist_node *tn; 1317 struct hlist_node *tn;
1318 struct hlist_head *hhd; 1318 struct hlist_head *hhd;
1319 struct ftrace_hash *old_hash;
1320 struct ftrace_hash *new_hash; 1319 struct ftrace_hash *new_hash;
1321 int size = src->count; 1320 int size = src->count;
1322 int bits = 0; 1321 int bits = 0;
@@ -1361,9 +1360,7 @@ update:
1361 */ 1360 */
1362 ftrace_hash_rec_disable_modify(ops, enable); 1361 ftrace_hash_rec_disable_modify(ops, enable);
1363 1362
1364 old_hash = *dst;
1365 rcu_assign_pointer(*dst, new_hash); 1363 rcu_assign_pointer(*dst, new_hash);
1366 free_ftrace_hash_rcu(old_hash);
1367 1364
1368 ftrace_hash_rec_enable_modify(ops, enable); 1365 ftrace_hash_rec_enable_modify(ops, enable);
1369 1366
@@ -3408,6 +3405,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3408{ 3405{
3409 struct ftrace_func_probe *entry; 3406 struct ftrace_func_probe *entry;
3410 struct ftrace_hash **orig_hash = &trace_probe_ops.func_hash->filter_hash; 3407 struct ftrace_hash **orig_hash = &trace_probe_ops.func_hash->filter_hash;
3408 struct ftrace_hash *old_hash = *orig_hash;
3411 struct ftrace_hash *hash; 3409 struct ftrace_hash *hash;
3412 struct ftrace_page *pg; 3410 struct ftrace_page *pg;
3413 struct dyn_ftrace *rec; 3411 struct dyn_ftrace *rec;
@@ -3426,7 +3424,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3426 3424
3427 mutex_lock(&trace_probe_ops.func_hash->regex_lock); 3425 mutex_lock(&trace_probe_ops.func_hash->regex_lock);
3428 3426
3429 hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); 3427 hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, old_hash);
3430 if (!hash) { 3428 if (!hash) {
3431 count = -ENOMEM; 3429 count = -ENOMEM;
3432 goto out; 3430 goto out;
@@ -3485,7 +3483,9 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3485 } while_for_each_ftrace_rec(); 3483 } while_for_each_ftrace_rec();
3486 3484
3487 ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); 3485 ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash);
3488 if (ret < 0) 3486 if (!ret)
3487 free_ftrace_hash_rcu(old_hash);
3488 else
3489 count = ret; 3489 count = ret;
3490 3490
3491 __enable_ftrace_function_probe(); 3491 __enable_ftrace_function_probe();
@@ -3512,6 +3512,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3512 struct ftrace_func_probe *entry; 3512 struct ftrace_func_probe *entry;
3513 struct ftrace_func_probe *p; 3513 struct ftrace_func_probe *p;
3514 struct ftrace_hash **orig_hash = &trace_probe_ops.func_hash->filter_hash; 3514 struct ftrace_hash **orig_hash = &trace_probe_ops.func_hash->filter_hash;
3515 struct ftrace_hash *old_hash = *orig_hash;
3515 struct list_head free_list; 3516 struct list_head free_list;
3516 struct ftrace_hash *hash; 3517 struct ftrace_hash *hash;
3517 struct hlist_node *tmp; 3518 struct hlist_node *tmp;
@@ -3519,6 +3520,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3519 int type = MATCH_FULL; 3520 int type = MATCH_FULL;
3520 int i, len = 0; 3521 int i, len = 0;
3521 char *search; 3522 char *search;
3523 int ret;
3522 3524
3523 if (glob && (strcmp(glob, "*") == 0 || !strlen(glob))) 3525 if (glob && (strcmp(glob, "*") == 0 || !strlen(glob)))
3524 glob = NULL; 3526 glob = NULL;
@@ -3577,8 +3579,11 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3577 * Remove after the disable is called. Otherwise, if the last 3579 * Remove after the disable is called. Otherwise, if the last
3578 * probe is removed, a null hash means *all enabled*. 3580 * probe is removed, a null hash means *all enabled*.
3579 */ 3581 */
3580 ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); 3582 ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash);
3581 synchronize_sched(); 3583 synchronize_sched();
3584 if (!ret)
3585 free_ftrace_hash_rcu(old_hash);
3586
3582 list_for_each_entry_safe(entry, p, &free_list, free_list) { 3587 list_for_each_entry_safe(entry, p, &free_list, free_list) {
3583 list_del(&entry->free_list); 3588 list_del(&entry->free_list);
3584 ftrace_free_entry(entry); 3589 ftrace_free_entry(entry);
@@ -3776,6 +3781,7 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len,
3776 unsigned long ip, int remove, int reset, int enable) 3781 unsigned long ip, int remove, int reset, int enable)
3777{ 3782{
3778 struct ftrace_hash **orig_hash; 3783 struct ftrace_hash **orig_hash;
3784 struct ftrace_hash *old_hash;
3779 struct ftrace_hash *hash; 3785 struct ftrace_hash *hash;
3780 int ret; 3786 int ret;
3781 3787
@@ -3810,10 +3816,12 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len,
3810 } 3816 }
3811 3817
3812 mutex_lock(&ftrace_lock); 3818 mutex_lock(&ftrace_lock);
3819 old_hash = *orig_hash;
3813 ret = ftrace_hash_move(ops, enable, orig_hash, hash); 3820 ret = ftrace_hash_move(ops, enable, orig_hash, hash);
3814 if (!ret) 3821 if (!ret) {
3815 ftrace_ops_update_code(ops); 3822 ftrace_ops_update_code(ops);
3816 3823 free_ftrace_hash_rcu(old_hash);
3824 }
3817 mutex_unlock(&ftrace_lock); 3825 mutex_unlock(&ftrace_lock);
3818 3826
3819 out_regex_unlock: 3827 out_regex_unlock:
@@ -4022,6 +4030,7 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
4022 struct seq_file *m = (struct seq_file *)file->private_data; 4030 struct seq_file *m = (struct seq_file *)file->private_data;
4023 struct ftrace_iterator *iter; 4031 struct ftrace_iterator *iter;
4024 struct ftrace_hash **orig_hash; 4032 struct ftrace_hash **orig_hash;
4033 struct ftrace_hash *old_hash;
4025 struct trace_parser *parser; 4034 struct trace_parser *parser;
4026 int filter_hash; 4035 int filter_hash;
4027 int ret; 4036 int ret;
@@ -4051,11 +4060,13 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
4051 orig_hash = &iter->ops->func_hash->notrace_hash; 4060 orig_hash = &iter->ops->func_hash->notrace_hash;
4052 4061
4053 mutex_lock(&ftrace_lock); 4062 mutex_lock(&ftrace_lock);
4063 old_hash = *orig_hash;
4054 ret = ftrace_hash_move(iter->ops, filter_hash, 4064 ret = ftrace_hash_move(iter->ops, filter_hash,
4055 orig_hash, iter->hash); 4065 orig_hash, iter->hash);
4056 if (!ret) 4066 if (!ret) {
4057 ftrace_ops_update_code(iter->ops); 4067 ftrace_ops_update_code(iter->ops);
4058 4068 free_ftrace_hash_rcu(old_hash);
4069 }
4059 mutex_unlock(&ftrace_lock); 4070 mutex_unlock(&ftrace_lock);
4060 } 4071 }
4061 4072