|
@@ -2293,10 +2293,13 @@ static void ftrace_run_update_code(int command)
|
|
|
FTRACE_WARN_ON(ret);
|
|
|
}
|
|
|
|
|
|
-static void ftrace_run_modify_code(struct ftrace_ops *ops, int command)
|
|
|
+static void ftrace_run_modify_code(struct ftrace_ops *ops, int command,
|
|
|
+ struct ftrace_hash *old_hash)
|
|
|
{
|
|
|
ops->flags |= FTRACE_OPS_FL_MODIFYING;
|
|
|
+ ops->old_hash.filter_hash = old_hash;
|
|
|
ftrace_run_update_code(command);
|
|
|
+ ops->old_hash.filter_hash = NULL;
|
|
|
ops->flags &= ~FTRACE_OPS_FL_MODIFYING;
|
|
|
}
|
|
|
|
|
@@ -3340,7 +3343,7 @@ static struct ftrace_ops trace_probe_ops __read_mostly =
|
|
|
|
|
|
static int ftrace_probe_registered;
|
|
|
|
|
|
-static void __enable_ftrace_function_probe(void)
|
|
|
+static void __enable_ftrace_function_probe(struct ftrace_hash *old_hash)
|
|
|
{
|
|
|
int ret;
|
|
|
int i;
|
|
@@ -3348,7 +3351,8 @@ static void __enable_ftrace_function_probe(void)
|
|
|
if (ftrace_probe_registered) {
|
|
|
/* still need to update the function call sites */
|
|
|
if (ftrace_enabled)
|
|
|
- ftrace_run_modify_code(&trace_probe_ops, FTRACE_UPDATE_CALLS);
|
|
|
+ ftrace_run_modify_code(&trace_probe_ops, FTRACE_UPDATE_CALLS,
|
|
|
+ old_hash);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -3477,13 +3481,14 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
|
|
|
} while_for_each_ftrace_rec();
|
|
|
|
|
|
ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash);
|
|
|
+
|
|
|
+ __enable_ftrace_function_probe(old_hash);
|
|
|
+
|
|
|
if (!ret)
|
|
|
free_ftrace_hash_rcu(old_hash);
|
|
|
else
|
|
|
count = ret;
|
|
|
|
|
|
- __enable_ftrace_function_probe();
|
|
|
-
|
|
|
out_unlock:
|
|
|
mutex_unlock(&ftrace_lock);
|
|
|
out:
|
|
@@ -3764,10 +3769,11 @@ ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove)
|
|
|
return add_hash_entry(hash, ip);
|
|
|
}
|
|
|
|
|
|
-static void ftrace_ops_update_code(struct ftrace_ops *ops)
|
|
|
+static void ftrace_ops_update_code(struct ftrace_ops *ops,
|
|
|
+ struct ftrace_hash *old_hash)
|
|
|
{
|
|
|
if (ops->flags & FTRACE_OPS_FL_ENABLED && ftrace_enabled)
|
|
|
- ftrace_run_modify_code(ops, FTRACE_UPDATE_CALLS);
|
|
|
+ ftrace_run_modify_code(ops, FTRACE_UPDATE_CALLS, old_hash);
|
|
|
}
|
|
|
|
|
|
static int
|
|
@@ -3813,7 +3819,7 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len,
|
|
|
old_hash = *orig_hash;
|
|
|
ret = ftrace_hash_move(ops, enable, orig_hash, hash);
|
|
|
if (!ret) {
|
|
|
- ftrace_ops_update_code(ops);
|
|
|
+ ftrace_ops_update_code(ops, old_hash);
|
|
|
free_ftrace_hash_rcu(old_hash);
|
|
|
}
|
|
|
mutex_unlock(&ftrace_lock);
|
|
@@ -4058,7 +4064,7 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
|
|
|
ret = ftrace_hash_move(iter->ops, filter_hash,
|
|
|
orig_hash, iter->hash);
|
|
|
if (!ret) {
|
|
|
- ftrace_ops_update_code(iter->ops);
|
|
|
+ ftrace_ops_update_code(iter->ops, old_hash);
|
|
|
free_ftrace_hash_rcu(old_hash);
|
|
|
}
|
|
|
mutex_unlock(&ftrace_lock);
|