From: Coly Li <colyli@suse.de>
To: linux-bcache@vger.kernel.org
Cc: linux-block@vger.kernel.org, Coly Li <colyli@suse.de>
Subject: [PATCH] bcache: add alloc_thread_running to struct cache
Date: Thu, 25 Apr 2019 01:25:39 +0800 [thread overview]
Message-ID: <20190424172539.4991-1-colyli@suse.de> (raw)
During the process to run a cache set, bch_btree_check() may consume too
many memory to fail bch_cache_allocator_start() to create and run
ca->alloc_thread. If bch_cache_allocator_start() fails, run_cache_set()
will fail too and the cache set won't start to work.
If the allocator thread is created before calling bch_btree_check(),
there will be enough memory for bch_cache_allocator_start(). This is
the major idea how this patch fixes the above issue.
This patch adds a bool variable 'alloc_thread_running' in struct cache.
If caller of bch_allocator_thread() sets 'wait' parameter to true, then
inside bch_allocator_thread(), ca->alloc_thread_running will be set to
false. Which means after the allocator thread starts, it will wait on
allocator_wait() before go into thread main loop, until
ca->alloc_thread_running is set to true.
Then we can call bch_cache_allocator_start() before calling
bch_btree_check() to get enough memory to create allocator thread.
Because ca->alloc_thread_running is initialized to false, we are sure it
won't do real work before being waken up later (at the location where
bch_cache_allocator_start() was originally called in run_cache_set())
If the cache device is not in sync state, all existing data will be
invalid and bch_btree_check() won't be called, for such condition,
'wait' parameter will be set to false to bch_cache_allocator_start(),
then ca->alloc_thread_running will be initialized to true, kernel thread
routine bch_allocator_thread() will not wait and directly go into the
thread main loop.
Now we can avoid cache set start failure in extreme memory pressure
situation, and not change current cache set start procedure.
Signed-off-by: Coly Li <colyli@suse.de>
---
drivers/md/bcache/alloc.c | 14 ++++++++++----
drivers/md/bcache/bcache.h | 3 ++-
drivers/md/bcache/super.c | 16 ++++++++++++----
3 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index f8986effcb50..c7bb913735d8 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -321,6 +321,8 @@ static int bch_allocator_thread(void *arg)
mutex_lock(&ca->set->bucket_lock);
+ allocator_wait(ca, ca->alloc_thread_running == true);
+
while (1) {
/*
* First, we pull buckets off of the unused and free_inc lists,
@@ -719,12 +721,16 @@ int bch_open_buckets_alloc(struct cache_set *c)
return 0;
}
-int bch_cache_allocator_start(struct cache *ca)
+int bch_cache_allocator_start(struct cache *ca, bool wait)
{
- struct task_struct *k = kthread_run(bch_allocator_thread,
- ca, "bcache_allocator");
- if (IS_ERR(k))
+ struct task_struct *k;
+
+ ca->alloc_thread_running = (wait == true) ? false : true;
+ k = kthread_run(bch_allocator_thread, ca, "bcache_allocator");
+ if (IS_ERR(k)) {
+ pr_err("kthread_run() error: %p", k);
return PTR_ERR(k);
+ }
ca->alloc_thread = k;
return 0;
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index fdf75352e16a..385c6555ee93 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -454,6 +454,7 @@ struct cache {
struct journal_device journal;
+ bool alloc_thread_running;
/* The rest of this all shows up in sysfs */
#define IO_ERROR_SHIFT 20
atomic_t io_errors;
@@ -1019,7 +1020,7 @@ void bch_moving_init_cache_set(struct cache_set *c);
int bch_open_buckets_alloc(struct cache_set *c);
void bch_open_buckets_free(struct cache_set *c);
-int bch_cache_allocator_start(struct cache *ca);
+int bch_cache_allocator_start(struct cache *ca, bool wait);
void bch_debug_exit(void);
void bch_debug_init(void);
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index d9f9d701669f..8e6bcde08122 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1844,6 +1844,12 @@ static int run_cache_set(struct cache_set *c)
if (err)
goto err;
+ err = "error starting allocator thread";
+ for_each_cache(ca, c, i)
+ /* wait until ca->alloc_thread_running set to true */
+ if (bch_cache_allocator_start(ca, true))
+ goto err;
+
err = "error in recovery";
if (bch_btree_check(c))
goto err;
@@ -1859,10 +1865,11 @@ static int run_cache_set(struct cache_set *c)
*/
bch_journal_next(&c->journal);
- err = "error starting allocator thread";
for_each_cache(ca, c, i)
- if (bch_cache_allocator_start(ca))
- goto err;
+ if (!IS_ERR(ca->alloc_thread)) {
+ ca->alloc_thread_running = true;
+ wake_up_process(ca->alloc_thread);
+ }
/*
* First place it's safe to allocate: btree_check() and
@@ -1897,7 +1904,8 @@ static int run_cache_set(struct cache_set *c)
err = "error starting allocator thread";
for_each_cache(ca, c, i)
- if (bch_cache_allocator_start(ca))
+ /* start without waiting for ca->alloc_thread_running */
+ if (bch_cache_allocator_start(ca, false))
goto err;
mutex_lock(&c->bucket_lock);
--
2.16.4
reply other threads:[~2019-04-24 18:00 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190424172539.4991-1-colyli@suse.de \
--to=colyli@suse.de \
--cc=linux-bcache@vger.kernel.org \
--cc=linux-block@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.