From: Jiri Olsa <olsajiri@gmail.com>
To: bot+bpf-ci@kernel.org
Cc: rostedt@kernel.org, revest@google.com, mark.rutland@arm.com,
bpf@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-trace-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, ast@kernel.org,
daniel@iogearbox.net, andrii@kernel.org,
menglong8.dong@gmail.com, song@kernel.org, martin.lau@kernel.org,
eddyz87@gmail.com, yonghong.song@linux.dev, clm@meta.com,
ihor.solodrai@linux.dev
Subject: Re: [PATCHv4 bpf-next 4/9] ftrace: Add update_ftrace_direct_add function
Date: Wed, 3 Dec 2025 21:25:12 +0100 [thread overview]
Message-ID: <aTCcqGiWnEmGGuRI@krava> (raw)
In-Reply-To: <d0d8e0d78f614eb8b443772b50fb36093d48c7f43374316246ad3ad836b5c9ce@mail.kernel.org>
On Wed, Dec 03, 2025 at 08:47:45AM +0000, bot+bpf-ci@kernel.org wrote:
> > diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
> > index 8c034b028..eb60d971e 100644
> > --- a/include/linux/ftrace.h
> > +++ b/include/linux/ftrace.h
>
> [ ... ]
>
> > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> > index 84aee9096..1660a8754 100644
> > --- a/kernel/trace/ftrace.c
> > +++ b/kernel/trace/ftrace.c
>
> [ ... ]
>
> > +int update_ftrace_direct_add(struct ftrace_ops *ops, struct ftrace_hash *hash)
> > +{
> > + struct ftrace_hash *old_direct_functions = NULL, *new_direct_functions = NULL;
> > + struct ftrace_hash *old_filter_hash = NULL, *new_filter_hash = NULL;
> > + struct ftrace_func_entry *entry;
> > + int i, size, err = -EINVAL;
> > + bool reg;
> > +
> > + if (!hash_count(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_lookup_ip(direct_functions, entry->ip))
> > + goto out_unlock;
> > + }
> > + }
> > +
> > + old_filter_hash = ops->func_hash ? ops->func_hash->filter_hash : NULL;
> > + old_direct_functions = direct_functions;
> > +
> > + /* If there's nothing in filter_hash we need to register the ops. */
> > + reg = hash_count(old_filter_hash) == 0;
> > + if (reg) {
> > + if (ops->func || ops->trampoline)
> > + goto out_unlock;
> > + if (ops->flags & FTRACE_OPS_FL_ENABLED)
> > + goto out_unlock;
> > + }
> > +
> > + err = -ENOMEM;
> > + new_filter_hash = hash_add(old_filter_hash, hash);
> > + if (!new_filter_hash)
> > + goto out_unlock;
> > +
> > + new_direct_functions = hash_add(old_direct_functions, hash);
> > + if (!new_direct_functions)
> > + goto out_unlock;
>
> Can new_filter_hash leak here? If the second hash_add() fails but the
> first one succeeds, update_ftrace_direct_add() will goto out_unlock
> with new_filter_hash pointing to allocated memory. At out_unlock, only
> old_filter_hash gets freed, not new_filter_hash.
mamma mia, can't get this right apparently.. yea, will fix in next
version, thanks
jirka
>
> register_ftrace_direct() handles this by freeing new_hash on error:
>
> 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);
>
> return err;
>
> > +
> > + rcu_assign_pointer(direct_functions, new_direct_functions);
> > +
> > + if (reg) {
> > + ops->func = call_direct_funcs;
> > + ops->flags |= MULTI_FLAGS;
> > + ops->trampoline = FTRACE_REGS_ADDR;
> > + ops->local_hash.filter_hash = new_filter_hash;
> > +
> > + err = register_ftrace_function_nolock(ops);
> > + if (err) {
> > + /* restore old filter on error */
> > + ops->local_hash.filter_hash = old_filter_hash;
> > + old_filter_hash = new_filter_hash;
> > +
> > + /* cleanup for possible another register call */
> > + ops->func = NULL;
> > + ops->trampoline = 0;
> > + }
> > + } else {
> > + err = ftrace_update_ops(ops, new_filter_hash, EMPTY_HASH);
> > + /*
> > + * new_filter_hash is dup-ed, so we need to release it anyway,
> > + * old_filter_hash either stays on error or is released already
> > + */
> > + old_filter_hash = new_filter_hash;
> > + }
> > +
> > + if (err) {
> > + /* reset direct_functions and free the new one */
> > + rcu_assign_pointer(direct_functions, old_direct_functions);
> > + old_direct_functions = new_direct_functions;
> > + }
> > +
> > + out_unlock:
> > + mutex_unlock(&direct_mutex);
> > +
> > + if (old_direct_functions && old_direct_functions != EMPTY_HASH)
> > + call_rcu_tasks(&old_direct_functions->rcu, register_ftrace_direct_cb);
> > + if (old_filter_hash)
> > + free_ftrace_hash(old_filter_hash);
> > +
> > + return err;
> > +}
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/19887401362
next prev parent reply other threads:[~2025-12-03 20:25 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-03 8:23 [PATCHv4 bpf-next 0/9] ftrace,bpf: Use single direct ops for bpf trampolines Jiri Olsa
2025-12-03 8:23 ` [PATCHv4 bpf-next 1/9] ftrace,bpf: Remove FTRACE_OPS_FL_JMP ftrace_ops flag Jiri Olsa
2025-12-03 9:15 ` Menglong Dong
2025-12-03 20:23 ` Jiri Olsa
2025-12-03 8:23 ` [PATCHv4 bpf-next 2/9] ftrace: Make alloc_and_copy_ftrace_hash direct friendly Jiri Olsa
2025-12-03 8:23 ` [PATCHv4 bpf-next 3/9] ftrace: Export some of hash related functions Jiri Olsa
2025-12-03 8:23 ` [PATCHv4 bpf-next 4/9] ftrace: Add update_ftrace_direct_add function Jiri Olsa
2025-12-03 8:47 ` bot+bpf-ci
2025-12-03 20:25 ` Jiri Olsa [this message]
2025-12-03 8:23 ` [PATCHv4 bpf-next 5/9] ftrace: Add update_ftrace_direct_del function Jiri Olsa
2025-12-03 8:23 ` [PATCHv4 bpf-next 6/9] ftrace: Add update_ftrace_direct_mod function Jiri Olsa
2025-12-03 8:24 ` [PATCHv4 bpf-next 7/9] bpf: Add trampoline ip hash table Jiri Olsa
2025-12-03 8:24 ` [PATCHv4 bpf-next 8/9] ftrace: Factor ftrace_ops ops_func interface Jiri Olsa
2025-12-03 8:24 ` [PATCHv4 bpf-next 9/9] bpf,x86: Use single ftrace_ops for direct calls Jiri Olsa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aTCcqGiWnEmGGuRI@krava \
--to=olsajiri@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bot+bpf-ci@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=clm@meta.com \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=ihor.solodrai@linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=martin.lau@kernel.org \
--cc=menglong8.dong@gmail.com \
--cc=revest@google.com \
--cc=rostedt@kernel.org \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.