bcachefs: Use mmap() instead of vmalloc_exec() in userspace
authorKent Overstreet <kent.overstreet@gmail.com>
Sat, 24 Apr 2021 04:38:16 +0000 (00:38 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:02 +0000 (17:09 -0400)
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>
fs/bcachefs/btree_cache.c

index 5a5eb99..a42e092 100644 (file)
@@ -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;