bcache: Move journal work to new flush wq
authorKai Krakow <kai@kaishome.de>
Wed, 10 Feb 2021 05:07:27 +0000 (13:07 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 4 Mar 2021 09:26:43 +0000 (10:26 +0100)
commit afe78ab46f638ecdf80a35b122ffc92c20d9ae5d upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/md/bcache/bcache.h
drivers/md/bcache/journal.c
drivers/md/bcache/super.c

index 830ca66c284a7d81ad034c85cc6ef53f750bc121..36de6f7ddf2219b28a2d3c536f1af0976dc872f5 100644 (file)
@@ -986,6 +986,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 8250d2d1d780c1a08a206040c2198f9a47b3a0bb..b4fd923e0d401cda61cb8d01e13745826d4534f7 100644 (file)
@@ -958,8 +958,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 a1b010c783046513311839610a4f2f8f39b964a5..b0d569032dd4e02c5ae7c172d0f2ebd27023973a 100644 (file)
@@ -48,6 +48,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;
 
 
@@ -2652,6 +2653,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)
@@ -2715,6 +2718,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;