btrfs: use a kmem_cache for block groups

We are currently allocating block groups using the generic slabs, and
given that the size of btrfs_block_group structure is 672 bytes (on a
release kernel), we end up using the kmalloc-1024 slab and therefore
waste quite some memory since on a 4K page system we can only fit 4
block groups per page. The block groups are also allocated and
delallocated with some frequency, specially if we have auto reclaim
enabled.

So use a kmem_cache for block groups, this way on a 4K page system we
can fit 6 block groups per page instead of 4.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Filipe Manana 2026-04-15 12:26:40 +01:00 committed by David Sterba
parent 3fc0803f1c
commit d293344c22
3 changed files with 26 additions and 3 deletions

View File

@ -22,6 +22,23 @@
#include "accessors.h"
#include "extent-tree.h"
static struct kmem_cache *block_group_cache;
int __init btrfs_init_block_group(void)
{
block_group_cache = kmem_cache_create("btrfs_block_group",
sizeof(struct btrfs_block_group),
0, 0, NULL);
if (!block_group_cache)
return -ENOMEM;
return 0;
}
void __cold btrfs_exit_block_group(void)
{
kmem_cache_destroy(block_group_cache);
}
#ifdef CONFIG_BTRFS_DEBUG
int btrfs_should_fragment_free_space(const struct btrfs_block_group *block_group)
{
@ -182,7 +199,7 @@ void btrfs_put_block_group(struct btrfs_block_group *cache)
kfree(cache->free_space_ctl);
btrfs_free_chunk_map(cache->physical_map);
kfree(cache);
kmem_cache_free(block_group_cache, cache);
}
}
@ -2371,13 +2388,13 @@ static struct btrfs_block_group *btrfs_create_block_group(
{
struct btrfs_block_group *cache;
cache = kzalloc_obj(*cache, GFP_NOFS);
cache = kmem_cache_zalloc(block_group_cache, GFP_NOFS);
if (!cache)
return NULL;
cache->free_space_ctl = kzalloc_obj(*cache->free_space_ctl, GFP_NOFS);
if (!cache->free_space_ctl) {
kfree(cache);
kmem_cache_free(block_group_cache, cache);
return NULL;
}

View File

@ -320,6 +320,9 @@ static inline u64 btrfs_block_group_available_space(const struct btrfs_block_gro
int btrfs_should_fragment_free_space(const struct btrfs_block_group *block_group);
#endif
int __init btrfs_init_block_group(void);
void __cold btrfs_exit_block_group(void);
struct btrfs_block_group *btrfs_lookup_first_block_group(
struct btrfs_fs_info *info, u64 bytenr);
struct btrfs_block_group *btrfs_lookup_block_group(

View File

@ -2603,6 +2603,9 @@ static const struct init_sequence mod_init_seq[] = {
}, {
.init_func = btrfs_init_compress,
.exit_func = btrfs_exit_compress,
}, {
.init_func = btrfs_init_block_group,
.exit_func = btrfs_exit_block_group,
}, {
.init_func = btrfs_init_cachep,
.exit_func = btrfs_destroy_cachep,