diff mbox series

[net-next,v1] neighbour: Replace kvzalloc() with kzalloc() when GFP_ATOMIC is specified

Message ID 20250216163016.57444-1-enjuk@amazon.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series [net-next,v1] neighbour: Replace kvzalloc() with kzalloc() when GFP_ATOMIC is specified | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/build_clang success Errors and warnings before: 1 this patch: 1
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 2 this patch: 2
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 16 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2025-02-16--18-00 (tests: 891)

Commit Message

Kohei Enju Feb. 16, 2025, 4:30 p.m. UTC
Replace kvzalloc()/kvfree() with kzalloc()/kfree() when GFP_ATOMIC is
specified, since kvzalloc() doesn't support non-sleeping allocations such
as GFP_ATOMIC.

With incompatible gfp flags, kvzalloc() never falls back to the vmalloc
path and returns immediately after the kmalloc path fails.
Therefore, using kzalloc() is sufficient in this case.

Fixes: 41b3caa7c076 ("neighbour: Add hlist_node to struct neighbour")
Signed-off-by: Kohei Enju <enjuk@amazon.com>
---
 net/core/neighbour.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Kuniyuki Iwashima Feb. 16, 2025, 7:06 p.m. UTC | #1
From: Kohei Enju <enjuk@amazon.com>
Date: Mon, 17 Feb 2025 01:30:16 +0900
> Replace kvzalloc()/kvfree() with kzalloc()/kfree() when GFP_ATOMIC is
> specified, since kvzalloc() doesn't support non-sleeping allocations such
> as GFP_ATOMIC.
> 
> With incompatible gfp flags, kvzalloc() never falls back to the vmalloc
> path and returns immediately after the kmalloc path fails.
> Therefore, using kzalloc() is sufficient in this case.
> 
> Fixes: 41b3caa7c076 ("neighbour: Add hlist_node to struct neighbour")

This commit followed the old hash_buckets allocation, so I'd add

  Fixes: ab101c553bc1 ("neighbour: use kvzalloc()/kvfree()")

too.

Both commits were introduced in v6.13, so there's no difference in terms
of backporting though.

Also, it would be nice to CC mm maintainers in case they have some
comments.


> Signed-off-by: Kohei Enju <enjuk@amazon.com>
> ---
>  net/core/neighbour.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index d8dd686b5287..344c9cd168ec 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -518,7 +518,7 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift)
>  	if (!ret)
>  		return NULL;
>  
> -	hash_heads = kvzalloc(size, GFP_ATOMIC);
> +	hash_heads = kzalloc(size, GFP_ATOMIC);
>  	if (!hash_heads) {
>  		kfree(ret);
>  		return NULL;
> @@ -536,7 +536,7 @@ static void neigh_hash_free_rcu(struct rcu_head *head)
>  						    struct neigh_hash_table,
>  						    rcu);
>  
> -	kvfree(nht->hash_heads);
> +	kfree(nht->hash_heads);
>  	kfree(nht);
>  }
>  
> -- 
> 2.39.5 (Apple Git-154)
Eric Dumazet Feb. 17, 2025, 8:56 a.m. UTC | #2
On Sun, Feb 16, 2025 at 8:07 PM Kuniyuki Iwashima <kuniyu@amazon.com> wrote:
>
> From: Kohei Enju <enjuk@amazon.com>
> Date: Mon, 17 Feb 2025 01:30:16 +0900
> > Replace kvzalloc()/kvfree() with kzalloc()/kfree() when GFP_ATOMIC is
> > specified, since kvzalloc() doesn't support non-sleeping allocations such
> > as GFP_ATOMIC.
> >
> > With incompatible gfp flags, kvzalloc() never falls back to the vmalloc
> > path and returns immediately after the kmalloc path fails.
> > Therefore, using kzalloc() is sufficient in this case.
> >
> > Fixes: 41b3caa7c076 ("neighbour: Add hlist_node to struct neighbour")
>
> This commit followed the old hash_buckets allocation, so I'd add
>
>   Fixes: ab101c553bc1 ("neighbour: use kvzalloc()/kvfree()")
>
> too.
>
> Both commits were introduced in v6.13, so there's no difference in terms
> of backporting though.
>
> Also, it would be nice to CC mm maintainers in case they have some
> comments.

