mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-19 21:44:08 +00:00
ftrace: Add modify_ftrace_direct_multi_nolock
This is similar to modify_ftrace_direct_multi, but does not acquire direct_mutex. This is useful when direct_mutex is already locked by the user. Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org> Link: https://lore.kernel.org/bpf/20220720002126.803253-2-song@kernel.org
This commit is contained in:
parent
f664f9c6b4
commit
f96f644ab9
2 changed files with 67 additions and 24 deletions
|
@ -340,6 +340,7 @@ unsigned long ftrace_find_rec_direct(unsigned long ip);
|
||||||
int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
|
int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
|
||||||
int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
|
int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
|
||||||
int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
|
int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
|
||||||
|
int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned long addr);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
struct ftrace_ops;
|
struct ftrace_ops;
|
||||||
|
@ -384,6 +385,10 @@ static inline int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned lo
|
||||||
{
|
{
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
static inline int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned long addr)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
|
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
|
||||||
|
|
||||||
#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
|
#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
|
||||||
|
|
|
@ -5691,22 +5691,8 @@ int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(unregister_ftrace_direct_multi);
|
EXPORT_SYMBOL_GPL(unregister_ftrace_direct_multi);
|
||||||
|
|
||||||
/**
|
static int
|
||||||
* modify_ftrace_direct_multi - Modify an existing direct 'multi' call
|
__modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
|
||||||
* to call something else
|
|
||||||
* @ops: The address of the struct ftrace_ops object
|
|
||||||
* @addr: The address of the new trampoline to call at @ops functions
|
|
||||||
*
|
|
||||||
* This is used to unregister currently registered direct caller and
|
|
||||||
* register new one @addr on functions registered in @ops object.
|
|
||||||
*
|
|
||||||
* Note there's window between ftrace_shutdown and ftrace_startup calls
|
|
||||||
* where there will be no callbacks called.
|
|
||||||
*
|
|
||||||
* Returns: zero on success. Non zero on error, which includes:
|
|
||||||
* -EINVAL - The @ops object was not properly registered.
|
|
||||||
*/
|
|
||||||
int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
|
|
||||||
{
|
{
|
||||||
struct ftrace_hash *hash;
|
struct ftrace_hash *hash;
|
||||||
struct ftrace_func_entry *entry, *iter;
|
struct ftrace_func_entry *entry, *iter;
|
||||||
|
@ -5717,12 +5703,7 @@ int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
|
||||||
int i, size;
|
int i, size;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (check_direct_multi(ops))
|
lockdep_assert_held_once(&direct_mutex);
|
||||||
return -EINVAL;
|
|
||||||
if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
mutex_lock(&direct_mutex);
|
|
||||||
|
|
||||||
/* Enable the tmp_ops to have the same functions as the direct ops */
|
/* Enable the tmp_ops to have the same functions as the direct ops */
|
||||||
ftrace_ops_init(&tmp_ops);
|
ftrace_ops_init(&tmp_ops);
|
||||||
|
@ -5730,7 +5711,7 @@ int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
|
||||||
|
|
||||||
err = register_ftrace_function(&tmp_ops);
|
err = register_ftrace_function(&tmp_ops);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_direct;
|
return err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now the ftrace_ops_list_func() is called to do the direct callers.
|
* Now the ftrace_ops_list_func() is called to do the direct callers.
|
||||||
|
@ -5754,7 +5735,64 @@ int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
|
||||||
/* Removing the tmp_ops will add the updated direct callers to the functions */
|
/* Removing the tmp_ops will add the updated direct callers to the functions */
|
||||||
unregister_ftrace_function(&tmp_ops);
|
unregister_ftrace_function(&tmp_ops);
|
||||||
|
|
||||||
out_direct:
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* modify_ftrace_direct_multi_nolock - Modify an existing direct 'multi' call
|
||||||
|
* to call something else
|
||||||
|
* @ops: The address of the struct ftrace_ops object
|
||||||
|
* @addr: The address of the new trampoline to call at @ops functions
|
||||||
|
*
|
||||||
|
* This is used to unregister currently registered direct caller and
|
||||||
|
* register new one @addr on functions registered in @ops object.
|
||||||
|
*
|
||||||
|
* Note there's window between ftrace_shutdown and ftrace_startup calls
|
||||||
|
* where there will be no callbacks called.
|
||||||
|
*
|
||||||
|
* Caller should already have direct_mutex locked, so we don't lock
|
||||||
|
* direct_mutex here.
|
||||||
|
*
|
||||||
|
* Returns: zero on success. Non zero on error, which includes:
|
||||||
|
* -EINVAL - The @ops object was not properly registered.
|
||||||
|
*/
|
||||||
|
int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned long addr)
|
||||||
|
{
|
||||||
|
if (check_direct_multi(ops))
|
||||||
|
return -EINVAL;
|
||||||
|
if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return __modify_ftrace_direct_multi(ops, addr);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(modify_ftrace_direct_multi_nolock);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* modify_ftrace_direct_multi - Modify an existing direct 'multi' call
|
||||||
|
* to call something else
|
||||||
|
* @ops: The address of the struct ftrace_ops object
|
||||||
|
* @addr: The address of the new trampoline to call at @ops functions
|
||||||
|
*
|
||||||
|
* This is used to unregister currently registered direct caller and
|
||||||
|
* register new one @addr on functions registered in @ops object.
|
||||||
|
*
|
||||||
|
* Note there's window between ftrace_shutdown and ftrace_startup calls
|
||||||
|
* where there will be no callbacks called.
|
||||||
|
*
|
||||||
|
* Returns: zero on success. Non zero on error, which includes:
|
||||||
|
* -EINVAL - The @ops object was not properly registered.
|
||||||
|
*/
|
||||||
|
int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (check_direct_multi(ops))
|
||||||
|
return -EINVAL;
|
||||||
|
if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_lock(&direct_mutex);
|
||||||
|
err = __modify_ftrace_direct_multi(ops, addr);
|
||||||
mutex_unlock(&direct_mutex);
|
mutex_unlock(&direct_mutex);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue