diff mbox series

[bpf] bpf: Use kmalloc_size_roundup() to adjust size_index

Message ID 20230928101558.2594068-1-houtao@huaweicloud.com (mailing list archive)
State Accepted
Commit 9077fc228f09c9f975c498c55f5d2e882cd0da59
Delegated to: BPF
Headers show
Series [bpf] bpf: Use kmalloc_size_roundup() to adjust size_index | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for bpf
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1345 this patch: 1345
netdev/cc_maintainers warning 4 maintainers not CCed: linux-riscv@lists.infradead.org paul.walmsley@sifive.com aou@eecs.berkeley.edu palmer@dabbelt.com
netdev/build_clang success Errors and warnings before: 1364 this patch: 1364
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: 1368 this patch: 1368
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 56 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-PR success PR summary
bpf/vmtest-bpf-VM_Test-0 success Logs for ShellCheck
bpf/vmtest-bpf-VM_Test-5 success Logs for set-matrix
bpf/vmtest-bpf-VM_Test-1 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-VM_Test-3 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-VM_Test-4 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-VM_Test-2 success Logs for build for s390x with gcc
bpf/vmtest-bpf-VM_Test-6 success Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-9 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-VM_Test-8 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-12 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-17 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-VM_Test-19 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-13 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-VM_Test-16 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-20 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-VM_Test-18 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-21 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-22 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-23 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-VM_Test-24 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-28 success Logs for veristat
bpf/vmtest-bpf-VM_Test-26 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-27 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-VM_Test-10 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-14 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-25 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-VM_Test-15 success Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-VM_Test-11 success Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-VM_Test-7 success Logs for test_maps on s390x with gcc

Commit Message

Hou Tao Sept. 28, 2023, 10:15 a.m. UTC
From: Hou Tao <houtao1@huawei.com>

