]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/btree_cache.c
Update bcachefs sources to feaca6edbd24 mean and variance: Promote to lib/math
[bcachefs-tools-debian] / libbcachefs / btree_cache.c
index 72dea90e12fa9d11b2d1ceb74edebecc3b78bc5e..47e7770d05831757d45c4aee9331f52a10c06e76 100644 (file)
 
 #include <linux/prefetch.h>
 #include <linux/sched/mm.h>
-#include <linux/seq_buf.h>
-
-#define BTREE_CACHE_NOT_FREED_INCREMENT(counter) \
-do {                                            \
-       if (shrinker_counter)                    \
-               bc->not_freed_##counter++;       \
-} while (0)
 
 const char * const bch2_btree_node_flags[] = {
 #define x(f)   #f,
@@ -208,7 +201,7 @@ static inline struct btree *btree_cache_find(struct btree_cache *bc,
  * this version is for btree nodes that have already been freed (we're not
  * reaping a real btree node)
  */
-static int __btree_node_reclaim(struct bch_fs *c, struct btree *b, bool flush, bool shrinker_counter)
+static int __btree_node_reclaim(struct bch_fs *c, struct btree *b, bool flush)
 {
        struct btree_cache *bc = &c->btree_cache;
        int ret = 0;
@@ -218,64 +211,38 @@ wait_on_io:
        if (b->flags & ((1U << BTREE_NODE_dirty)|
                        (1U << BTREE_NODE_read_in_flight)|
                        (1U << BTREE_NODE_write_in_flight))) {
-               if (!flush) {
-                       if (btree_node_dirty(b))
-                               BTREE_CACHE_NOT_FREED_INCREMENT(dirty);
-                       else if (btree_node_read_in_flight(b))
-                               BTREE_CACHE_NOT_FREED_INCREMENT(read_in_flight);
-                       else if (btree_node_write_in_flight(b))
-                               BTREE_CACHE_NOT_FREED_INCREMENT(write_in_flight);
+               if (!flush)
                        return -BCH_ERR_ENOMEM_btree_node_reclaim;
-               }
 
                /* XXX: waiting on IO with btree cache lock held */
                bch2_btree_node_wait_on_read(b);
                bch2_btree_node_wait_on_write(b);
        }
 
-       if (!six_trylock_intent(&b->c.lock)) {
-               BTREE_CACHE_NOT_FREED_INCREMENT(lock_intent);
+       if (!six_trylock_intent(&b->c.lock))
                return -BCH_ERR_ENOMEM_btree_node_reclaim;
-       }
 
-       if (!six_trylock_write(&b->c.lock)) {
-               BTREE_CACHE_NOT_FREED_INCREMENT(lock_write);
+       if (!six_trylock_write(&b->c.lock))
                goto out_unlock_intent;
-       }
 
        /* recheck under lock */
        if (b->flags & ((1U << BTREE_NODE_read_in_flight)|
                        (1U << BTREE_NODE_write_in_flight))) {
-               if (!flush) {
-                       if (btree_node_read_in_flight(b))
-                               BTREE_CACHE_NOT_FREED_INCREMENT(read_in_flight);
-                       else if (btree_node_write_in_flight(b))
-                               BTREE_CACHE_NOT_FREED_INCREMENT(write_in_flight);
+               if (!flush)
                        goto out_unlock;
-               }
                six_unlock_write(&b->c.lock);
                six_unlock_intent(&b->c.lock);
                goto wait_on_io;
        }
 
-       if (btree_node_noevict(b)) {
-               BTREE_CACHE_NOT_FREED_INCREMENT(noevict);
-               goto out_unlock;
-       }
-       if (btree_node_write_blocked(b)) {
-               BTREE_CACHE_NOT_FREED_INCREMENT(write_blocked);
-               goto out_unlock;
-       }
-       if (btree_node_will_make_reachable(b)) {
-               BTREE_CACHE_NOT_FREED_INCREMENT(will_make_reachable);
+       if (btree_node_noevict(b) ||
+           btree_node_write_blocked(b) ||
+           btree_node_will_make_reachable(b))
                goto out_unlock;
-       }
 
        if (btree_node_dirty(b)) {
-               if (!flush) {
-                       BTREE_CACHE_NOT_FREED_INCREMENT(dirty);
+               if (!flush)
                        goto out_unlock;
-               }
                /*
                 * Using the underscore version because we don't want to compact
                 * bsets after the write, since this node is about to be evicted
@@ -305,14 +272,14 @@ out_unlock_intent:
        goto out;
 }
 
-static int btree_node_reclaim(struct bch_fs *c, struct btree *b, bool shrinker_counter)
+static int btree_node_reclaim(struct bch_fs *c, struct btree *b)
 {
-       return __btree_node_reclaim(c, b, false, shrinker_counter);
+       return __btree_node_reclaim(c, b, false);
 }
 
 static int btree_node_write_and_reclaim(struct bch_fs *c, struct btree *b)
 {
-       return __btree_node_reclaim(c, b, true, false);
+       return __btree_node_reclaim(c, b, true);
 }
 
 static unsigned long bch2_btree_cache_scan(struct shrinker *shrink,
@@ -360,12 +327,11 @@ static unsigned long bch2_btree_cache_scan(struct shrinker *shrink,
                if (touched >= nr)
                        goto out;
 
-               if (!btree_node_reclaim(c, b, true)) {
+               if (!btree_node_reclaim(c, b)) {
                        btree_node_data_free(c, b);
                        six_unlock_write(&b->c.lock);
                        six_unlock_intent(&b->c.lock);
                        freed++;
-                       bc->freed++;
                }
        }
 restart:
@@ -374,11 +340,9 @@ restart:
 
                if (btree_node_accessed(b)) {
                        clear_btree_node_accessed(b);
-                       bc->not_freed_access_bit++;
-               } else if (!btree_node_reclaim(c, b, true)) {
+               } else if (!btree_node_reclaim(c, b)) {
                        freed++;
                        btree_node_data_free(c, b);
-                       bc->freed++;
 
                        bch2_btree_node_hash_remove(bc, b);
                        six_unlock_write(&b->c.lock);
@@ -428,17 +392,6 @@ static unsigned long bch2_btree_cache_count(struct shrinker *shrink,
        return btree_cache_can_free(bc);
 }
 
-static void bch2_btree_cache_shrinker_to_text(struct seq_buf *s, struct shrinker *shrink)
-{
-       struct bch_fs *c = shrink->private_data;
-       char *cbuf;
-       size_t buflen = seq_buf_get_buf(s, &cbuf);
-       struct printbuf out = PRINTBUF_EXTERN(cbuf, buflen);
-
-       bch2_btree_cache_to_text(&out, &c->btree_cache);
-       seq_buf_commit(s, out.pos);
-}
-
 void bch2_fs_btree_cache_exit(struct bch_fs *c)
 {
        struct btree_cache *bc = &c->btree_cache;
@@ -525,7 +478,6 @@ int bch2_fs_btree_cache_init(struct bch_fs *c)
        bc->shrink = shrink;
        shrink->count_objects   = bch2_btree_cache_count;
        shrink->scan_objects    = bch2_btree_cache_scan;
-       shrink->to_text         = bch2_btree_cache_shrinker_to_text;
        shrink->seeks           = 4;
        shrink->private_data    = c;
        shrinker_register(shrink);
@@ -599,7 +551,7 @@ static struct btree *btree_node_cannibalize(struct bch_fs *c)
        struct btree *b;
 
        list_for_each_entry_reverse(b, &bc->live, list)
-               if (!btree_node_reclaim(c, b, false))
+               if (!btree_node_reclaim(c, b))
                        return b;
 
        while (1) {
@@ -635,7 +587,7 @@ struct btree *bch2_btree_node_mem_alloc(struct btree_trans *trans, bool pcpu_rea
         * disk node. Check the freed list before allocating a new one:
         */
        list_for_each_entry(b, freed, list)
-               if (!btree_node_reclaim(c, b, false)) {
+               if (!btree_node_reclaim(c, b)) {
                        list_del_init(&b->list);
                        goto got_node;
                }
@@ -661,7 +613,7 @@ got_node:
         * the list. Check if there's any freed nodes there:
         */
        list_for_each_entry(b2, &bc->freeable, list)
-               if (!btree_node_reclaim(c, b2, false)) {
+               if (!btree_node_reclaim(c, b2)) {
                        swap(b->data, b2->data);
                        swap(b->aux_data, b2->aux_data);
                        btree_node_to_freedlist(bc, b2);
@@ -1257,21 +1209,9 @@ void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c, const struc
               stats.failed);
 }
 
-void bch2_btree_cache_to_text(struct printbuf *out, const struct btree_cache *bc)
+void bch2_btree_cache_to_text(struct printbuf *out, const struct bch_fs *c)
 {
-       prt_printf(out, "nr nodes:\t\t%u\n", bc->used);
-       prt_printf(out, "nr dirty:\t\t%u\n", atomic_read(&bc->dirty));
-       prt_printf(out, "cannibalize lock:\t%p\n", bc->alloc_lock);
-
-       prt_printf(out, "freed:\t\t\t\t%u\n", bc->freed);
-       prt_printf(out, "not freed, dirty:\t\t%u\n", bc->not_freed_dirty);
-       prt_printf(out, "not freed, write in flight:\t%u\n", bc->not_freed_write_in_flight);
-       prt_printf(out, "not freed, read in flight:\t%u\n", bc->not_freed_read_in_flight);
-       prt_printf(out, "not freed, lock intent failed:\t%u\n", bc->not_freed_lock_intent);
-       prt_printf(out, "not freed, lock write failed:\t%u\n", bc->not_freed_lock_write);
-       prt_printf(out, "not freed, access bit:\t\t%u\n", bc->not_freed_access_bit);
-       prt_printf(out, "not freed, no evict failed:\t%u\n", bc->not_freed_noevict);
-       prt_printf(out, "not freed, write blocked:\t%u\n", bc->not_freed_write_blocked);
-       prt_printf(out, "not freed, will make reachable:\t%u\n", bc->not_freed_will_make_reachable);
-
+       prt_printf(out, "nr nodes:\t\t%u\n", c->btree_cache.used);
+       prt_printf(out, "nr dirty:\t\t%u\n", atomic_read(&c->btree_cache.dirty));
+       prt_printf(out, "cannibalize lock:\t%p\n", c->btree_cache.alloc_lock);
 }