summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-02-24 18:05:21 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2018-02-27 23:03:37 -0500
commit632ff7a0aa95053ac30e8ccf62fbe0b249b4f3e8 (patch)
tree9b045f85f05dbe3e8619d8d225ab01be96fffc16
parentbf5f4fa0f6c8d6fd6d3d321a8cc9641a9f4883aa (diff)
bcachefs: Better signal from allocator to copygc thread
-rw-r--r--fs/bcachefs/alloc.c13
-rw-r--r--fs/bcachefs/bcachefs.h1
-rw-r--r--fs/bcachefs/movinggc.c4
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;