* [PATCH] bcache: fix a race between register and allocator thread
@ 2019-01-24 8:09 Junhui Tang
2019-02-06 8:08 ` Coly Li
0 siblings, 1 reply; 2+ messages in thread
From: Junhui Tang @ 2019-01-24 8:09 UTC (permalink / raw)
To: colyli; +Cc: linux-bcache, linux-block
From d75d1b51aeedcc9349571be084c5f51d8f7e7612 Mon Sep 17 00:00:00 2001
From: Tang Junhui <tang.junhui.linux@gmail.com>
Date: Thu, 24 Jan 2019 16:01:35 +0800
Subject: [PATCH] bcache: fix a race between register and allocator thread
when register a new cache device, allocator get stucked,
the call trace is bellow:
Sangfor:EDS/eds-fe5192de /sf # cat /proc/3642/task/*/stack
[<ffffffffa02b01c8>] bch_bucket_alloc+0x178/0x2b0 [bcache]
[<ffffffffa02c737d>] bch_prio_write+0x18d/0x320 [bcache]
[<ffffffffa02b0042>] bch_allocator_thread+0x432/0x440 [bcache]
[<ffffffff810a1430>] kthread+0xc0/0xd0
[<ffffffff8173def7>] ret_from_fork+0x77/0xb0
[<ffffffffffffffff>] 0xffffffffffffffff
There is a race between register and allocator thread:
register thread allocator thread
run_cache_set
=>bch_initial_gc_finish
alloc prio buckets
=>bch_cache_allocator_start
start allocator thread bch_allocator_thread
=>bch_prio_write =>invalidate_buckets
write prio using prio buckets fill bucket into ca->free_inc
=>SET_CACHE_SYNC
set cache sync mode =>bch_prio_write
since cache sync mode is set,
write prio to bucket, and the
prio bucket has been used in
register thread, no bucket can
used. so the allocator thread
stuck here.
In this patch, register thread wait for the allocator thread to finish
work, then write prio to buckets and set cache to sync mode.
Signed-off-by: Tang Junhui <tang.junhui.linux@gmail.com>
---
drivers/md/bcache/super.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index fa4058e..818d2f1 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1852,13 +1852,28 @@ static void run_cache_set(struct cache_set *c)
bch_initial_gc_finish(c);
err = "error starting allocator thread";
- for_each_cache(ca, c, i)
- if (bch_cache_allocator_start(ca))
- goto err;
-
mutex_lock(&c->bucket_lock);
- for_each_cache(ca, c, i)
+ for_each_cache(ca, c, i) {
+ DEFINE_WAIT(wait);
+
+ if (bch_cache_allocator_start(ca)) {
+ mutex_unlock(&c->bucket_lock);
+ goto err;
+ }
+
+ for (;;) {
+ prepare_to_wait(&c->bucket_wait, &wait,
+ TASK_UNINTERRUPTIBLE);
+ if (!fifo_empty(&ca->free_inc))
+ break;
+ mutex_unlock(&c->bucket_lock);
+ schedule();
+ mutex_lock(&c->bucket_lock);
+ }
+
+ finish_wait(&c->bucket_wait, &wait);
bch_prio_write(ca);
+ }
mutex_unlock(&c->bucket_lock);
err = "cannot allocate new UUID bucket";
--
1.8.3.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] bcache: fix a race between register and allocator thread
2019-01-24 8:09 [PATCH] bcache: fix a race between register and allocator thread Junhui Tang
@ 2019-02-06 8:08 ` Coly Li
0 siblings, 0 replies; 2+ messages in thread
From: Coly Li @ 2019-02-06 8:08 UTC (permalink / raw)
To: Junhui Tang; +Cc: linux-bcache, linux-block
On 2019/1/24 4:09 下午, Junhui Tang wrote:
> From d75d1b51aeedcc9349571be084c5f51d8f7e7612 Mon Sep 17 00:00:00 2001
> From: Tang Junhui <tang.junhui.linux@gmail.com>
> Date: Thu, 24 Jan 2019 16:01:35 +0800
> Subject: [PATCH] bcache: fix a race between register and allocator thread
>
> when register a new cache device, allocator get stucked,
> the call trace is bellow:
> Sangfor:EDS/eds-fe5192de /sf # cat /proc/3642/task/*/stack
> [<ffffffffa02b01c8>] bch_bucket_alloc+0x178/0x2b0 [bcache]
> [<ffffffffa02c737d>] bch_prio_write+0x18d/0x320 [bcache]
> [<ffffffffa02b0042>] bch_allocator_thread+0x432/0x440 [bcache]
> [<ffffffff810a1430>] kthread+0xc0/0xd0
> [<ffffffff8173def7>] ret_from_fork+0x77/0xb0
> [<ffffffffffffffff>] 0xffffffffffffffff
>
> There is a race between register and allocator thread:
> register thread allocator thread
> run_cache_set
> =>bch_initial_gc_finish
> alloc prio buckets
> =>bch_cache_allocator_start
> start allocator thread bch_allocator_thread
> =>bch_prio_write =>invalidate_buckets
> write prio using prio buckets fill bucket into ca->free_inc
> =>SET_CACHE_SYNC
> set cache sync mode =>bch_prio_write
> since cache sync mode is set,
> write prio to bucket, and the
> prio bucket has been used in
> register thread, no bucket can
> used. so the allocator thread
> stuck here.
> In this patch, register thread wait for the allocator thread to finish
> work, then write prio to buckets and set cache to sync mode.
>
> Signed-off-by: Tang Junhui <tang.junhui.linux@gmail.com>
> ---
> drivers/md/bcache/super.c | 25 ++++++++++++++++++++-----
> 1 file changed, 20 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
> index fa4058e..818d2f1 100644
> --- a/drivers/md/bcache/super.c
> +++ b/drivers/md/bcache/super.c
> @@ -1852,13 +1852,28 @@ static void run_cache_set(struct cache_set *c)
> bch_initial_gc_finish(c);
>
> err = "error starting allocator thread";
> - for_each_cache(ca, c, i)
> - if (bch_cache_allocator_start(ca))
> - goto err;
> -
> mutex_lock(&c->bucket_lock);
> - for_each_cache(ca, c, i)
> + for_each_cache(ca, c, i) {
> + DEFINE_WAIT(wait);
> +
> + if (bch_cache_allocator_start(ca)) {
> + mutex_unlock(&c->bucket_lock);
> + goto err;
> + }
> +
> + for (;;) {
> + prepare_to_wait(&c->bucket_wait, &wait,
> + TASK_UNINTERRUPTIBLE);
> + if (!fifo_empty(&ca->free_inc))
> + break;
> + mutex_unlock(&c->bucket_lock);
> + schedule();
> + mutex_lock(&c->bucket_lock);
> + }
> +
> + finish_wait(&c->bucket_wait, &wait);
> bch_prio_write(ca);
> + }
> mutex_unlock(&c->bucket_lock);
>
> err = "cannot allocate new UUID bucket";
>
Hi Junhui,
It seems your patch losts all indent format. Could you please to handle
it and resend the peroper format again ?
Thanks.
--
Coly Li
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-02-06 8:08 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-24 8:09 [PATCH] bcache: fix a race between register and allocator thread Junhui Tang
2019-02-06 8:08 ` Coly Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).