bcachefs: Use mm_account_reclaimed_pages() when freeing btree nodes
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 4 Sep 2024 19:30:48 +0000 (15:30 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Sep 2024 15:39:48 +0000 (11:39 -0400)
When freeing in a shrinker callback, we need to notify memory reclaim,
so it knows forward progress has been made.

Normally this is done in e.g. slab code, but we're not freeing through
slab - or rather we are, but these allocations are big, and use the
kmalloc_large() path.

This is really a bug in the slub code, but we're working around it here
for now.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_cache.c

index 02e6e609e377de49b585b63b01513bd893506a5c..9a2e6c6ea82c0d4edb5df3df8f2fe06d8cf37cd8 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/prefetch.h>
 #include <linux/sched/mm.h>
+#include <linux/swap.h>
 
 #define BTREE_CACHE_NOT_FREED_INCREMENT(counter) \
 do {                                            \
@@ -63,6 +64,16 @@ static void btree_node_data_free(struct bch_fs *c, struct btree *b)
 {
        struct btree_cache *bc = &c->btree_cache;
 
+       /*
+        * This should really be done in slub/vmalloc, but we're using the
+        * kmalloc_large() path, so we're working around a slub bug by doing
+        * this here:
+        */
+       if (b->data)
+               mm_account_reclaimed_pages(btree_buf_bytes(b) / PAGE_SIZE);
+       if (b->aux_data)
+               mm_account_reclaimed_pages(btree_aux_data_bytes(b) / PAGE_SIZE);
+
        EBUG_ON(btree_node_write_in_flight(b));
 
        clear_btree_node_just_written(b);