bcache: Move journal work to new flush wq
authorKai Krakow <kai@kaishome.de>
Wed, 10 Feb 2021 05:07:27 +0000 (13:07 +0800)
committerJens Axboe <axboe@kernel.dk>
Wed, 10 Feb 2021 15:06:00 +0000 (08:06 -0700)
This is potentially long running and not latency sensitive, let's get
it out of the way of other latency sensitive events.

As observed in the previous commit, the `system_wq` comes easily
congested by bcache, and this fixes a few more stalls I was observing
every once in a while.

Let's not make this `WQ_MEM_RECLAIM` as it showed to reduce performance
of boot and file system operations in my tests. Also, without
`WQ_MEM_RECLAIM`, I no longer see desktop stalls. This matches the
previous behavior as `system_wq` also does no memory reclaim:

> // workqueue.c:
> system_wq = alloc_workqueue("events", 0, 0);

Cc: Coly Li <colyli@suse.de>
Cc: stable@vger.kernel.org # 5.4+
Signed-off-by: Kai Krakow <kai@kaishome.de>
Signed-off-by: Coly Li <colyli@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/md/bcache/bcache.h
drivers/md/bcache/journal.c
drivers/md/bcache/super.c

index 2b8c7dd2cfae55b3a7f6e877738585b37515c4bb..848dd4db165929ea8607eea1808734cebd381e58 100644 (file)
@@ -1005,6 +1005,7 @@ void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent);
 
 extern struct workqueue_struct *bcache_wq;
 extern struct workqueue_struct *bch_journal_wq;
+extern struct workqueue_struct *bch_flush_wq;
 extern struct mutex bch_register_lock;
 extern struct list_head bch_cache_sets;
 
index aefbdb7e003bc02edf926ede5ad7638d75cb57db..c6613e817333765aa240053f381a374a7d8f1db8 100644 (file)
@@ -932,8 +932,8 @@ atomic_t *bch_journal(struct cache_set *c,
                journal_try_write(c);
        } else if (!w->dirty) {
                w->dirty = true;
-               schedule_delayed_work(&c->journal.work,
-                                     msecs_to_jiffies(c->journal_delay_ms));
+               queue_delayed_work(bch_flush_wq, &c->journal.work,
+                                  msecs_to_jiffies(c->journal_delay_ms));
                spin_unlock(&c->journal.lock);
        } else {
                spin_unlock(&c->journal.lock);
index 97405aec4b5141a0728fcfcdbdb47b15b15320f5..71691f32959b38adc1f1aab670a371589919023d 100644 (file)
@@ -49,6 +49,7 @@ static int bcache_major;
 static DEFINE_IDA(bcache_device_idx);
 static wait_queue_head_t unregister_wait;
 struct workqueue_struct *bcache_wq;
+struct workqueue_struct *bch_flush_wq;
 struct workqueue_struct *bch_journal_wq;
 
 
@@ -2821,6 +2822,8 @@ static void bcache_exit(void)
                destroy_workqueue(bcache_wq);
        if (bch_journal_wq)
                destroy_workqueue(bch_journal_wq);
+       if (bch_flush_wq)
+               destroy_workqueue(bch_flush_wq);
        bch_btree_exit();
 
        if (bcache_major)
@@ -2884,6 +2887,19 @@ static int __init bcache_init(void)
        if (!bcache_wq)
                goto err;
 
+       /*
+        * Let's not make this `WQ_MEM_RECLAIM` for the following reasons:
+        *
+        * 1. It used `system_wq` before which also does no memory reclaim.
+        * 2. With `WQ_MEM_RECLAIM` desktop stalls, increased boot times, and
+        *    reduced throughput can be observed.
+        *
+        * We still want to user our own queue to not congest the `system_wq`.
+        */
+       bch_flush_wq = alloc_workqueue("bch_flush", 0, 0);
+       if (!bch_flush_wq)
+               goto err;
+
        bch_journal_wq = alloc_workqueue("bch_journal", WQ_MEM_RECLAIM, 0);
        if (!bch_journal_wq)
                goto err;