[PATCH bpf] ftrace: fix incorrect hash size in register_ftrace_direct()

Menglong Dong posted 1 patch 8 months, 1 week ago
There is a newer version of this series
kernel/trace/ftrace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH bpf] ftrace: fix incorrect hash size in register_ftrace_direct()
Posted by Menglong Dong 8 months, 1 week ago
The max ftrace hash bits is made fls(32) in register_ftrace_direct(),
which seems illogical, and it seems to be a spelling mistake.

Just fix it.

(Do I misunderstand something?)

Fixes: d05cb470663a ("ftrace: Fix modification of direct_function hash while in use")
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
 kernel/trace/ftrace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 1a48aedb5255..7697605a41e6 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -5914,7 +5914,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
 
 	/* Make a copy hash to place the new and the old entries in */
 	size = hash->count + direct_functions->count;
-	if (size > 32)
+	if (size < 32)
 		size = 32;
 	new_hash = alloc_ftrace_hash(fls(size));
 	if (!new_hash)
-- 
2.39.5
Re: [PATCH bpf] ftrace: fix incorrect hash size in register_ftrace_direct()
Posted by Steven Rostedt 8 months, 1 week ago
On Sat, 12 Apr 2025 21:33:48 +0800
Menglong Dong <menglong8.dong@gmail.com> wrote:

> The max ftrace hash bits is made fls(32) in register_ftrace_direct(),
> which seems illogical, and it seems to be a spelling mistake.
> 
> Just fix it.
> 
> (Do I misunderstand something?)

I think the logic is incorrect and this patch doesn't fix it.

> 
> Fixes: d05cb470663a ("ftrace: Fix modification of direct_function hash while in use")
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> ---
>  kernel/trace/ftrace.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index 1a48aedb5255..7697605a41e6 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -5914,7 +5914,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
>  
>  	/* Make a copy hash to place the new and the old entries in */
>  	size = hash->count + direct_functions->count;
> -	if (size > 32)
> +	if (size < 32)
>  		size = 32;
>  	new_hash = alloc_ftrace_hash(fls(size));
>  	if (!new_hash)

The above probably should be:

	size = hash->count + direct_functions->count
	size = fls(size);
	if (size > FTRACE_HASH_MAX_BITS)
                size = FTRACE_HASH_MAX_BITS;
	new_hash = alloc_ftrace_hash(size);

-- Steve
Re: [PATCH bpf] ftrace: fix incorrect hash size in register_ftrace_direct()
Posted by Menglong Dong 8 months, 1 week ago
On Sat, Apr 12, 2025 at 10:09 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Sat, 12 Apr 2025 21:33:48 +0800
> Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> > The max ftrace hash bits is made fls(32) in register_ftrace_direct(),
> > which seems illogical, and it seems to be a spelling mistake.
> >
> > Just fix it.
> >
> > (Do I misunderstand something?)
>
> I think the logic is incorrect and this patch doesn't fix it.
>
> >
> > Fixes: d05cb470663a ("ftrace: Fix modification of direct_function hash while in use")
> > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > ---
> >  kernel/trace/ftrace.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> > index 1a48aedb5255..7697605a41e6 100644
> > --- a/kernel/trace/ftrace.c
> > +++ b/kernel/trace/ftrace.c
> > @@ -5914,7 +5914,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
> >
> >       /* Make a copy hash to place the new and the old entries in */
> >       size = hash->count + direct_functions->count;
> > -     if (size > 32)
> > +     if (size < 32)
> >               size = 32;
> >       new_hash = alloc_ftrace_hash(fls(size));
> >       if (!new_hash)
>
> The above probably should be:
>
>         size = hash->count + direct_functions->count
>         size = fls(size);
>         if (size > FTRACE_HASH_MAX_BITS)
>                 size = FTRACE_HASH_MAX_BITS;
>         new_hash = alloc_ftrace_hash(size);

Yeah, this seems to make more sense. And I'll send a V2
later.

BTW, Should we still keep the "size = min(size, 32)" logic
to avoid the hash bits being too small, just like the origin
logic in "dup_hash"?

Thanks!
Menglong Dong