Oh well, we need to trigger neigh_hash_grow() from a process context,
or convert net/core/neighbour.c to modern rhashtable.
Kohei Enju Feb. 17, 2025, 4:52 p.m. UTC | #3
+ SLAB ALLOCATOR maintainers and reviewers

> > From: Kohei Enju <enjuk@amazon.com>
> > Date: Mon, 17 Feb 2025 01:30:16 +0900
> > > Replace kvzalloc()/kvfree() with kzalloc()/kfree() when GFP_ATOMIC is
> > > specified, since kvzalloc() doesn't support non-sleeping allocations such
> > > as GFP_ATOMIC.
> > >
> > > With incompatible gfp flags, kvzalloc() never falls back to the vmalloc
> > > path and returns immediately after the kmalloc path fails.
> > > Therefore, using kzalloc() is sufficient in this case.
> > >
> > > Fixes: 41b3caa7c076 ("neighbour: Add hlist_node to struct neighbour")
> >
> > This commit followed the old hash_buckets allocation, so I'd add
> >
> >   Fixes: ab101c553bc1 ("neighbour: use kvzalloc()/kvfree()")
> >
> > too.
> >
> > Both commits were introduced in v6.13, so there's no difference in terms
> > of backporting though.
> >
> > Also, it would be nice to CC mm maintainers in case they have some
> > comments.
> 
> Oh well, we need to trigger neigh_hash_grow() from a process context,
> or convert net/core/neighbour.c to modern rhashtable.

Hi all, thanks for your comments.

