bcachefs: Journal reclaim requires memalloc_noreclaim_save()
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 20 Nov 2020 02:15:39 +0000 (21:15 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:48 +0000 (17:08 -0400)
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>
fs/bcachefs/journal_reclaim.c

index 7f8ab13256c865b4d03b897d52542777d8e6458d..9c67597d1ec64945db9f5ce63cb78a0f3acd1ada 100644 (file)
@@ -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))