diff options
-rw-r--r-- | kernel/trace/ftrace.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index fb186b9ddf51..483b8c1b1de0 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -2293,10 +2293,13 @@ static void ftrace_run_update_code(int command) | |||
2293 | FTRACE_WARN_ON(ret); | 2293 | FTRACE_WARN_ON(ret); |
2294 | } | 2294 | } |
2295 | 2295 | ||
2296 | static void ftrace_run_modify_code(struct ftrace_ops *ops, int command) | 2296 | static void ftrace_run_modify_code(struct ftrace_ops *ops, int command, |
2297 | struct ftrace_hash *old_hash) | ||
2297 | { | 2298 | { |
2298 | ops->flags |= FTRACE_OPS_FL_MODIFYING; | 2299 | ops->flags |= FTRACE_OPS_FL_MODIFYING; |
2300 | ops->old_hash.filter_hash = old_hash; | ||
2299 | ftrace_run_update_code(command); | 2301 | ftrace_run_update_code(command); |
2302 | ops->old_hash.filter_hash = NULL; | ||
2300 | ops->flags &= ~FTRACE_OPS_FL_MODIFYING; | 2303 | ops->flags &= ~FTRACE_OPS_FL_MODIFYING; |
2301 | } | 2304 | } |
2302 | 2305 | ||
@@ -3340,7 +3343,7 @@ static struct ftrace_ops trace_probe_ops __read_mostly = | |||
3340 | 3343 | ||
3341 | static int ftrace_probe_registered; | 3344 | static int ftrace_probe_registered; |
3342 | 3345 | ||
3343 | static void __enable_ftrace_function_probe(void) | 3346 | static void __enable_ftrace_function_probe(struct ftrace_hash *old_hash) |
3344 | { | 3347 | { |
3345 | int ret; | 3348 | int ret; |
3346 | int i; | 3349 | int i; |
@@ -3348,7 +3351,8 @@ static void __enable_ftrace_function_probe(void) | |||
3348 | if (ftrace_probe_registered) { | 3351 | if (ftrace_probe_registered) { |
3349 | /* still need to update the function call sites */ | 3352 | /* still need to update the function call sites */ |
3350 | if (ftrace_enabled) | 3353 | if (ftrace_enabled) |
3351 | ftrace_run_modify_code(&trace_probe_ops, FTRACE_UPDATE_CALLS); | 3354 | ftrace_run_modify_code(&trace_probe_ops, FTRACE_UPDATE_CALLS, |
3355 | old_hash); | ||
3352 | return; | 3356 | return; |
3353 | } | 3357 | } |
3354 | 3358 | ||
@@ -3477,13 +3481,14 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, | |||
3477 | } while_for_each_ftrace_rec(); | 3481 | } while_for_each_ftrace_rec(); |
3478 | 3482 | ||
3479 | ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); | 3483 | ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); |
3484 | |||
3485 | __enable_ftrace_function_probe(old_hash); | ||
3486 | |||
3480 | if (!ret) | 3487 | if (!ret) |
3481 | free_ftrace_hash_rcu(old_hash); | 3488 | free_ftrace_hash_rcu(old_hash); |
3482 | else | 3489 | else |
3483 | count = ret; | 3490 | count = ret; |
3484 | 3491 | ||
3485 | __enable_ftrace_function_probe(); | ||
3486 | |||
3487 | out_unlock: | 3492 | out_unlock: |
3488 | mutex_unlock(&ftrace_lock); | 3493 | mutex_unlock(&ftrace_lock); |
3489 | out: | 3494 | out: |
@@ -3764,10 +3769,11 @@ ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove) | |||
3764 | return add_hash_entry(hash, ip); | 3769 | return add_hash_entry(hash, ip); |
3765 | } | 3770 | } |
3766 | 3771 | ||
3767 | static void ftrace_ops_update_code(struct ftrace_ops *ops) | 3772 | static void ftrace_ops_update_code(struct ftrace_ops *ops, |
3773 | struct ftrace_hash *old_hash) | ||
3768 | { | 3774 | { |
3769 | if (ops->flags & FTRACE_OPS_FL_ENABLED && ftrace_enabled) | 3775 | if (ops->flags & FTRACE_OPS_FL_ENABLED && ftrace_enabled) |
3770 | ftrace_run_modify_code(ops, FTRACE_UPDATE_CALLS); | 3776 | ftrace_run_modify_code(ops, FTRACE_UPDATE_CALLS, old_hash); |
3771 | } | 3777 | } |
3772 | 3778 | ||
3773 | static int | 3779 | static int |
@@ -3813,7 +3819,7 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len, | |||
3813 | old_hash = *orig_hash; | 3819 | old_hash = *orig_hash; |
3814 | ret = ftrace_hash_move(ops, enable, orig_hash, hash); | 3820 | ret = ftrace_hash_move(ops, enable, orig_hash, hash); |
3815 | if (!ret) { | 3821 | if (!ret) { |
3816 | ftrace_ops_update_code(ops); | 3822 | ftrace_ops_update_code(ops, old_hash); |
3817 | free_ftrace_hash_rcu(old_hash); | 3823 | free_ftrace_hash_rcu(old_hash); |
3818 | } | 3824 | } |
3819 | mutex_unlock(&ftrace_lock); | 3825 | mutex_unlock(&ftrace_lock); |
@@ -4058,7 +4064,7 @@ int ftrace_regex_release(struct inode *inode, struct file *file) | |||
4058 | ret = ftrace_hash_move(iter->ops, filter_hash, | 4064 | ret = ftrace_hash_move(iter->ops, filter_hash, |
4059 | orig_hash, iter->hash); | 4065 | orig_hash, iter->hash); |
4060 | if (!ret) { | 4066 | if (!ret) { |
4061 | ftrace_ops_update_code(iter->ops); | 4067 | ftrace_ops_update_code(iter->ops, old_hash); |
4062 | free_ftrace_hash_rcu(old_hash); | 4068 | free_ftrace_hash_rcu(old_hash); |
4063 | } | 4069 | } |
4064 | mutex_unlock(&ftrace_lock); | 4070 | mutex_unlock(&ftrace_lock); |