summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-11-19 21:15:39 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:48 -0400
commit9d4582ffdb286d3513ee9ebf7961b1741d8cbc0d (patch)
tree031018c1cff43f37b7c98fed0b748902f5eba848
parentb3c2a06b7d89eb06454f31c4b396e37fbe59374c (diff)
bcachefs: Journal reclaim requires memalloc_noreclaim_save()
Memory reclaim requires journal reclaim to make forward progress - it's what cleans our caches - thus, while we're in journal reclaim or holding the journal reclaim lock we can't recurse into memory reclaim. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/journal_reclaim.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/fs/bcachefs/journal_reclaim.c b/fs/bcachefs/journal_reclaim.c
index 7f8ab13256c8..9c67597d1ec6 100644
--- a/fs/bcachefs/journal_reclaim.c
+++ b/fs/bcachefs/journal_reclaim.c
@@ -9,6 +9,8 @@
#include "super.h"
#include "trace.h"
+#include <linux/sched/mm.h>
+
/* Free space calculations: */
static unsigned journal_space_from(struct journal_device *ja,
@@ -537,8 +539,16 @@ void bch2_journal_reclaim(struct journal *j)
struct bch_fs *c = container_of(j, struct bch_fs, journal);
u64 seq_to_flush, nr_flushed = 0;
size_t min_nr;
+ unsigned flags;
+ /*
+ * We can't invoke memory reclaim while holding the reclaim_lock -
+ * journal reclaim is required to make progress for memory reclaim
+ * (cleaning the caches), so we can't get stuck in memory reclaim while
+ * we're holding the reclaim lock:
+ */
lockdep_assert_held(&j->reclaim_lock);
+ flags = memalloc_noreclaim_save();
do {
bch2_journal_do_discards(j);
@@ -575,6 +585,8 @@ void bch2_journal_reclaim(struct journal *j)
nr_flushed += journal_flush_pins(j, seq_to_flush, min_nr);
} while (min_nr);
+ memalloc_noreclaim_restore(flags);
+
trace_journal_reclaim_finish(c, nr_flushed);
if (!bch2_journal_error(j))