diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-04-24 07:38:16 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-23 00:09:02 +0300 |
commit | 65c0601a329580f6a016298f7148305288b7d719 (patch) | |
tree | 79d4f2942092b9ec89c9d56f838ee7c13e7ba442 | |
parent | 537c32f5212396751bf39b10d71af60af32dc257 (diff) | |
download | linux-65c0601a329580f6a016298f7148305288b7d719.tar.xz |
bcachefs: Use mmap() instead of vmalloc_exec() in userspace
Calling mmap() directly is much better than malloc() then mprotect(), we
end up with much less address space fragmentation.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/btree_cache.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c index 5a5eb99baefa..a42e0922f5e9 100644 --- a/fs/bcachefs/btree_cache.c +++ b/fs/bcachefs/btree_cache.c @@ -33,21 +33,21 @@ static inline unsigned btree_cache_can_free(struct btree_cache *bc) return max_t(int, 0, bc->used - bc->reserve); } -static void __btree_node_data_free(struct bch_fs *c, struct btree *b) +static void btree_node_data_free(struct bch_fs *c, struct btree *b) { + struct btree_cache *bc = &c->btree_cache; + EBUG_ON(btree_node_write_in_flight(b)); kvpfree(b->data, btree_bytes(c)); b->data = NULL; +#ifdef __KERNEL__ kvfree(b->aux_data); +#else + munmap(b->aux_data, btree_aux_data_bytes(b)); +#endif b->aux_data = NULL; -} -static void btree_node_data_free(struct bch_fs *c, struct btree *b) -{ - struct btree_cache *bc = &c->btree_cache; - - __btree_node_data_free(c, b); bc->used--; list_move(&b->list, &bc->freed); } @@ -75,8 +75,15 @@ static int btree_node_data_alloc(struct bch_fs *c, struct btree *b, gfp_t gfp) b->data = kvpmalloc(btree_bytes(c), gfp); if (!b->data) return -ENOMEM; - +#ifdef __KERNEL__ b->aux_data = kvmalloc(btree_aux_data_bytes(b), gfp); +#else + b->aux_data = mmap(NULL, btree_aux_data_bytes(b), + PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); + if (b->aux_data == MAP_FAILED) + b->aux_data = NULL; +#endif if (!b->aux_data) { kvpfree(b->data, btree_bytes(c)); b->data = NULL; |