linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).