Commit d52b59315bf5 ("bpf: Adjust size_index according to the value of
KMALLOC_MIN_SIZE") uses KMALLOC_MIN_SIZE to adjust size_index, but as
reported by Nathan, the adjustment is not enough, because
__kmalloc_minalign() also decides the minimal alignment of slab object
as shown in new_kmalloc_cache() and its value may be greater than
KMALLOC_MIN_SIZE (e.g., 64 bytes vs 8 bytes under a riscv QEMU VM).

Instead of invoking __kmalloc_minalign() in bpf subsystem to find the
maximal alignment, just using kmalloc_size_roundup() directly to get the
corresponding slab object size for each allocation size. If these two
sizes are unmatched, adjust size_index to select a bpf_mem_cache with
unit_size equal to the object_size of the underlying slab cache for the
allocation size.

Fixes: 822fb26bdb55 ("bpf: Add a hint to allocated objects.")
Reported-by: Nathan Chancellor <nathan@kernel.org>
Closes: https://lore.kernel.org/bpf/20230914181407.GA1000274@dev-arch.thelio-3990X/
Signed-off-by: Hou Tao <houtao1@huawei.com>
---
 kernel/bpf/memalloc.c | 44 +++++++++++++++++++------------------------
 1 file changed, 19 insertions(+), 25 deletions(-)

Comments

Emil Renner Berthing Sept. 29, 2023, 9:30 p.m. UTC | #1
Hou Tao wrote:
> From: Hou Tao <houtao1@huawei.com>
>
> Commit d52b59315bf5 ("bpf: Adjust size_index according to the value of
> KMALLOC_MIN_SIZE") uses KMALLOC_MIN_SIZE to adjust size_index, but as
> reported by Nathan, the adjustment is not enough, because
> __kmalloc_minalign() also decides the minimal alignment of slab object
> as shown in new_kmalloc_cache() and its value may be greater than
> KMALLOC_MIN_SIZE (e.g., 64 bytes vs 8 bytes under a riscv QEMU VM).
>
> Instead of invoking __kmalloc_minalign() in bpf subsystem to find the
> maximal alignment, just using kmalloc_size_roundup() directly to get the
> corresponding slab object size for each allocation size. If these two
> sizes are unmatched, adjust size_index to select a bpf_mem_cache with
> unit_size equal to the object_size of the underlying slab cache for the
> allocation size.

I applied this to 6.6-rc3 and it fixes the warning on my Nezha board (Allwinner
D1) and also boots fine on my VisionFive 2 (JH7110) which didn't show the error
before. I didn't do any other testing beyond that though, but for basic boot
testing:

Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>

> Fixes: 822fb26bdb55 ("bpf: Add a hint to allocated objects.")
> Reported-by: Nathan Chancellor <nathan@kernel.org>
> Closes: https://lore.kernel.org/bpf/20230914181407.GA1000274@dev-arch.thelio-3990X/
> Signed-off-by: Hou Tao <houtao1@huawei.com>
> ---
>  kernel/bpf/memalloc.c | 44 +++++++++++++++++++------------------------
>  1 file changed, 19 insertions(+), 25 deletions(-)
>
> diff --git a/kernel/bpf/memalloc.c b/kernel/bpf/memalloc.c
> index 1c22b90e754a..06fbb5168482 100644
> --- a/kernel/bpf/memalloc.c
> +++ b/kernel/bpf/memalloc.c
> @@ -958,37 +958,31 @@ void notrace *bpf_mem_cache_alloc_flags(struct bpf_mem_alloc *ma, gfp_t flags)
>  	return !ret ? NULL : ret + LLIST_NODE_SZ;
>  }
>
> -/* Most of the logic is taken from setup_kmalloc_cache_index_table() */
>  static __init int bpf_mem_cache_adjust_size(void)
>  {
> -	unsigned int size, index;
> +	unsigned int size;
>
> -	/* Normally KMALLOC_MIN_SIZE is 8-bytes, but it can be
> -	 * up-to 256-bytes.
> +	/* Adjusting the indexes in size_index() according to the object_size
> +	 * of underlying slab cache, so bpf_mem_alloc() will select a
> +	 * bpf_mem_cache with unit_size equal to the object_size of
> +	 * the underlying slab cache.
> +	 *
> +	 * The maximal value of KMALLOC_MIN_SIZE and __kmalloc_minalign() is
> +	 * 256-bytes, so only do adjustment for [8-bytes, 192-bytes].
>  	 */
> -	size = KMALLOC_MIN_SIZE;
> -	if (size <= 192)
> -		index = size_index[(size - 1) / 8];
> -	else
> -		index = fls(size - 1) - 1;
> -	for (size = 8; size < KMALLOC_MIN_SIZE && size <= 192; size += 8)
> -		size_index[(size - 1) / 8] = index;
> +	for (size = 192; size >= 8; size -= 8) {
> +		unsigned int kmalloc_size, index;
>
> -	/* The minimal alignment is 64-bytes, so disable 96-bytes cache and
> -	 * use 128-bytes cache instead.
> -	 */
> -	if (KMALLOC_MIN_SIZE >= 64) {
> -		index = size_index[(128 - 1) / 8];
> -		for (size = 64 + 8; size <= 96; size += 8)
> -			size_index[(size - 1) / 8] = index;
> -	}
> +		kmalloc_size = kmalloc_size_roundup(size);
> +		if (kmalloc_size == size)
> +			continue;
>
> -	/* The minimal alignment is 128-bytes, so disable 192-bytes cache and
> -	 * use 256-bytes cache instead.
> -	 */
> -	if (KMALLOC_MIN_SIZE >= 128) {
> -		index = fls(256 - 1) - 1;
> -		for (size = 128 + 8; size <= 192; size += 8)
> +		if (kmalloc_size <= 192)
> +			index = size_index[(kmalloc_size - 1) / 8];
> +		else
> +			index = fls(kmalloc_size - 1) - 1;
> +		/* Only overwrite if necessary */
> +		if (size_index[(size - 1) / 8] != index)
>  			size_index[(size - 1) / 8] = index;
>  	}
>
patchwork-bot+netdevbpf@kernel.org Sept. 30, 2023, 4:50 p.m. UTC | #2
Hello:

This patch was applied to bpf/bpf.git (master)
by Alexei Starovoitov <ast@kernel.org>:

On Thu, 28 Sep 2023 18:15:58 +0800 you wrote:
> From: Hou Tao <houtao1@huawei.com>
> 
> Commit d52b59315bf5 ("bpf: Adjust size_index according to the value of
> KMALLOC_MIN_SIZE") uses KMALLOC_MIN_SIZE to adjust size_index, but as
> reported by Nathan, the adjustment is not enough, because
> __kmalloc_minalign() also decides the minimal alignment of slab object
> as shown in new_kmalloc_cache() and its value may be greater than
> KMALLOC_MIN_SIZE (e.g., 64 bytes vs 8 bytes under a riscv QEMU VM).
> 
> [...]

Here is the summary with links:
  - [bpf] bpf: Use kmalloc_size_roundup() to adjust size_index
    https://git.kernel.org/bpf/bpf/c/9077fc228f09

You are awesome, thank you!
diff mbox series

Patch

diff --git a/kernel/bpf/memalloc.c b/kernel/bpf/memalloc.c
index 1c22b90e754a..06fbb5168482 100644
--- a/kernel/bpf/memalloc.c
+++ b/kernel/bpf/memalloc.c
@@ -958,37 +958,31 @@  void notrace *bpf_mem_cache_alloc_flags(struct bpf_mem_alloc *ma, gfp_t flags)
 	return !ret ? NULL : ret + LLIST_NODE_SZ;
 }
 
-/* Most of the logic is taken from setup_kmalloc_cache_index_table() */
 static __init int bpf_mem_cache_adjust_size(void)
 {
-	unsigned int size, index;
+	unsigned int size;
 
-	/* Normally KMALLOC_MIN_SIZE is 8-bytes, but it can be
-	 * up-to 256-bytes.
+	/* Adjusting the indexes in size_index() according to the object_size
+	 * of underlying slab cache, so bpf_mem_alloc() will select a
+	 * bpf_mem_cache with unit_size equal to the object_size of
+	 * the underlying slab cache.
+	 *
+	 * The maximal value of KMALLOC_MIN_SIZE and __kmalloc_minalign() is
+	 * 256-bytes, so only do adjustment for [8-bytes, 192-bytes].
 	 */
-	size = KMALLOC_MIN_SIZE;
-	if (size <= 192)
-		index = size_index[(size - 1) / 8];
-	else
-		index = fls(size - 1) - 1;
-	for (size = 8; size < KMALLOC_MIN_SIZE && size <= 192; size += 8)
-		size_index[(size - 1) / 8] = index;
+	for (size = 192; size >= 8; size -= 8) {
+		unsigned int kmalloc_size, index;
 
-	/* The minimal alignment is 64-bytes, so disable 96-bytes cache and
-	 * use 128-bytes cache instead.
-	 */
-	if (KMALLOC_MIN_SIZE >= 64) {
-		index = size_index[(128 - 1) / 8];
-		for (size = 64 + 8; size <= 96; size += 8)
-			size_index[(size - 1) / 8] = index;
-	}
+		kmalloc_size = kmalloc_size_roundup(size);
+		if (kmalloc_size == size)
+			continue;
 
-	/* The minimal alignment is 128-bytes, so disable 192-bytes cache and
-	 * use 256-bytes cache instead.
-	 */
-	if (KMALLOC_MIN_SIZE >= 128) {
-		index = fls(256 - 1) - 1;
-		for (size = 128 + 8; size <= 192; size += 8)
+		if (kmalloc_size <= 192)
+			index = size_index[(kmalloc_size - 1) / 8];
+		else
+			index = fls(kmalloc_size - 1) - 1;
+		/* Only overwrite if necessary */
+		if (size_index[(size - 1) / 8] != index)
 			size_index[(size - 1) / 8] = index;
 	}