Commit 59495740 authored by Florent Revest's avatar Florent Revest Committed by Steven Rostedt (Google)

ftrace: Let unregister_ftrace_direct_multi() call ftrace_free_filter()

A common pattern when using the ftrace_direct_multi API is to unregister
the ops and also immediately free its filter. We've noticed it's very
easy for users to miss calling ftrace_free_filter().

This adds a "free_filters" argument to unregister_ftrace_direct_multi()
to both remind the user they should free filters and also to make their
life easier.

Link: https://lkml.kernel.org/r/20230321140424.345218-2-revest@chromium.orgSuggested-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Signed-off-by: default avatarFlorent Revest <revest@chromium.org>
Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent e8d018dd
...@@ -407,7 +407,8 @@ int ftrace_modify_direct_caller(struct ftrace_func_entry *entry, ...@@ -407,7 +407,8 @@ int ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
unsigned long new_addr); unsigned long new_addr);
unsigned long ftrace_find_rec_direct(unsigned long ip); 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,
bool free_filters);
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); int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned long addr);
...@@ -446,7 +447,8 @@ static inline int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned ...@@ -446,7 +447,8 @@ static inline int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned
{ {
return -ENODEV; return -ENODEV;
} }
static inline int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr) static inline int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr,
bool free_filters)
{ {
return -ENODEV; return -ENODEV;
} }
......
...@@ -198,7 +198,7 @@ static int unregister_fentry(struct bpf_trampoline *tr, void *old_addr) ...@@ -198,7 +198,7 @@ static int unregister_fentry(struct bpf_trampoline *tr, void *old_addr)
int ret; int ret;
if (tr->func.ftrace_managed) if (tr->func.ftrace_managed)
ret = unregister_ftrace_direct_multi(tr->fops, (long)old_addr); ret = unregister_ftrace_direct_multi(tr->fops, (long)old_addr, false);
else else
ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, old_addr, NULL); ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, old_addr, NULL);
......
...@@ -5805,7 +5805,8 @@ EXPORT_SYMBOL_GPL(register_ftrace_direct_multi); ...@@ -5805,7 +5805,8 @@ EXPORT_SYMBOL_GPL(register_ftrace_direct_multi);
* 0 on success * 0 on success
* -EINVAL - The @ops object was not properly registered. * -EINVAL - The @ops object was not properly registered.
*/ */
int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr) int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr,
bool free_filters)
{ {
struct ftrace_hash *hash = ops->func_hash->filter_hash; struct ftrace_hash *hash = ops->func_hash->filter_hash;
int err; int err;
...@@ -5823,6 +5824,9 @@ int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr) ...@@ -5823,6 +5824,9 @@ int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
/* cleanup for possible another register call */ /* cleanup for possible another register call */
ops->func = NULL; ops->func = NULL;
ops->trampoline = 0; ops->trampoline = 0;
if (free_filters)
ftrace_free_filter(ops);
return err; return err;
} }
EXPORT_SYMBOL_GPL(unregister_ftrace_direct_multi); EXPORT_SYMBOL_GPL(unregister_ftrace_direct_multi);
......
...@@ -151,8 +151,7 @@ static int __init ftrace_direct_multi_init(void) ...@@ -151,8 +151,7 @@ static int __init ftrace_direct_multi_init(void)
static void __exit ftrace_direct_multi_exit(void) static void __exit ftrace_direct_multi_exit(void)
{ {
kthread_stop(simple_tsk); kthread_stop(simple_tsk);
unregister_ftrace_direct_multi(&direct, my_tramp); unregister_ftrace_direct_multi(&direct, my_tramp, true);
ftrace_free_filter(&direct);
} }
module_init(ftrace_direct_multi_init); module_init(ftrace_direct_multi_init);
......
...@@ -78,8 +78,7 @@ static int __init ftrace_direct_multi_init(void) ...@@ -78,8 +78,7 @@ static int __init ftrace_direct_multi_init(void)
static void __exit ftrace_direct_multi_exit(void) static void __exit ftrace_direct_multi_exit(void)
{ {
unregister_ftrace_direct_multi(&direct, (unsigned long) my_tramp); unregister_ftrace_direct_multi(&direct, (unsigned long) my_tramp, true);
ftrace_free_filter(&direct);
} }
module_init(ftrace_direct_multi_init); module_init(ftrace_direct_multi_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment