From bae895a5a3300c2da605dd0c841e175c4c9e5872 Mon Sep 17 00:00:00 2001
From: Kent Overstreet <kent.overstreet@gmail.com>
Date: Sun, 18 Apr 2021 17:54:56 -0400
Subject: [PATCH] bcachefs: Add allocator thread state to sysfs

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
---
 fs/bcachefs/alloc_background.c | 25 ++++++++++++++++---------
 fs/bcachefs/alloc_background.h |  4 +++-
 fs/bcachefs/alloc_types.h      | 12 ++++++++++++
 fs/bcachefs/bcachefs.h         | 11 +----------
 fs/bcachefs/movinggc.c         |  2 +-
 fs/bcachefs/sysfs.c            |  6 ++++--
 6 files changed, 37 insertions(+), 23 deletions(-)

diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
index 055b6b5596664..54e58b377e517 100644
--- a/fs/bcachefs/alloc_background.c
+++ b/fs/bcachefs/alloc_background.c
@@ -25,6 +25,13 @@
 #include <linux/sched/task.h>
 #include <linux/sort.h>
 
+const char * const bch2_allocator_states[] = {
+#define x(n)	#n,
+	ALLOC_THREAD_STATES()
+#undef x
+	NULL
+};
+
 static const unsigned BCH_ALLOC_V1_FIELD_BYTES[] = {
 #define x(name, bits) [BCH_ALLOC_FIELD_V1_##name] = bits / 8,
 	BCH_ALLOC_FIELDS_V1()
@@ -469,7 +476,7 @@ static int wait_buckets_available(struct bch_fs *c, struct bch_dev *ca)
 	s64 available;
 	int ret = 0;
 
-	ca->allocator_state = ALLOCATOR_BLOCKED;
+	ca->allocator_state = ALLOCATOR_blocked;
 	closure_wake_up(&c->freelist_wait);
 
 	while (1) {
@@ -497,7 +504,7 @@ static int wait_buckets_available(struct bch_fs *c, struct bch_dev *ca)
 	}
 
 	__set_current_state(TASK_RUNNING);
-	ca->allocator_state = ALLOCATOR_RUNNING;
+	ca->allocator_state = ALLOCATOR_running;
 	closure_wake_up(&c->freelist_wait);
 
 	return ret;
@@ -978,15 +985,15 @@ static int push_invalidated_bucket(struct bch_fs *c, struct bch_dev *ca, size_t
 				fifo_pop(&ca->free_inc, bucket);
 
 				closure_wake_up(&c->freelist_wait);
-				ca->allocator_state = ALLOCATOR_RUNNING;
+				ca->allocator_state = ALLOCATOR_running;
 
 				spin_unlock(&c->freelist_lock);
 				goto out;
 			}
 		}
 
-		if (ca->allocator_state != ALLOCATOR_BLOCKED_FULL) {
-			ca->allocator_state = ALLOCATOR_BLOCKED_FULL;
+		if (ca->allocator_state != ALLOCATOR_blocked_full) {
+			ca->allocator_state = ALLOCATOR_blocked_full;
 			closure_wake_up(&c->freelist_wait);
 		}
 
@@ -1053,12 +1060,12 @@ static int bch2_allocator_thread(void *arg)
 
 	while (1) {
 		if (!allocator_thread_running(ca)) {
-			ca->allocator_state = ALLOCATOR_STOPPED;
+			ca->allocator_state = ALLOCATOR_stopped;
 			if (kthread_wait_freezable(allocator_thread_running(ca)))
 				break;
 		}
 
-		ca->allocator_state = ALLOCATOR_RUNNING;
+		ca->allocator_state = ALLOCATOR_running;
 
 		cond_resched();
 		if (kthread_should_stop())
@@ -1139,7 +1146,7 @@ static int bch2_allocator_thread(void *arg)
 
 stop:
 	pr_debug("alloc thread stopping (ret %i)", ret);
-	ca->allocator_state = ALLOCATOR_STOPPED;
+	ca->allocator_state = ALLOCATOR_stopped;
 	closure_wake_up(&c->freelist_wait);
 	return 0;
 }
@@ -1319,7 +1326,7 @@ void bch2_dev_allocator_quiesce(struct bch_fs *c, struct bch_dev *ca)
 {
 	if (ca->alloc_thread)
 		closure_wait_event(&c->freelist_wait,
-				   ca->allocator_state != ALLOCATOR_RUNNING);
+				   ca->allocator_state != ALLOCATOR_running);
 }
 
 /* stop allocator thread: */
