bcache: shrink btree node cache after bch_btree_check()
authorColy Li <colyli@suse.de>
Fri, 28 Jun 2019 11:59:52 +0000 (19:59 +0800)
committerJens Axboe <axboe@kernel.dk>
Fri, 28 Jun 2019 13:39:17 +0000 (07:39 -0600)
When cache set starts, bch_btree_check() will check all bkeys on cache
device by calculating the checksum. This operation will consume a huge
number of system memory if there are a lot of data cached. Since bcache
uses its own mca cache to maintain all its read-in btree nodes, and only
releases the cache space when system memory manage code starts to shrink
caches. Then before memory manager code to call the mca cache shrinker
callback, bcache mca cache will compete memory resource with user space
application, which may have nagive effect to performance of user space
workloads (e.g. data base, or I/O service of distributed storage node).

This patch tries to call bcache mca shrinker routine to proactively
release mca cache memory, to decrease the memory pressure of system and
avoid negative effort of the overall system I/O performance.

Signed-off-by: Coly Li <colyli@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/md/bcache/super.c

index a8ea4e2086a923910df4fe651667372b896ca126..26e374fbf57c7873d626e3a84b052a7a8c9d2353 100644 (file)
@@ -1880,6 +1880,23 @@ static int run_cache_set(struct cache_set *c)
                if (bch_btree_check(c))
                        goto err;
 
+               /*
+                * bch_btree_check() may occupy too much system memory which
+                * has negative effects to user space application (e.g. data
+                * base) performance. Shrink the mca cache memory proactively
+                * here to avoid competing memory with user space workloads..
+                */
+               if (!c->shrinker_disabled) {
+                       struct shrink_control sc;
+
+                       sc.gfp_mask = GFP_KERNEL;
+                       sc.nr_to_scan = c->btree_cache_used * c->btree_pages;
+                       /* first run to clear b->accessed tag */
+                       c->shrink.scan_objects(&c->shrink, &sc);
+                       /* second run to reap non-accessed nodes */
+                       c->shrink.scan_objects(&c->shrink, &sc);
+               }
+
                bch_journal_mark(c, &journal);
                bch_initial_gc_finish(c);
                pr_debug("btree_check() done");