kzalloc() uses page allocator when size is larger than 
KMALLOC_MAX_CACHE_SIZE, so I think what commit ab101c553bc1 ("neighbour: 
use kvzalloc()/kvfree()") intended could be achieved by using kzalloc().

As mentioned, when using GFP_ATOMIC, kvzalloc() only tries the kmalloc 
path, since the vmalloc path doesn't support the flag.
In this case, kvzalloc() is equivalent to kzalloc() in that neither try 
the vmalloc path, so there is no functional change between this patch and 
either commit ab101c553bc1 ("neighbour: use kvzalloc()/kvfree()") or 
commit 41b3caa7c076 ("neighbour: Add hlist_node to struct neighbour").

Actually there's no real bug in the current code so the Fixes tag was not 
appropriate. I shall remove the tag.

Regards,
Kohei
Vlastimil Babka Feb. 17, 2025, 6:43 p.m. UTC | #4
On 2/17/25 17:52, Kohei Enju wrote:
> + SLAB ALLOCATOR maintainers and reviewers
> 
>> > From: Kohei Enju <enjuk@amazon.com>
>> > Date: Mon, 17 Feb 2025 01:30:16 +0900
>> > > Replace kvzalloc()/kvfree() with kzalloc()/kfree() when GFP_ATOMIC is
>> > > specified, since kvzalloc() doesn't support non-sleeping allocations such
>> > > as GFP_ATOMIC.
>> > >
>> > > With incompatible gfp flags, kvzalloc() never falls back to the vmalloc
>> > > path and returns immediately after the kmalloc path fails.
>> > > Therefore, using kzalloc() is sufficient in this case.
>> > >
>> > > Fixes: 41b3caa7c076 ("neighbour: Add hlist_node to struct neighbour")
>> >
>> > This commit followed the old hash_buckets allocation, so I'd add
>> >
>> >   Fixes: ab101c553bc1 ("neighbour: use kvzalloc()/kvfree()")
>> >
>> > too.
>> >
>> > Both commits were introduced in v6.13, so there's no difference in terms
>> > of backporting though.
>> >
>> > Also, it would be nice to CC mm maintainers in case they have some
>> > comments.
>> 
>> Oh well, we need to trigger neigh_hash_grow() from a process context,
>> or convert net/core/neighbour.c to modern rhashtable.
> 
> Hi all, thanks for your comments.
> 
> kzalloc() uses page allocator when size is larger than 
> KMALLOC_MAX_CACHE_SIZE, so I think what commit ab101c553bc1 ("neighbour: 
> use kvzalloc()/kvfree()") intended could be achieved by using kzalloc().

Indeed, kzalloc() should be equivalent to pre-ab101c553bc1 code. kvmalloc()
would only be necessary if you need more than order-3 page worth of memory
and don't want it to fail because of fragmentation (but indeed it's not
supported in GFP_ATOMIC context). But since you didn't need such large
allocations before, you probably don't need them now too?

> As mentioned, when using GFP_ATOMIC, kvzalloc() only tries the kmalloc 
> path, since the vmalloc path doesn't support the flag.
> In this case, kvzalloc() is equivalent to kzalloc() in that neither try 
> the vmalloc path, so there is no functional change between this patch and 
> either commit ab101c553bc1 ("neighbour: use kvzalloc()/kvfree()") or 

Agreed.

> commit 41b3caa7c076 ("neighbour: Add hlist_node to struct neighbour").
> 
> Actually there's no real bug in the current code so the Fixes tag was not 
> appropriate. I shall remove the tag.

True, the code is just more clear.

Thanks,
Vlastimil

> Regards,
> Kohei
Kohei Enju Feb. 18, 2025, 4:22 a.m. UTC | #5
>>> > From: Kohei Enju <enjuk@amazon.com>
>>> > Date: Mon, 17 Feb 2025 01:30:16 +0900
>>> > > Replace kvzalloc()/kvfree() with kzalloc()/kfree() when GFP_ATOMIC is
>>> > > specified, since kvzalloc() doesn't support non-sleeping allocations such
>>> > > as GFP_ATOMIC.
>>> > >
>>> > > With incompatible gfp flags, kvzalloc() never falls back to the vmalloc
>>> > > path and returns immediately after the kmalloc path fails.
>>> > > Therefore, using kzalloc() is sufficient in this case.
>>> > >
>>> > > Fixes: 41b3caa7c076 ("neighbour: Add hlist_node to struct neighbour")
>>> >
>>> > This commit followed the old hash_buckets allocation, so I'd add
>>> >
>>> >   Fixes: ab101c553bc1 ("neighbour: use kvzalloc()/kvfree()")
>>> >
>>> > too.
>>> >
>>> > Both commits were introduced in v6.13, so there's no difference in terms
>>> > of backporting though.
>>> >
>>> > Also, it would be nice to CC mm maintainers in case they have some
>>> > comments.
>>> 
>>> Oh well, we need to trigger neigh_hash_grow() from a process context,
>>> or convert net/core/neighbour.c to modern rhashtable.
>> 
>> Hi all, thanks for your comments.
>> 
>> kzalloc() uses page allocator when size is larger than 
>> KMALLOC_MAX_CACHE_SIZE, so I think what commit ab101c553bc1 ("neighbour: 
>> use kvzalloc()/kvfree()") intended could be achieved by using kzalloc().
>
>Indeed, kzalloc() should be equivalent to pre-ab101c553bc1 code. kvmalloc()
>would only be necessary if you need more than order-3 page worth of memory
>and don't want it to fail because of fragmentation (but indeed it's not
>supported in GFP_ATOMIC context). But since you didn't need such large
>allocations before, you probably don't need them now too?

Yes, from pre-ab101c553bc1 code, it looks like we don't need the vmalloc 
path for large allocations now too.

>> As mentioned, when using GFP_ATOMIC, kvzalloc() only tries the kmalloc 
>> path, since the vmalloc path doesn't support the flag.
>> In this case, kvzalloc() is equivalent to kzalloc() in that neither try 
>> the vmalloc path, so there is no functional change between this patch and 
>> either commit ab101c553bc1 ("neighbour: use kvzalloc()/kvfree()") or 
>
>Agreed.
>
>> commit 41b3caa7c076 ("neighbour: Add hlist_node to struct neighbour").
>> 
>> Actually there's no real bug in the current code so the Fixes tag was not 
>> appropriate. I shall remove the tag.
>
>True, the code is just more clear.

Thank you for looking at the patches and providing your comments.

I'll send out v2 with the revised commit message, removing the Fixes tag.

Regards,
Kohei
diff mbox series

Patch

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index d8dd686b5287..344c9cd168ec 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -518,7 +518,7 @@  static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift)
 	if (!ret)
 		return NULL;
 
-	hash_heads = kvzalloc(size, GFP_ATOMIC);
+	hash_heads = kzalloc(size, GFP_ATOMIC);
 	if (!hash_heads) {
 		kfree(ret);
 		return NULL;
@@ -536,7 +536,7 @@  static void neigh_hash_free_rcu(struct rcu_head *head)
 						    struct neigh_hash_table,
 						    rcu);
 
-	kvfree(nht->hash_heads);
+	kfree(nht->hash_heads);
 	kfree(nht);
 }