>
> -- Steve
>
>
Re: [PATCH bpf] ftrace: fix incorrect hash size in register_ftrace_direct()
Posted by Menglong Dong 8 months, 1 week ago
On Sat, Apr 12, 2025 at 10:32 PM Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> On Sat, Apr 12, 2025 at 10:09 PM Steven Rostedt <rostedt@goodmis.org> wrote:
> >
> > On Sat, 12 Apr 2025 21:33:48 +0800
> > Menglong Dong <menglong8.dong@gmail.com> wrote:
> >
> > > The max ftrace hash bits is made fls(32) in register_ftrace_direct(),
> > > which seems illogical, and it seems to be a spelling mistake.
> > >
> > > Just fix it.
> > >
> > > (Do I misunderstand something?)
> >
> > I think the logic is incorrect and this patch doesn't fix it.
> >
> > >
> > > Fixes: d05cb470663a ("ftrace: Fix modification of direct_function hash while in use")
> > > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > > ---
> > >  kernel/trace/ftrace.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> > > index 1a48aedb5255..7697605a41e6 100644
> > > --- a/kernel/trace/ftrace.c
> > > +++ b/kernel/trace/ftrace.c
> > > @@ -5914,7 +5914,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
> > >
> > >       /* Make a copy hash to place the new and the old entries in */
> > >       size = hash->count + direct_functions->count;
> > > -     if (size > 32)
> > > +     if (size < 32)
> > >               size = 32;
> > >       new_hash = alloc_ftrace_hash(fls(size));
> > >       if (!new_hash)
> >
> > The above probably should be:
> >
> >         size = hash->count + direct_functions->count
> >         size = fls(size);
> >         if (size > FTRACE_HASH_MAX_BITS)
> >                 size = FTRACE_HASH_MAX_BITS;
> >         new_hash = alloc_ftrace_hash(size);
>
> Yeah, this seems to make more sense. And I'll send a V2
> later.
>
> BTW, Should we still keep the "size = min(size, 32)" logic

Oops, I mean "size =  max(size, 32); size = fls(size);" here :/

> to avoid the hash bits being too small, just like the origin
> logic in "dup_hash"?
>
> Thanks!
> Menglong Dong
>
> >
> > -- Steve
> >
> >
Re: [PATCH bpf] ftrace: fix incorrect hash size in register_ftrace_direct()
Posted by Steven Rostedt 8 months, 1 week ago
On Sat, 12 Apr 2025 22:36:56 +0800
Menglong Dong <menglong8.dong@gmail.com> wrote:

> > Yeah, this seems to make more sense. And I'll send a V2
> > later.
> >
> > BTW, Should we still keep the "size = min(size, 32)" logic  
> 
> Oops, I mean "size =  max(size, 32); size = fls(size);" here :/
> 
> > to avoid the hash bits being too small, just like the origin
> > logic in "dup_hash"?
> >

If you have 5 functions, why do you need more that 5 buckets?

	size = 5;
	size = max(5, 32); // size = 32
	size = fls(size); // size = 5
	alloc_ftrace_hash(size);

		size = 1 << size; // size = 32
		hash->buckets = kcalloc(size, ...);

Now you have 32 buckets for 5 functions. Why waste the memory?

If you add more functions, the hash bucket size will get updated.

-- Steve
Re: [PATCH bpf] ftrace: fix incorrect hash size in register_ftrace_direct()
Posted by Menglong Dong 8 months, 1 week ago
On Sat, Apr 12, 2025 at 10:45 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Sat, 12 Apr 2025 22:36:56 +0800
> Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> > > Yeah, this seems to make more sense. And I'll send a V2
> > > later.
> > >
> > > BTW, Should we still keep the "size = min(size, 32)" logic
> >
> > Oops, I mean "size =  max(size, 32); size = fls(size);" here :/
> >
> > > to avoid the hash bits being too small, just like the origin
> > > logic in "dup_hash"?
> > >
>
> If you have 5 functions, why do you need more that 5 buckets?
>
>         size = 5;
>         size = max(5, 32); // size = 32
>         size = fls(size); // size = 5
>         alloc_ftrace_hash(size);
>
>                 size = 1 << size; // size = 32
>                 hash->buckets = kcalloc(size, ...);
>
> Now you have 32 buckets for 5 functions. Why waste the memory?
>
> If you add more functions, the hash bucket size will get updated.

Yeah, I see. The hash bucket will be reallocated when we
add more functions to the direct_funtions, so it is not
necessary to make the budget size large here.

Thanks!
Menglong Dong

>
> -- Steve