diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-02-24 18:05:21 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-02-27 23:03:37 -0500 |
commit | 632ff7a0aa95053ac30e8ccf62fbe0b249b4f3e8 (patch) | |
tree | 9b045f85f05dbe3e8619d8d225ab01be96fffc16 | |
parent | bf5f4fa0f6c8d6fd6d3d321a8cc9641a9f4883aa (diff) |
bcachefs: Better signal from allocator to copygc thread
-rw-r--r-- | fs/bcachefs/alloc.c | 13 | ||||
-rw-r--r-- | fs/bcachefs/bcachefs.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/movinggc.c | 4 |
3 files changed, 16 insertions, 2 deletions
diff --git a/fs/bcachefs/alloc.c b/fs/bcachefs/alloc.c index a76f2b7cc48a..470ef207ac04 100644 --- a/fs/bcachefs/alloc.c +++ b/fs/bcachefs/alloc.c @@ -966,11 +966,24 @@ static int bch2_allocator_thread(void *arg) if (fifo_full(&ca->free_inc)) break; + if (!fifo_empty(&ca->free_inc) && + !fifo_full(&ca->free[RESERVE_MOVINGGC])) + break; + + /* + * copygc may be waiting until either its reserve fills + * up, or we can't make forward progress: + */ + ca->allocator_blocked = true; + closure_wake_up(&c->freelist_wait); + if (wait_buckets_available(c, ca)) { up_read(&c->gc_lock); return 0; } } + + ca->allocator_blocked = false; up_read(&c->gc_lock); sort_free_inc(c, ca); diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index c2226e4c1062..369d078c3d2e 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -399,6 +399,7 @@ struct bch_dev { size_t inc_gen_really_needs_gc; u64 allocator_journal_seq_flush; bool allocator_invalidating_data; + bool allocator_blocked; alloc_heap alloc_heap; diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c index ad56e039163b..2aa58b557794 100644 --- a/fs/bcachefs/movinggc.c +++ b/fs/bcachefs/movinggc.c @@ -106,8 +106,8 @@ static bool have_copygc_reserve(struct bch_dev *ca) bool ret; spin_lock(&ca->freelist_lock); - ret = fifo_used(&ca->free[RESERVE_MOVINGGC]) >= - COPYGC_BUCKETS_PER_ITER(ca); + ret = fifo_full(&ca->free[RESERVE_MOVINGGC]) || + ca->allocator_blocked; spin_unlock(&ca->freelist_lock); return ret; |