Skip to content

Commit f96f644

Browse files
liu-song-6borkmann
authored andcommitted
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 <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Reviewed-by: Steven Rostedt (Google) <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent f664f9c commit f96f644

File tree

2 files changed

+67
-24
lines changed

2 files changed

+67
-24
lines changed

include/linux/ftrace.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ unsigned long ftrace_find_rec_direct(unsigned long ip);
340340
int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
341341
int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
342342
int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
343+
int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned long addr);
343344

344345
#else
345346
struct ftrace_ops;
@@ -384,6 +385,10 @@ static inline int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned lo
384385
{
385386
return -ENODEV;
386387
}
388+
static inline int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned long addr)
389+
{
390+
return -ENODEV;
391+
}
387392
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
388393

389394
#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS

kernel/trace/ftrace.c

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5691,22 +5691,8 @@ int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
56915691
}
56925692
EXPORT_SYMBOL_GPL(unregister_ftrace_direct_multi);
56935693

5694-
/**
5695-
* modify_ftrace_direct_multi - Modify an existing direct 'multi' call
5696-
* to call something else
5697-
* @ops: The address of the struct ftrace_ops object
5698-
* @addr: The address of the new trampoline to call at @ops functions
5699-
*
5700-
* This is used to unregister currently registered direct caller and
5701-
* register new one @addr on functions registered in @ops object.
5702-
*
5703-
* Note there's window between ftrace_shutdown and ftrace_startup calls
5704-
* where there will be no callbacks called.
5705-
*
5706-
* Returns: zero on success. Non zero on error, which includes:
5707-
* -EINVAL - The @ops object was not properly registered.
5708-
*/
5709-
int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
5694+
static int
5695+
__modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
57105696
{
57115697
struct ftrace_hash *hash;
57125698
struct ftrace_func_entry *entry, *iter;
@@ -5717,20 +5703,15 @@ int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
57175703
int i, size;
57185704
int err;
57195705

5720-
if (check_direct_multi(ops))
5721-
return -EINVAL;
5722-
if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
5723-
return -EINVAL;
5724-
5725-
mutex_lock(&direct_mutex);
5706+
lockdep_assert_held_once(&direct_mutex);
57265707

57275708
/* Enable the tmp_ops to have the same functions as the direct ops */
57285709
ftrace_ops_init(&tmp_ops);
57295710
tmp_ops.func_hash = ops->func_hash;
57305711

57315712
err = register_ftrace_function(&tmp_ops);
57325713
if (err)
5733-
goto out_direct;
5714+
return err;
57345715

57355716
/*
57365717
* 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)
57545735
/* Removing the tmp_ops will add the updated direct callers to the functions */
57555736
unregister_ftrace_function(&tmp_ops);
57565737

5757-
out_direct:
5738+
return err;
5739+
}
5740+
5741+
/**
5742+
* modify_ftrace_direct_multi_nolock - Modify an existing direct 'multi' call
5743+
* to call something else
5744+
* @ops: The address of the struct ftrace_ops object
5745+
* @addr: The address of the new trampoline to call at @ops functions
5746+
*
5747+
* This is used to unregister currently registered direct caller and
5748+
* register new one @addr on functions registered in @ops object.
5749+
*
5750+
* Note there's window between ftrace_shutdown and ftrace_startup calls
5751+
* where there will be no callbacks called.
5752+
*
5753+
* Caller should already have direct_mutex locked, so we don't lock
5754+
* direct_mutex here.
5755+
*
5756+
* Returns: zero on success. Non zero on error, which includes:
5757+
* -EINVAL - The @ops object was not properly registered.
5758+
*/
5759+
int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned long addr)
5760+
{
5761+
if (check_direct_multi(ops))
5762+
return -EINVAL;
5763+
if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
5764+
return -EINVAL;
5765+
5766+
return __modify_ftrace_direct_multi(ops, addr);
5767+
}
5768+
EXPORT_SYMBOL_GPL(modify_ftrace_direct_multi_nolock);
5769+
5770+
/**
5771+
* modify_ftrace_direct_multi - Modify an existing direct 'multi' call
5772+
* to call something else
5773+
* @ops: The address of the struct ftrace_ops object
5774+
* @addr: The address of the new trampoline to call at @ops functions
5775+
*
5776+
* This is used to unregister currently registered direct caller and
5777+
* register new one @addr on functions registered in @ops object.
5778+
*
5779+
* Note there's window between ftrace_shutdown and ftrace_startup calls
5780+
* where there will be no callbacks called.
5781+
*
5782+
* Returns: zero on success. Non zero on error, which includes:
5783+
* -EINVAL - The @ops object was not properly registered.
5784+
*/
5785+
int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
5786+
{
5787+
int err;
5788+
5789+
if (check_direct_multi(ops))
5790+
return -EINVAL;
5791+
if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
5792+
return -EINVAL;
5793+
5794+
mutex_lock(&direct_mutex);
5795+
err = __modify_ftrace_direct_multi(ops, addr);
57585796
mutex_unlock(&direct_mutex);
57595797
return err;
57605798
}

0 commit comments

Comments
 (0)