summaryrefslogtreecommitdiff
path: root/fs/bcachefs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-10-30 15:13:09 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-11-04 22:19:11 -0400
commitf82755e4e8b83a4a98ebd6d819d716547fe11919 (patch)
tree4b91b447e899e17bf0098223e5ad813af6ae776c /fs/bcachefs
parentc4accde498dd7db8352d574958d19a5f710aba69 (diff)
bcachefs: Data move path now uses bch2_trans_unlock_long()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs')
-rw-r--r--fs/bcachefs/btree_iter.c12
-rw-r--r--fs/bcachefs/move.c13
-rw-r--r--fs/bcachefs/move.h1
-rw-r--r--fs/bcachefs/movinggc.c4
-rw-r--r--fs/bcachefs/rebalance.c2
5 files changed, 23 insertions, 9 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index b22fd395a1fd..af98545e0f35 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -2833,6 +2833,13 @@ void *__bch2_trans_kmalloc(struct btree_trans *trans, size_t size)
return p;
}
+static inline void check_srcu_held_too_long(struct btree_trans *trans)
+{
+ WARN(trans->srcu_held && time_after(jiffies, trans->srcu_lock_time + HZ * 10),
+ "btree trans held srcu lock (delaying memory reclaim) for %lu seconds",
+ (jiffies - trans->srcu_lock_time) / HZ);
+}
+
void bch2_trans_srcu_unlock(struct btree_trans *trans)
{
if (trans->srcu_held) {
@@ -2843,6 +2850,7 @@ void bch2_trans_srcu_unlock(struct btree_trans *trans)
if (path->cached && !btree_node_locked(path, 0))
path->l[0].b = ERR_PTR(-BCH_ERR_no_btree_node_srcu_reset);
+ check_srcu_held_too_long(trans);
srcu_read_unlock(&c->btree_trans_barrier, trans->srcu_idx);
trans->srcu_held = false;
}
@@ -3074,8 +3082,10 @@ void bch2_trans_put(struct btree_trans *trans)
check_btree_paths_leaked(trans);
- if (trans->srcu_held)
+ if (trans->srcu_held) {
+ check_srcu_held_too_long(trans);
srcu_read_unlock(&c->btree_trans_barrier, trans->srcu_idx);
+ }
bch2_journal_preres_put(&c->journal, &trans->journal_preres);
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
index 1b15b010461a..ab749bf2fcbc 100644
--- a/fs/bcachefs/move.c
+++ b/fs/bcachefs/move.c
@@ -147,9 +147,8 @@ void bch2_moving_ctxt_do_pending_writes(struct moving_context *ctxt)
{
struct moving_io *io;
- bch2_trans_unlock(ctxt->trans);
-
while ((io = bch2_moving_ctxt_next_pending_write(ctxt))) {
+ bch2_trans_unlock_long(ctxt->trans);
list_del(&io->read_list);
move_write(io);
}
@@ -485,8 +484,8 @@ int bch2_move_ratelimit(struct moving_context *ctxt)
struct bch_fs *c = ctxt->trans->c;
u64 delay;
- if (ctxt->wait_on_copygc) {
- bch2_trans_unlock(ctxt->trans);
+ if (ctxt->wait_on_copygc && !c->copygc_running) {
+ bch2_trans_unlock_long(ctxt->trans);
wait_event_killable(c->copygc_running_wq,
!c->copygc_running ||
kthread_should_stop());
@@ -495,8 +494,12 @@ int bch2_move_ratelimit(struct moving_context *ctxt)
do {
delay = ctxt->rate ? bch2_ratelimit_delay(ctxt->rate) : 0;
+
if (delay) {
- bch2_trans_unlock(ctxt->trans);
+ if (delay > HZ / 10)
+ bch2_trans_unlock_long(ctxt->trans);
+ else
+ bch2_trans_unlock(ctxt->trans);
set_current_state(TASK_INTERRUPTIBLE);
}
diff --git a/fs/bcachefs/move.h b/fs/bcachefs/move.h
index 1b1e8678bfae..07cf9d42643b 100644
--- a/fs/bcachefs/move.h
+++ b/fs/bcachefs/move.h
@@ -45,6 +45,7 @@ do { \
\
if (_cond) \
break; \
+ bch2_trans_unlock_long((_ctxt)->trans); \
__wait_event((_ctxt)->wait, \
bch2_moving_ctxt_next_pending_write(_ctxt) || \
(cond_finished = (_cond))); \
diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c
index e0efa5282a77..4d955f3cc5b2 100644
--- a/fs/bcachefs/movinggc.c
+++ b/fs/bcachefs/movinggc.c
@@ -128,7 +128,7 @@ static void move_buckets_wait(struct moving_context *ctxt,
kfree(i);
}
- bch2_trans_unlock(ctxt->trans);
+ bch2_trans_unlock_long(ctxt->trans);
}
static bool bucket_in_flight(struct buckets_in_flight *list,
@@ -327,7 +327,7 @@ static int bch2_copygc_thread(void *arg)
while (!ret && !kthread_should_stop()) {
bool did_work = false;
- bch2_trans_unlock(ctxt.trans);
+ bch2_trans_unlock_long(ctxt.trans);
cond_resched();
if (!c->copy_gc_enabled) {
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
index 82014cc6e271..3319190b8d9c 100644
--- a/fs/bcachefs/rebalance.c
+++ b/fs/bcachefs/rebalance.c
@@ -348,7 +348,7 @@ static int do_rebalance(struct moving_context *ctxt)
!kthread_should_stop() &&
!atomic64_read(&r->work_stats.sectors_seen) &&
!atomic64_read(&r->scan_stats.sectors_seen)) {
- bch2_trans_unlock(trans);
+ bch2_trans_unlock_long(trans);
rebalance_wait(c);
}