* [PATCH bpf-next v2 03/18] ftrace: factor out ftrace_direct_update from register_ftrace_direct
[not found] <20250703121521.1874196-1-dongml2@chinatelecom.cn>
@ 2025-07-03 12:15 ` Menglong Dong
2025-07-05 2:41 ` kernel test robot
2025-07-03 12:15 ` [PATCH bpf-next v2 04/18] ftrace: add reset_ftrace_direct_ips Menglong Dong
2025-07-03 12:15 ` [PATCH bpf-next v2 07/18] bpf: refactor the modules_array to ptr_array Menglong Dong
2 siblings, 1 reply; 8+ messages in thread
From: Menglong Dong @ 2025-07-03 12:15 UTC (permalink / raw)
To: alexei.starovoitov, rostedt, jolsa
Cc: bpf, Menglong Dong, Mark Rutland, Mathieu Desnoyers, linux-kernel,
linux-trace-kernel
Factor out ftrace_direct_update() from register_ftrace_direct(), which is
used to add new entries to the direct_functions. This function will be
used in the later patch.
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
kernel/trace/ftrace.c | 108 +++++++++++++++++++++++-------------------
1 file changed, 60 insertions(+), 48 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 4203fad56b6c..f5f6d7bc26f0 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -5953,53 +5953,18 @@ static void register_ftrace_direct_cb(struct rcu_head *rhp)
free_ftrace_hash(fhp);
}
-/**
- * register_ftrace_direct - Call a custom trampoline directly
- * for multiple functions registered in @ops
- * @ops: The address of the struct ftrace_ops object
- * @addr: The address of the trampoline to call at @ops functions
- *
- * This is used to connect a direct calls to @addr from the nop locations
- * of the functions registered in @ops (with by ftrace_set_filter_ip
- * function).
- *
- * The location that it calls (@addr) must be able to handle a direct call,
- * and save the parameters of the function being traced, and restore them
- * (or inject new ones if needed), before returning.
- *
- * Returns:
- * 0 on success
- * -EINVAL - The @ops object was already registered with this call or
- * when there are no functions in @ops object.
- * -EBUSY - Another direct function is already attached (there can be only one)
- * -ENODEV - @ip does not point to a ftrace nop location (or not supported)
- * -ENOMEM - There was an allocation failure.
- */
-int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
+static int ftrace_direct_update(struct ftrace_hash *hash, unsigned long addr)
{
- struct ftrace_hash *hash, *new_hash = NULL, *free_hash = NULL;
struct ftrace_func_entry *entry, *new;
+ struct ftrace_hash *new_hash = NULL;
int err = -EBUSY, size, i;
- if (ops->func || ops->trampoline)
- return -EINVAL;
- if (!(ops->flags & FTRACE_OPS_FL_INITIALIZED))
- return -EINVAL;
- if (ops->flags & FTRACE_OPS_FL_ENABLED)
- return -EINVAL;
-
- hash = ops->func_hash->filter_hash;
- if (ftrace_hash_empty(hash))
- return -EINVAL;
-
- mutex_lock(&direct_mutex);
-
/* Make sure requested entries are not already registered.. */
size = 1 << hash->size_bits;
for (i = 0; i < size; i++) {
hlist_for_each_entry(entry, &hash->buckets[i], hlist) {
if (ftrace_find_rec_direct(entry->ip))
- goto out_unlock;
+ goto out;
}
}
@@ -6012,7 +5977,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
size = FTRACE_HASH_MAX_BITS;
new_hash = alloc_ftrace_hash(size);
if (!new_hash)
- goto out_unlock;
+ goto out;
/* Now copy over the existing direct entries */
size = 1 << direct_functions->size_bits;
@@ -6020,7 +5985,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
hlist_for_each_entry(entry, &direct_functions->buckets[i], hlist) {
new = add_hash_entry(new_hash, entry->ip);
if (!new)
- goto out_unlock;
+ goto out;
new->direct = entry->direct;
}
}
@@ -6031,16 +5996,67 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
hlist_for_each_entry(entry, &hash->buckets[i], hlist) {
new = add_hash_entry(new_hash, entry->ip);
if (!new)
- goto out_unlock;
+ goto out;
/* Update both the copy and the hash entry */
new->direct = addr;
entry->direct = addr;
}
}
- free_hash = direct_functions;
rcu_assign_pointer(direct_functions, new_hash);
new_hash = NULL;
+ err = 0;
+out:
+ if (new_hash)
+ free_ftrace_hash(new_hash);
+
+ return err;
+}
+
+/**
+ * register_ftrace_direct - Call a custom trampoline directly
+ * for multiple functions registered in @ops
+ * @ops: The address of the struct ftrace_ops object
+ * @addr: The address of the trampoline to call at @ops functions
+ *
+ * This is used to connect a direct calls to @addr from the nop locations
+ * of the functions registered in @ops (with by ftrace_set_filter_ip
+ * function).
+ *
+ * The location that it calls (@addr) must be able to handle a direct call,
+ * and save the parameters of the function being traced, and restore them
+ * (or inject new ones if needed), before returning.
+ *
+ * Returns:
+ * 0 on success
+ * -EINVAL - The @ops object was already registered with this call or
+ * when there are no functions in @ops object.
+ * -EBUSY - Another direct function is already attached (there can be only one)
+ * -ENODEV - @ip does not point to a ftrace nop location (or not supported)
+ * -ENOMEM - There was an allocation failure.
+ */
+int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
+{
+ struct ftrace_hash *hash, *free_hash = NULL;
+ int err = -EBUSY;
+
+ if (ops->func || ops->trampoline)
+ return -EINVAL;
+ if (!(ops->flags & FTRACE_OPS_FL_INITIALIZED))
+ return -EINVAL;
+ if (ops->flags & FTRACE_OPS_FL_ENABLED)
+ return -EINVAL;
+
+ hash = ops->func_hash->filter_hash;
+ if (ftrace_hash_empty(hash))
+ return -EINVAL;
+
+ mutex_lock(&direct_mutex);
+
+ free_hash = direct_functions;
+ err = ftrace_direct_update(hash, addr);
+ if (err)
+ goto out_unlock;
ops->func = call_direct_funcs;
ops->flags = MULTI_FLAGS;
@@ -6048,15 +6064,11 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
ops->direct_call = addr;
err = register_ftrace_function_nolock(ops);
-
- out_unlock:
- mutex_unlock(&direct_mutex);
-
if (free_hash && free_hash != EMPTY_HASH)
call_rcu_tasks(&free_hash->rcu, register_ftrace_direct_cb);
- if (new_hash)
- free_ftrace_hash(new_hash);
+ out_unlock:
+ mutex_unlock(&direct_mutex);
return err;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next v2 04/18] ftrace: add reset_ftrace_direct_ips
[not found] <20250703121521.1874196-1-dongml2@chinatelecom.cn>
2025-07-03 12:15 ` [PATCH bpf-next v2 03/18] ftrace: factor out ftrace_direct_update from register_ftrace_direct Menglong Dong
@ 2025-07-03 12:15 ` Menglong Dong
2025-07-03 15:30 ` Steven Rostedt
2025-07-03 12:15 ` [PATCH bpf-next v2 07/18] bpf: refactor the modules_array to ptr_array Menglong Dong
2 siblings, 1 reply; 8+ messages in thread
From: Menglong Dong @ 2025-07-03 12:15 UTC (permalink / raw)
To: alexei.starovoitov, rostedt, jolsa
Cc: bpf, Menglong Dong, Mark Rutland, Mathieu Desnoyers, linux-kernel,
linux-trace-kernel
For now, we can change the address of a direct ftrace_ops with
modify_ftrace_direct(). However, we can't change the functions to filter
for a direct ftrace_ops. Therefore, we introduce the function
reset_ftrace_direct_ips() to do such things, and this function will reset
the functions to filter for a direct ftrace_ops.
This function do such thing in following steps:
1. filter out the new functions from ips that don't exist in the
ops->func_hash->filter_hash and add them to the new hash.
2. add all the functions in the new ftrace_hash to direct_functions by
ftrace_direct_update().
3. reset the functions to filter of the ftrace_ops to the ips with
ftrace_set_filter_ips().
4. remove the functions that in the old ftrace_hash, but not in the new
ftrace_hash from direct_functions.
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
include/linux/ftrace.h | 7 ++++
kernel/trace/ftrace.c | 75 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 82 insertions(+)
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index b672ca15f265..b7c60f5a4120 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -528,6 +528,8 @@ int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsigned long addr);
void ftrace_stub_direct_tramp(void);
+int reset_ftrace_direct_ips(struct ftrace_ops *ops, unsigned long *ips,
+ unsigned int cnt);
#else
struct ftrace_ops;
static inline unsigned long ftrace_find_rec_direct(unsigned long ip)
@@ -551,6 +553,11 @@ static inline int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsigned l
{
return -ENODEV;
}
+static inline int reset_ftrace_direct_ips(struct ftrace_ops *ops, unsigned long *ips,
+ unsigned int cnt)
+{
+ return -ENODEV;
+}
/*
* This must be implemented by the architecture.
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index f5f6d7bc26f0..db3aa61889d3 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -6224,6 +6224,81 @@ int modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
return err;
}
EXPORT_SYMBOL_GPL(modify_ftrace_direct);
+
+/* reset the ips for a direct ftrace (add or remove) */
+int reset_ftrace_direct_ips(struct ftrace_ops *ops, unsigned long *ips,
+ unsigned int cnt)
+{
+ struct ftrace_hash *hash, *free_hash;
+ struct ftrace_func_entry *entry, *del;
+ unsigned long ip;
+ int err, size;
+
+ if (check_direct_multi(ops))
+ return -EINVAL;
+ if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
+ return -EINVAL;
+
+ mutex_lock(&direct_mutex);
+ hash = alloc_ftrace_hash(FTRACE_HASH_DEFAULT_BITS);
+ if (!hash) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
+ /* find out the new functions from ips and add to hash */
+ for (int i = 0; i < cnt; i++) {
+ ip = ftrace_location(ips[i]);
+ if (!ip) {
+ err = -ENOENT;
+ goto out_unlock;
+ }
+ if (__ftrace_lookup_ip(ops->func_hash->filter_hash, ip))
+ continue;
+ err = __ftrace_match_addr(hash, ip, 0);
+ if (err)
+ goto out_unlock;
+ }
+
+ free_hash = direct_functions;
+ /* add the new ips to direct hash. */
+ err = ftrace_direct_update(hash, ops->direct_call);
+ if (err)
+ goto out_unlock;
+
+ if (free_hash && free_hash != EMPTY_HASH)
+ call_rcu_tasks(&free_hash->rcu, register_ftrace_direct_cb);
+
+ free_ftrace_hash(hash);
+ hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS,
+ ops->func_hash->filter_hash);
+ if (!hash) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+ err = ftrace_set_filter_ips(ops, ips, cnt, 0, 1);
+
+ /* remove the entries that don't exist in our filter_hash anymore
+ * from the direct_functions.
+ */
+ size = 1 << hash->size_bits;
+ for (int i = 0; i < size; i++) {
+ hlist_for_each_entry(entry, &hash->buckets[i], hlist) {
+ if (__ftrace_lookup_ip(ops->func_hash->filter_hash, entry->ip))
+ continue;
+ del = __ftrace_lookup_ip(direct_functions, entry->ip);
+ if (del && del->direct == ops->direct_call) {
+ remove_hash_entry(direct_functions, del);
+ kfree(del);
+ }
+ }
+ }
+out_unlock:
+ mutex_unlock(&direct_mutex);
+ if (hash)
+ free_ftrace_hash(hash);
+ return err;
+}
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
/**
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next v2 07/18] bpf: refactor the modules_array to ptr_array
[not found] <20250703121521.1874196-1-dongml2@chinatelecom.cn>
2025-07-03 12:15 ` [PATCH bpf-next v2 03/18] ftrace: factor out ftrace_direct_update from register_ftrace_direct Menglong Dong
2025-07-03 12:15 ` [PATCH bpf-next v2 04/18] ftrace: add reset_ftrace_direct_ips Menglong Dong
@ 2025-07-03 12:15 ` Menglong Dong
2 siblings, 0 replies; 8+ messages in thread
From: Menglong Dong @ 2025-07-03 12:15 UTC (permalink / raw)
To: alexei.starovoitov, rostedt, jolsa
Cc: bpf, Menglong Dong, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo, Mathieu Desnoyers, linux-kernel, linux-trace-kernel
Refactor the struct modules_array to more general struct ptr_array, which
is used to store the pointers.
Meanwhile, introduce the bpf_try_add_ptr(), which checks the existing of
the ptr before adding it to the array.
Seems it should be moved to another files in "lib", and I'm not sure where
to add it now, and let's move it to kernel/bpf/syscall.c for now.
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
include/linux/bpf.h | 10 +++++++++
kernel/bpf/syscall.c | 36 ++++++++++++++++++++++++++++++
kernel/trace/bpf_trace.c | 48 ++++++----------------------------------
3 files changed, 53 insertions(+), 41 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 5e6d83750d39..bb3ab1aa3a9d 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -314,6 +314,16 @@ struct bpf_map {
s64 __percpu *elem_count;
};
+struct ptr_array {
+ void **ptrs;
+ int cnt;
+ int cap;
+};
+
+int bpf_add_ptr(struct ptr_array *arr, void *ptr);
+bool bpf_has_ptr(struct ptr_array *arr, struct module *mod);
+int bpf_try_add_ptr(struct ptr_array *arr, void *ptr);
+
static inline const char *btf_field_type_name(enum btf_field_type type)
{
switch (type) {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 56500381c28a..8ce061b079ec 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -619,6 +619,42 @@ int bpf_map_alloc_pages(const struct bpf_map *map, int nid,
return ret;
}
+int bpf_add_ptr(struct ptr_array *arr, void *ptr)
+{
+ void **ptrs;
+
+ if (arr->cnt == arr->cap) {
+ arr->cap = max(16, arr->cap * 3 / 2);
+ ptrs = krealloc_array(arr->ptrs, arr->cap, sizeof(*ptrs), GFP_KERNEL);
+ if (!ptrs)
+ return -ENOMEM;
+ arr->ptrs = ptrs;
+ }
+
+ arr->ptrs[arr->cnt] = ptr;
+ arr->cnt++;
+ return 0;
+}
+
+bool bpf_has_ptr(struct ptr_array *arr, struct module *mod)
+{
+ int i;
+
+ for (i = arr->cnt - 1; i >= 0; i--) {
+ if (arr->ptrs[i] == mod)
+ return true;
+ }
+ return false;
+}
+
+int bpf_try_add_ptr(struct ptr_array *arr, void *ptr)
+{
+ if (bpf_has_ptr(arr, ptr))
+ return -EEXIST;
+ if (bpf_add_ptr(arr, ptr))
+ return -ENOMEM;
+ return 0;
+}
static int btf_field_cmp(const void *a, const void *b)
{
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 0a06ea6638fe..167fd1dcc28b 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -2779,43 +2779,9 @@ static void symbols_swap_r(void *a, void *b, int size, const void *priv)
}
}
-struct modules_array {
- struct module **mods;
- int mods_cnt;
- int mods_cap;
-};
-
-static int add_module(struct modules_array *arr, struct module *mod)
-{
- struct module **mods;
-
- if (arr->mods_cnt == arr->mods_cap) {
- arr->mods_cap = max(16, arr->mods_cap * 3 / 2);
- mods = krealloc_array(arr->mods, arr->mods_cap, sizeof(*mods), GFP_KERNEL);
- if (!mods)
- return -ENOMEM;
- arr->mods = mods;
- }
-
- arr->mods[arr->mods_cnt] = mod;
- arr->mods_cnt++;
- return 0;
-}
-
-static bool has_module(struct modules_array *arr, struct module *mod)
-{
- int i;
-
- for (i = arr->mods_cnt - 1; i >= 0; i--) {
- if (arr->mods[i] == mod)
- return true;
- }
- return false;
-}
-
static int get_modules_for_addrs(struct module ***mods, unsigned long *addrs, u32 addrs_cnt)
{
- struct modules_array arr = {};
+ struct ptr_array arr = {};
u32 i, err = 0;
for (i = 0; i < addrs_cnt; i++) {
@@ -2825,7 +2791,7 @@ static int get_modules_for_addrs(struct module ***mods, unsigned long *addrs, u3
scoped_guard(rcu) {
mod = __module_address(addrs[i]);
/* Either no module or it's already stored */
- if (!mod || has_module(&arr, mod)) {
+ if (!mod || bpf_has_ptr(&arr, mod)) {
skip_add = true;
break; /* scoped_guard */
}
@@ -2836,7 +2802,7 @@ static int get_modules_for_addrs(struct module ***mods, unsigned long *addrs, u3
continue;
if (err)
break;
- err = add_module(&arr, mod);
+ err = bpf_add_ptr(&arr, mod);
if (err) {
module_put(mod);
break;
@@ -2845,14 +2811,14 @@ static int get_modules_for_addrs(struct module ***mods, unsigned long *addrs, u3
/* We return either err < 0 in case of error, ... */
if (err) {
- kprobe_multi_put_modules(arr.mods, arr.mods_cnt);
- kfree(arr.mods);
+ kprobe_multi_put_modules((struct module **)arr.ptrs, arr.cnt);
+ kfree(arr.ptrs);
return err;
}
/* or number of modules found if everything is ok. */
- *mods = arr.mods;
- return arr.mods_cnt;
+ *mods = (struct module **)arr.ptrs;
+ return arr.cnt;
}
static int addrs_check_error_injection_list(unsigned long *addrs, u32 cnt)
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 04/18] ftrace: add reset_ftrace_direct_ips
2025-07-03 12:15 ` [PATCH bpf-next v2 04/18] ftrace: add reset_ftrace_direct_ips Menglong Dong
@ 2025-07-03 15:30 ` Steven Rostedt
2025-07-04 1:54 ` Menglong Dong
0 siblings, 1 reply; 8+ messages in thread
From: Steven Rostedt @ 2025-07-03 15:30 UTC (permalink / raw)
To: Menglong Dong
Cc: alexei.starovoitov, jolsa, bpf, Menglong Dong, Mark Rutland,
Mathieu Desnoyers, linux-kernel, linux-trace-kernel
On Thu, 3 Jul 2025 20:15:07 +0800
Menglong Dong <menglong8.dong@gmail.com> wrote:
Note, the tracing subsystem uses capitalization in the subject:
ftrace: Add reset_ftrace_direct_ips
> For now, we can change the address of a direct ftrace_ops with
> modify_ftrace_direct(). However, we can't change the functions to filter
> for a direct ftrace_ops. Therefore, we introduce the function
> reset_ftrace_direct_ips() to do such things, and this function will reset
> the functions to filter for a direct ftrace_ops.
>
> This function do such thing in following steps:
>
> 1. filter out the new functions from ips that don't exist in the
> ops->func_hash->filter_hash and add them to the new hash.
> 2. add all the functions in the new ftrace_hash to direct_functions by
> ftrace_direct_update().
> 3. reset the functions to filter of the ftrace_ops to the ips with
> ftrace_set_filter_ips().
> 4. remove the functions that in the old ftrace_hash, but not in the new
> ftrace_hash from direct_functions.
Please also include a module that can be loaded for testing.
See samples/ftrace/ftrace-direct*
But make it a separate patch. And you'll need to add a test in selftests.
See tools/testing/selftests/ftrace/test.d/direct
>
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> ---
> include/linux/ftrace.h | 7 ++++
> kernel/trace/ftrace.c | 75 ++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 82 insertions(+)
>
> diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
> index b672ca15f265..b7c60f5a4120 100644
> --- a/include/linux/ftrace.h
> +++ b/include/linux/ftrace.h
> @@ -528,6 +528,8 @@ int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsigned long addr);
>
> void ftrace_stub_direct_tramp(void);
>
> +int reset_ftrace_direct_ips(struct ftrace_ops *ops, unsigned long *ips,
> + unsigned int cnt);
> #else
> struct ftrace_ops;
> static inline unsigned long ftrace_find_rec_direct(unsigned long ip)
> @@ -551,6 +553,11 @@ static inline int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsigned l
> {
> return -ENODEV;
> }
> +static inline int reset_ftrace_direct_ips(struct ftrace_ops *ops, unsigned long *ips,
> + unsigned int cnt)
> +{
> + return -ENODEV;
> +}
>
> /*
> * This must be implemented by the architecture.
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index f5f6d7bc26f0..db3aa61889d3 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -6224,6 +6224,81 @@ int modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
> return err;
> }
> EXPORT_SYMBOL_GPL(modify_ftrace_direct);
> +
> +/* reset the ips for a direct ftrace (add or remove) */
As this function is being used externally, it requires proper KernelDoc
headers.
What exactly do you mean by "reset"?
> +int reset_ftrace_direct_ips(struct ftrace_ops *ops, unsigned long *ips,
> + unsigned int cnt)
> +{
> + struct ftrace_hash *hash, *free_hash;
> + struct ftrace_func_entry *entry, *del;
> + unsigned long ip;
> + int err, size;
> +
> + if (check_direct_multi(ops))
> + return -EINVAL;
> + if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
> + return -EINVAL;
> +
> + mutex_lock(&direct_mutex);
> + hash = alloc_ftrace_hash(FTRACE_HASH_DEFAULT_BITS);
> + if (!hash) {
> + err = -ENOMEM;
> + goto out_unlock;
> + }
> +
> + /* find out the new functions from ips and add to hash */
Capitalize comment: /* Find out ...
> + for (int i = 0; i < cnt; i++) {
> + ip = ftrace_location(ips[i]);
> + if (!ip) {
> + err = -ENOENT;
> + goto out_unlock;
> + }
> + if (__ftrace_lookup_ip(ops->func_hash->filter_hash, ip))
> + continue;
> + err = __ftrace_match_addr(hash, ip, 0);
> + if (err)
> + goto out_unlock;
> + }
> +
> + free_hash = direct_functions;
Add newline.
> + /* add the new ips to direct hash. */
Again capitalize.
> + err = ftrace_direct_update(hash, ops->direct_call);
> + if (err)
> + goto out_unlock;
> +
> + if (free_hash && free_hash != EMPTY_HASH)
> + call_rcu_tasks(&free_hash->rcu, register_ftrace_direct_cb);
Since the above is now used more than once, let's make it into a helper
function so that if things change, there's only one place to change it:
free_ftrace_direct(free_hash);
static inline void free_ftrace_direct(struct ftrace_hash *hash)
{
if (hash && hash != EMPTY_HASH)
call_rcu_tasks(&free_hash->rcu, register_ftrace_direct_cb);
}
> +
> + free_ftrace_hash(hash);
> + hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS,
> + ops->func_hash->filter_hash);
> + if (!hash) {
> + err = -ENOMEM;
> + goto out_unlock;
> + }
> + err = ftrace_set_filter_ips(ops, ips, cnt, 0, 1);
> +
> + /* remove the entries that don't exist in our filter_hash anymore
> + * from the direct_functions.
> + */
This isn't the network subsystem, we use the default comment style for multiple lines:
/*
* line 1
* line 2
* ...
*/
-- Steve
> + size = 1 << hash->size_bits;
> + for (int i = 0; i < size; i++) {
> + hlist_for_each_entry(entry, &hash->buckets[i], hlist) {
> + if (__ftrace_lookup_ip(ops->func_hash->filter_hash, entry->ip))
> + continue;
> + del = __ftrace_lookup_ip(direct_functions, entry->ip);
> + if (del && del->direct == ops->direct_call) {
> + remove_hash_entry(direct_functions, del);
> + kfree(del);
> + }
> + }
> + }
> +out_unlock:
> + mutex_unlock(&direct_mutex);
> + if (hash)
> + free_ftrace_hash(hash);
> + return err;
> +}
> #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
>
> /**
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 04/18] ftrace: add reset_ftrace_direct_ips
2025-07-03 15:30 ` Steven Rostedt
@ 2025-07-04 1:54 ` Menglong Dong
2025-07-07 18:52 ` Steven Rostedt
0 siblings, 1 reply; 8+ messages in thread
From: Menglong Dong @ 2025-07-04 1:54 UTC (permalink / raw)
To: Steven Rostedt
Cc: alexei.starovoitov, jolsa, bpf, Menglong Dong, Mark Rutland,
Mathieu Desnoyers, linux-kernel, linux-trace-kernel
On Thu, Jul 3, 2025 at 11:30 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Thu, 3 Jul 2025 20:15:07 +0800
> Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> Note, the tracing subsystem uses capitalization in the subject:
>
> ftrace: Add reset_ftrace_direct_ips
Hi, Steven. Thanks for your feedback. I'll keep this point
in mind. I was wondering why Alexei changed the "make" to "Make"
in c11f34e30088 :/
>
>
> > For now, we can change the address of a direct ftrace_ops with
> > modify_ftrace_direct(). However, we can't change the functions to filter
> > for a direct ftrace_ops. Therefore, we introduce the function
> > reset_ftrace_direct_ips() to do such things, and this function will reset
> > the functions to filter for a direct ftrace_ops.
> >
> > This function do such thing in following steps:
> >
> > 1. filter out the new functions from ips that don't exist in the
> > ops->func_hash->filter_hash and add them to the new hash.
> > 2. add all the functions in the new ftrace_hash to direct_functions by
> > ftrace_direct_update().
> > 3. reset the functions to filter of the ftrace_ops to the ips with
> > ftrace_set_filter_ips().
> > 4. remove the functions that in the old ftrace_hash, but not in the new
> > ftrace_hash from direct_functions.
>
> Please also include a module that can be loaded for testing.
> See samples/ftrace/ftrace-direct*
>
> But make it a separate patch. And you'll need to add a test in selftests.
> See tools/testing/selftests/ftrace/test.d/direct
Okay!
>
> >
> > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > ---
> > include/linux/ftrace.h | 7 ++++
> > kernel/trace/ftrace.c | 75 ++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 82 insertions(+)
> >
> > diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
> > index b672ca15f265..b7c60f5a4120 100644
> > --- a/include/linux/ftrace.h
> > +++ b/include/linux/ftrace.h
> > @@ -528,6 +528,8 @@ int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsigned long addr);
> >
> > void ftrace_stub_direct_tramp(void);
> >
> > +int reset_ftrace_direct_ips(struct ftrace_ops *ops, unsigned long *ips,
> > + unsigned int cnt);
> > #else
> > struct ftrace_ops;
> > static inline unsigned long ftrace_find_rec_direct(unsigned long ip)
> > @@ -551,6 +553,11 @@ static inline int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsigned l
> > {
> > return -ENODEV;
> > }
> > +static inline int reset_ftrace_direct_ips(struct ftrace_ops *ops, unsigned long *ips,
> > + unsigned int cnt)
> > +{
> > + return -ENODEV;
> > +}
> >
> > /*
> > * This must be implemented by the architecture.
> > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> > index f5f6d7bc26f0..db3aa61889d3 100644
> > --- a/kernel/trace/ftrace.c
> > +++ b/kernel/trace/ftrace.c
> > @@ -6224,6 +6224,81 @@ int modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
> > return err;
> > }
> > EXPORT_SYMBOL_GPL(modify_ftrace_direct);
> > +
> > +/* reset the ips for a direct ftrace (add or remove) */
>
> As this function is being used externally, it requires proper KernelDoc
> headers.
Okay!
>
> What exactly do you mean by "reset"?
It means to reset the filter hash of the ftrace_ops to ips. In
the origin logic, the filter hash of a direct ftrace_ops will not
be changed. However, in the tracing-multi case, there are
multi functions in the filter hash and can change. This function
is used to change the filter hash of a direct ftrace_ops.
>
> > +int reset_ftrace_direct_ips(struct ftrace_ops *ops, unsigned long *ips,
> > + unsigned int cnt)
> > +{
> > + struct ftrace_hash *hash, *free_hash;
> > + struct ftrace_func_entry *entry, *del;
> > + unsigned long ip;
> > + int err, size;
> > +
> > + if (check_direct_multi(ops))
> > + return -EINVAL;
> > + if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
> > + return -EINVAL;
> > +
> > + mutex_lock(&direct_mutex);
> > + hash = alloc_ftrace_hash(FTRACE_HASH_DEFAULT_BITS);
> > + if (!hash) {
> > + err = -ENOMEM;
> > + goto out_unlock;
> > + }
> > +
> > + /* find out the new functions from ips and add to hash */
>
> Capitalize comment: /* Find out ...
>
> > + for (int i = 0; i < cnt; i++) {
> > + ip = ftrace_location(ips[i]);
> > + if (!ip) {
> > + err = -ENOENT;
> > + goto out_unlock;
> > + }
> > + if (__ftrace_lookup_ip(ops->func_hash->filter_hash, ip))
> > + continue;
> > + err = __ftrace_match_addr(hash, ip, 0);
> > + if (err)
> > + goto out_unlock;
> > + }
> > +
> > + free_hash = direct_functions;
>
> Add newline.
>
> > + /* add the new ips to direct hash. */
>
> Again capitalize.
>
> > + err = ftrace_direct_update(hash, ops->direct_call);
> > + if (err)
> > + goto out_unlock;
> > +
> > + if (free_hash && free_hash != EMPTY_HASH)
> > + call_rcu_tasks(&free_hash->rcu, register_ftrace_direct_cb);
>
> Since the above is now used more than once, let's make it into a helper
> function so that if things change, there's only one place to change it:
>
> free_ftrace_direct(free_hash);
>
> static inline void free_ftrace_direct(struct ftrace_hash *hash)
> {
> if (hash && hash != EMPTY_HASH)
> call_rcu_tasks(&free_hash->rcu, register_ftrace_direct_cb);
> }
Sounds nice~
>
> > +
> > + free_ftrace_hash(hash);
> > + hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS,
> > + ops->func_hash->filter_hash);
> > + if (!hash) {
> > + err = -ENOMEM;
> > + goto out_unlock;
> > + }
> > + err = ftrace_set_filter_ips(ops, ips, cnt, 0, 1);
> > +
> > + /* remove the entries that don't exist in our filter_hash anymore
> > + * from the direct_functions.
> > + */
>
> This isn't the network subsystem, we use the default comment style for multiple lines:
>
> /*
> * line 1
> * line 2
> * ...
> */
Okay! I'll do the modification as your comment in this (and other)
patches.
Thanks!
Menglong Dong
>
> -- Steve
>
> > + size = 1 << hash->size_bits;
> > + for (int i = 0; i < size; i++) {
> > + hlist_for_each_entry(entry, &hash->buckets[i], hlist) {
> > + if (__ftrace_lookup_ip(ops->func_hash->filter_hash, entry->ip))
> > + continue;
> > + del = __ftrace_lookup_ip(direct_functions, entry->ip);
> > + if (del && del->direct == ops->direct_call) {
> > + remove_hash_entry(direct_functions, del);
> > + kfree(del);
> > + }
> > + }
> > + }
> > +out_unlock:
> > + mutex_unlock(&direct_mutex);
> > + if (hash)
> > + free_ftrace_hash(hash);
> > + return err;
> > +}
> > #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
> >
> > /**
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 03/18] ftrace: factor out ftrace_direct_update from register_ftrace_direct
2025-07-03 12:15 ` [PATCH bpf-next v2 03/18] ftrace: factor out ftrace_direct_update from register_ftrace_direct Menglong Dong
@ 2025-07-05 2:41 ` kernel test robot
0 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2025-07-05 2:41 UTC (permalink / raw)
To: Menglong Dong, alexei.starovoitov, rostedt, jolsa
Cc: oe-kbuild-all, bpf, Menglong Dong, Mark Rutland,
Mathieu Desnoyers, linux-kernel, linux-trace-kernel
Hi Menglong,
kernel test robot noticed the following build warnings:
[auto build test WARNING on bpf-next/master]
url: https://github.com/intel-lab-lkp/linux/commits/Menglong-Dong/bpf-add-function-hash-table-for-tracing-multi/20250703-203035
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link: https://lore.kernel.org/r/20250703121521.1874196-4-dongml2%40chinatelecom.cn
patch subject: [PATCH bpf-next v2 03/18] ftrace: factor out ftrace_direct_update from register_ftrace_direct
config: x86_64-randconfig-123-20250704 (https://download.01.org/0day-ci/archive/20250705/202507051048.PEDxVblg-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250705/202507051048.PEDxVblg-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202507051048.PEDxVblg-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
kernel/trace/ftrace.c:233:49: sparse: got struct ftrace_ops [noderef] __rcu *[addressable] [toplevel] ftrace_ops_list
kernel/trace/ftrace.c:318:16: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_ops **p @@ got struct ftrace_ops [noderef] __rcu **list @@
kernel/trace/ftrace.c:318:16: sparse: expected struct ftrace_ops **p
kernel/trace/ftrace.c:318:16: sparse: got struct ftrace_ops [noderef] __rcu **list
kernel/trace/ftrace.c:318:50: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_ops **p @@ got struct ftrace_ops [noderef] __rcu ** @@
kernel/trace/ftrace.c:318:50: sparse: expected struct ftrace_ops **p
kernel/trace/ftrace.c:318:50: sparse: got struct ftrace_ops [noderef] __rcu **
kernel/trace/ftrace.c:325:12: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_ops * @@ got struct ftrace_ops [noderef] __rcu *next @@
kernel/trace/ftrace.c:325:12: sparse: expected struct ftrace_ops *
kernel/trace/ftrace.c:325:12: sparse: got struct ftrace_ops [noderef] __rcu *next
kernel/trace/ftrace.c:1072:43: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *notrace_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:1072:43: sparse: expected struct ftrace_hash [noderef] __rcu *notrace_hash
kernel/trace/ftrace.c:1072:43: sparse: got struct ftrace_hash *
kernel/trace/ftrace.c:1073:43: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *filter_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:1073:43: sparse: expected struct ftrace_hash [noderef] __rcu *filter_hash
kernel/trace/ftrace.c:1073:43: sparse: got struct ftrace_hash *
kernel/trace/ftrace.c:1298:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:1298:40: sparse: expected struct ftrace_hash *hash
kernel/trace/ftrace.c:1298:40: sparse: got struct ftrace_hash [noderef] __rcu *filter_hash
kernel/trace/ftrace.c:1299:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:1299:40: sparse: expected struct ftrace_hash *hash
kernel/trace/ftrace.c:1299:40: sparse: got struct ftrace_hash [noderef] __rcu *notrace_hash
kernel/trace/ftrace.c:1300:37: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *filter_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:1300:37: sparse: expected struct ftrace_hash [noderef] __rcu *filter_hash
kernel/trace/ftrace.c:1300:37: sparse: got struct ftrace_hash *
kernel/trace/ftrace.c:1301:38: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *notrace_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:1301:38: sparse: expected struct ftrace_hash [noderef] __rcu *notrace_hash
kernel/trace/ftrace.c:1301:38: sparse: got struct ftrace_hash *
kernel/trace/ftrace.c:2100:54: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct ftrace_hash *old_hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:2100:54: sparse: expected struct ftrace_hash *old_hash
kernel/trace/ftrace.c:2100:54: sparse: got struct ftrace_hash [noderef] __rcu *filter_hash
kernel/trace/ftrace.c:1505:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/trace/ftrace.c:1505:9: sparse: struct ftrace_hash [noderef] __rcu *
kernel/trace/ftrace.c:1505:9: sparse: struct ftrace_hash *
kernel/trace/ftrace.c:1521:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:1522:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:1523:40: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:1524:42: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:1695:18: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_ops *ops @@ got struct ftrace_ops [noderef] __rcu *[addressable] [toplevel] ftrace_ops_list @@
kernel/trace/ftrace.c:1696:43: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_ops *ops @@ got struct ftrace_ops [noderef] __rcu *next @@
kernel/trace/ftrace.c:1757:14: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:1758:22: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *notrace_hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:2078:50: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:2089:50: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:2572:53: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *static [toplevel] direct_functions @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:2583:36: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *static [toplevel] direct_functions @@
kernel/trace/ftrace.c:3379:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash *B @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3380:66: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash **orig_hash @@ got struct ftrace_hash [noderef] __rcu ** @@
kernel/trace/ftrace.c:3386:52: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash *B @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:3387:66: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash **orig_hash @@ got struct ftrace_hash [noderef] __rcu ** @@
kernel/trace/ftrace.c:3400:41: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3401:51: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *src @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3404:52: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash *notrace_hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:3408:52: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *src @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:3423:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3424:42: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3432:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:3438:81: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3442:54: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash *notrace_hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:3444:56: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash *new_hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3474:60: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash *new_hash1 @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:3475:49: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected struct ftrace_hash *new_hash2 @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:3514:45: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *filter_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:3516:46: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *notrace_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:3518:48: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *filter_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:3520:49: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *notrace_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:3526:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3527:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:3533:34: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *save_filter_hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3534:35: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *save_notrace_hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:3536:45: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *filter_hash @@ got struct ftrace_hash *[addressable] filter_hash @@
kernel/trace/ftrace.c:3537:46: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *notrace_hash @@ got struct ftrace_hash *[addressable] notrace_hash @@
kernel/trace/ftrace.c:3542:53: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *filter_hash @@ got struct ftrace_hash *save_filter_hash @@
kernel/trace/ftrace.c:3543:54: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *notrace_hash @@ got struct ftrace_hash *save_notrace_hash @@
kernel/trace/ftrace.c:3590:31: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *filter_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:3591:32: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *notrace_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:3606:59: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *[addressable] filter_hash @@
kernel/trace/ftrace.c:3607:59: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *[addressable] notrace_hash @@
kernel/trace/ftrace.c:3612:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *[addressable] filter_hash @@
kernel/trace/ftrace.c:3613:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *[addressable] notrace_hash @@
kernel/trace/ftrace.c:3615:39: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *[addressable] filter_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:3616:40: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *[addressable] notrace_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:3658:48: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3659:48: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:3660:45: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *filter_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:3661:46: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *notrace_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:3947:14: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3964:22: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:4650:22: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:4653:22: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:5060:27: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash **orig_hash @@ got struct ftrace_hash [noderef] __rcu ** @@
kernel/trace/ftrace.c:5062:27: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash **orig_hash @@ got struct ftrace_hash [noderef] __rcu ** @@
kernel/trace/ftrace.c:5442:19: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash **orig_hash @@ got struct ftrace_hash [noderef] __rcu ** @@
kernel/trace/ftrace.c:5586:19: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash **orig_hash @@ got struct ftrace_hash [noderef] __rcu ** @@
kernel/trace/ftrace.c:5592:34: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *filter_hash @@ got struct ftrace_hash *[assigned] old_hash @@
kernel/trace/ftrace.c:5857:27: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash **orig_hash @@ got struct ftrace_hash [noderef] __rcu ** @@
kernel/trace/ftrace.c:5859:27: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash **orig_hash @@ got struct ftrace_hash [noderef] __rcu ** @@
kernel/trace/ftrace.c:5940:50: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *static [toplevel] direct_functions @@
kernel/trace/ftrace.c:5942:51: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *static [toplevel] direct_functions @@
kernel/trace/ftrace.c:6050:14: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
>> kernel/trace/ftrace.c:6056:19: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *free_hash @@ got struct ftrace_hash [noderef] __rcu *static [addressable] [assigned] [toplevel] direct_functions @@
kernel/trace/ftrace.c:6095:50: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:6147:14: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:6151:52: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *static [addressable] [assigned] [toplevel] direct_functions @@
kernel/trace/ftrace.c:6477:35: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *extern [addressable] [toplevel] ftrace_graph_hash @@ got struct ftrace_hash *[assigned] hash @@
kernel/trace/ftrace.c:6479:43: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *extern [addressable] [toplevel] ftrace_graph_notrace_hash @@ got struct ftrace_hash *[assigned] hash @@
kernel/trace/ftrace.c:6548:35: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash **orig_hash @@ got struct ftrace_hash [noderef] __rcu ** @@
kernel/trace/ftrace.c:6556:35: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash **orig_hash @@ got struct ftrace_hash [noderef] __rcu ** @@
kernel/trace/ftrace.c:6624:47: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *[addressable] [toplevel] ftrace_graph_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:6625:55: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct ftrace_hash [noderef] __rcu *[addressable] [toplevel] ftrace_graph_notrace_hash @@ got struct ftrace_hash * @@
kernel/trace/ftrace.c:7344:46: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:7345:47: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:7349:44: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:7367:18: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_ops *ops @@ got struct ftrace_ops [noderef] __rcu *[addressable] [toplevel] ftrace_ops_list @@
kernel/trace/ftrace.c:7367:66: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_ops *ops @@ got struct ftrace_ops [noderef] __rcu *next @@
kernel/trace/ftrace.c:7419:59: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:7420:59: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:7807:62: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:7808:62: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:7852:36: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/trace/ftrace.c:7852:36: sparse: struct ftrace_ops [noderef] __rcu *
kernel/trace/ftrace.c:7852:36: sparse: struct ftrace_ops *
kernel/trace/ftrace.c:8628:14: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:8628:14: sparse: expected struct ftrace_hash *hash
kernel/trace/ftrace.c:8628:14: sparse: got struct ftrace_hash [noderef] __rcu *filter_hash
kernel/trace/ftrace.c:8677:14: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:8677:14: sparse: expected struct ftrace_hash *hash
kernel/trace/ftrace.c:8677:14: sparse: got struct ftrace_hash [noderef] __rcu *filter_hash
kernel/trace/ftrace.c:231:20: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:231:20: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:231:20: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3434:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3434:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3434:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3434:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3434:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3434:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3468:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3468:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3468:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3468:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3468:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3468:29: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:5974:30: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:5983:21: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:5985:17: sparse: sparse: dereference of noderef expression
kernel/trace/ftrace.c:3739:48: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *filter_hash @@
kernel/trace/ftrace.c:3739:48: sparse: expected struct ftrace_hash *hash
kernel/trace/ftrace.c:3739:48: sparse: got struct ftrace_hash [noderef] __rcu *filter_hash
kernel/trace/ftrace.c:3740:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct ftrace_hash *hash @@ got struct ftrace_hash [noderef] __rcu *notrace_hash @@
kernel/trace/ftrace.c:3740:49: sparse: expected struct ftrace_hash *hash
kernel/trace/ftrace.c:3740:49: sparse: got struct ftrace_hash [noderef] __rcu *notrace_hash
vim +6056 kernel/trace/ftrace.c
6015
6016 /**
6017 * register_ftrace_direct - Call a custom trampoline directly
6018 * for multiple functions registered in @ops
6019 * @ops: The address of the struct ftrace_ops object
6020 * @addr: The address of the trampoline to call at @ops functions
6021 *
6022 * This is used to connect a direct calls to @addr from the nop locations
6023 * of the functions registered in @ops (with by ftrace_set_filter_ip
6024 * function).
6025 *
6026 * The location that it calls (@addr) must be able to handle a direct call,
6027 * and save the parameters of the function being traced, and restore them
6028 * (or inject new ones if needed), before returning.
6029 *
6030 * Returns:
6031 * 0 on success
6032 * -EINVAL - The @ops object was already registered with this call or
6033 * when there are no functions in @ops object.
6034 * -EBUSY - Another direct function is already attached (there can be only one)
6035 * -ENODEV - @ip does not point to a ftrace nop location (or not supported)
6036 * -ENOMEM - There was an allocation failure.
6037 */
6038 int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
6039 {
6040 struct ftrace_hash *hash, *free_hash = NULL;
6041 int err = -EBUSY;
6042
6043 if (ops->func || ops->trampoline)
6044 return -EINVAL;
6045 if (!(ops->flags & FTRACE_OPS_FL_INITIALIZED))
6046 return -EINVAL;
6047 if (ops->flags & FTRACE_OPS_FL_ENABLED)
6048 return -EINVAL;
6049
6050 hash = ops->func_hash->filter_hash;
6051 if (ftrace_hash_empty(hash))
6052 return -EINVAL;
6053
6054 mutex_lock(&direct_mutex);
6055
> 6056 free_hash = direct_functions;
6057 err = ftrace_direct_update(hash, addr);
6058 if (err)
6059 goto out_unlock;
6060
6061 ops->func = call_direct_funcs;
6062 ops->flags = MULTI_FLAGS;
6063 ops->trampoline = FTRACE_REGS_ADDR;
6064 ops->direct_call = addr;
6065
6066 err = register_ftrace_function_nolock(ops);
6067 if (free_hash && free_hash != EMPTY_HASH)
6068 call_rcu_tasks(&free_hash->rcu, register_ftrace_direct_cb);
6069
6070 out_unlock:
6071 mutex_unlock(&direct_mutex);
6072
6073 return err;
6074 }
6075 EXPORT_SYMBOL_GPL(register_ftrace_direct);
6076
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 04/18] ftrace: add reset_ftrace_direct_ips
2025-07-04 1:54 ` Menglong Dong
@ 2025-07-07 18:52 ` Steven Rostedt
2025-07-08 1:26 ` Menglong Dong
0 siblings, 1 reply; 8+ messages in thread
From: Steven Rostedt @ 2025-07-07 18:52 UTC (permalink / raw)
To: Menglong Dong
Cc: alexei.starovoitov, jolsa, bpf, Menglong Dong, Mark Rutland,
Mathieu Desnoyers, linux-kernel, linux-trace-kernel
On Fri, 4 Jul 2025 09:54:52 +0800
Menglong Dong <menglong8.dong@gmail.com> wrote:
> > What exactly do you mean by "reset"?
>
> It means to reset the filter hash of the ftrace_ops to ips. In
> the origin logic, the filter hash of a direct ftrace_ops will not
> be changed. However, in the tracing-multi case, there are
> multi functions in the filter hash and can change. This function
> is used to change the filter hash of a direct ftrace_ops.
The above still doesn't make sense to me.
Can you explain more what exactly you are doing at a higher level? To
me "reset" means to set back to what it originally was (which usually
is zero or nothing).
-- Steve
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 04/18] ftrace: add reset_ftrace_direct_ips
2025-07-07 18:52 ` Steven Rostedt
@ 2025-07-08 1:26 ` Menglong Dong
0 siblings, 0 replies; 8+ messages in thread
From: Menglong Dong @ 2025-07-08 1:26 UTC (permalink / raw)
To: Steven Rostedt
Cc: alexei.starovoitov, jolsa, bpf, Menglong Dong, Mark Rutland,
Mathieu Desnoyers, linux-kernel, linux-trace-kernel
On Tue, Jul 8, 2025 at 2:52 AM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Fri, 4 Jul 2025 09:54:52 +0800
> Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> > > What exactly do you mean by "reset"?
> >
> > It means to reset the filter hash of the ftrace_ops to ips. In
> > the origin logic, the filter hash of a direct ftrace_ops will not
> > be changed. However, in the tracing-multi case, there are
> > multi functions in the filter hash and can change. This function
> > is used to change the filter hash of a direct ftrace_ops.
>
> The above still doesn't make sense to me.
>
> Can you explain more what exactly you are doing at a higher level? To
> me "reset" means to set back to what it originally was (which usually
> is zero or nothing).
Yeah, with pleasure. When we need to update the functions to filter
for a ftrace_ops, we can use ftrace_set_filter_ips(), which is able to
add, remove and reset the functions to filter.
However, we don't have a function to do similar things for a direct
ftrace_ops. What reset_ftrace_direct_ips() do is the same as
ftrace_set_filter_ips() when the "reset" argument of it is 1, and that's
why I call it "reset". Or we can name it something else, such as "update"?
The use case is for the global trampoline. BPF global trampoline has
a direct ftrace_ops. When we attach new tracing-multi progs to the
new kernel functions, we need to add these functions to the ftrace_ops
of the bpf global trampoline.
The "reset_ftrace_direct_ips" can do both adding and removing things
for the direct ftrace_ops. We will get all the functions for the global
trampoline, and "reset" the functions to filter of the ftrace_ops to them.
Hoping I expressed it clearly :/
Thanks!
Menglong Dong
>
> -- Steve
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-07-08 1:27 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20250703121521.1874196-1-dongml2@chinatelecom.cn>
2025-07-03 12:15 ` [PATCH bpf-next v2 03/18] ftrace: factor out ftrace_direct_update from register_ftrace_direct Menglong Dong
2025-07-05 2:41 ` kernel test robot
2025-07-03 12:15 ` [PATCH bpf-next v2 04/18] ftrace: add reset_ftrace_direct_ips Menglong Dong
2025-07-03 15:30 ` Steven Rostedt
2025-07-04 1:54 ` Menglong Dong
2025-07-07 18:52 ` Steven Rostedt
2025-07-08 1:26 ` Menglong Dong
2025-07-03 12:15 ` [PATCH bpf-next v2 07/18] bpf: refactor the modules_array to ptr_array Menglong Dong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).