diff --git a/fs/bcachefs/alloc_background.h b/fs/bcachefs/alloc_background.h
index 6fededcd9f868..73e1c27c96e31 100644
--- a/fs/bcachefs/alloc_background.h
+++ b/fs/bcachefs/alloc_background.h
@@ -6,6 +6,8 @@
 #include "alloc_types.h"
 #include "debug.h"
 
+extern const char * const bch2_allocator_states[];
+
 struct bkey_alloc_unpacked {
 	u64		bucket;
 	u8		dev;
@@ -100,7 +102,7 @@ static inline void bch2_wake_allocator(struct bch_dev *ca)
 	p = rcu_dereference(ca->alloc_thread);
 	if (p) {
 		wake_up_process(p);
-		ca->allocator_state = ALLOCATOR_RUNNING;
+		ca->allocator_state = ALLOCATOR_running;
 	}
 	rcu_read_unlock();
 }
diff --git a/fs/bcachefs/alloc_types.h b/fs/bcachefs/alloc_types.h
index be164d6108bbc..4a1cd8b73d16b 100644
--- a/fs/bcachefs/alloc_types.h
+++ b/fs/bcachefs/alloc_types.h
@@ -10,6 +10,18 @@
 
 struct ec_bucket_buf;
 
+#define ALLOC_THREAD_STATES()		\
+	x(stopped)			\
+	x(running)			\
+	x(blocked)			\
+	x(blocked_full)
+
+enum allocator_states {
+#define x(n)	ALLOCATOR_##n,
+	ALLOC_THREAD_STATES()
+#undef x
+};
+
 enum alloc_reserve {
 	RESERVE_BTREE_MOVINGGC	= -2,
 	RESERVE_BTREE		= -1,
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
index 12441f943a6d0..9502f393a59ff 100644
--- a/fs/bcachefs/bcachefs.h
+++ b/fs/bcachefs/bcachefs.h
@@ -457,16 +457,7 @@ struct bch_dev {
 	size_t			inc_gen_needs_gc;
 	size_t			inc_gen_really_needs_gc;
 
-	/*
-	 * XXX: this should be an enum for allocator state, so as to include
-	 * error state
-	 */
-	enum {
-		ALLOCATOR_STOPPED,
-		ALLOCATOR_RUNNING,
-		ALLOCATOR_BLOCKED,
-		ALLOCATOR_BLOCKED_FULL,
-	}			allocator_state;
+	enum allocator_states	allocator_state;
 
 	alloc_heap		alloc_heap;
 
diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c
index e25fa0a2a4b57..3d57a72e63e43 100644
--- a/fs/bcachefs/movinggc.c
+++ b/fs/bcachefs/movinggc.c
@@ -108,7 +108,7 @@ static bool have_copygc_reserve(struct bch_dev *ca)
 
 	spin_lock(&ca->fs->freelist_lock);
 	ret = fifo_full(&ca->free[RESERVE_MOVINGGC]) ||
-		ca->allocator_state != ALLOCATOR_RUNNING;
+		ca->allocator_state != ALLOCATOR_running;
 	spin_unlock(&ca->fs->freelist_lock);
 
 	return ret;
diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c
index ff93e5ba9f419..c4d79096c53ad 100644
--- a/fs/bcachefs/sysfs.c
+++ b/fs/bcachefs/sysfs.c
@@ -805,7 +805,8 @@ static void dev_alloc_debug_to_text(struct printbuf *out, struct bch_dev *ca)
 	       "open_buckets_wait\t%s\n"
 	       "open_buckets_btree\t%u\n"
 	       "open_buckets_user\t%u\n"
-	       "btree reserve cache\t%u\n",
+	       "btree reserve cache\t%u\n"
+	       "thread state:\t\t%s\n",
 	       stats.buckets_ec,
 	       __dev_buckets_available(ca, stats),
 	       fifo_used(&ca->free_inc),		ca->free_inc.size,
@@ -818,7 +819,8 @@ static void dev_alloc_debug_to_text(struct printbuf *out, struct bch_dev *ca)
 	       c->open_buckets_wait.list.first		? "waiting" : "empty",
 	       nr[BCH_DATA_btree],
 	       nr[BCH_DATA_user],
-	       c->btree_reserve_cache_nr);
+	       c->btree_reserve_cache_nr,
+	       bch2_allocator_states[ca->allocator_state]);
 }
 
 static const char * const bch2_rw[] = {
-- 
2.30.2