]> www.infradead.org Git - users/hch/xfs.git/commitdiff
bcachefs: fix scheduling while atomic in break_cycle()
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 10 Jul 2024 16:59:28 +0000 (12:59 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 10 Jul 2024 16:59:28 +0000 (12:59 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_locking.c
fs/bcachefs/util.c
fs/bcachefs/util.h

index d66fff22109ae791b3a803209bc263c8d899a864..191d9a50378aa1e59f22e6b57fa5150de6768d6a 100644 (file)
@@ -231,7 +231,7 @@ static noinline int break_cycle(struct lock_graph *g, struct printbuf *cycle)
                        prt_newline(&buf);
                }
 
-               bch2_print_string_as_lines(KERN_ERR, buf.buf);
+               bch2_print_string_as_lines_nonblocking(KERN_ERR, buf.buf);
                printbuf_exit(&buf);
                BUG();
        }
index de331dec2a99cfb1192cbdaf898d43c4f1ee8194..4ec7e44d6e36cbe2ecc39d7e2648076179e4205d 100644 (file)
@@ -252,8 +252,10 @@ void bch2_prt_u64_base2(struct printbuf *out, u64 v)
        bch2_prt_u64_base2_nbits(out, v, fls64(v) ?: 1);
 }
 
-void bch2_print_string_as_lines(const char *prefix, const char *lines)
+static void __bch2_print_string_as_lines(const char *prefix, const char *lines,
+                                        bool nonblocking)
 {
+       bool locked = false;
        const char *p;
 
        if (!lines) {
@@ -261,7 +263,13 @@ void bch2_print_string_as_lines(const char *prefix, const char *lines)
                return;
        }
 
-       console_lock();
+       if (!nonblocking) {
+               console_lock();
+               locked = true;
+       } else {
+               locked = console_trylock();
+       }
+
        while (1) {
                p = strchrnul(lines, '\n');
                printk("%s%.*s\n", prefix, (int) (p - lines), lines);
@@ -269,7 +277,18 @@ void bch2_print_string_as_lines(const char *prefix, const char *lines)
                        break;
                lines = p + 1;
        }
-       console_unlock();
+       if (locked)
+               console_unlock();
+}
+
+void bch2_print_string_as_lines(const char *prefix, const char *lines)
+{
+       return __bch2_print_string_as_lines(prefix, lines, false);
+}
+
+void bch2_print_string_as_lines_nonblocking(const char *prefix, const char *lines)
+{
+       return __bch2_print_string_as_lines(prefix, lines, true);
 }
 
 int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *task, unsigned skipnr,
index 5d2c470a49ac9789be55d684029dd696e13ca83a..5b0533ec4c7e18fc648d30b2a49929fc0338d95d 100644 (file)
@@ -315,6 +315,7 @@ void bch2_prt_u64_base2_nbits(struct printbuf *, u64, unsigned);
 void bch2_prt_u64_base2(struct printbuf *, u64);
 
 void bch2_print_string_as_lines(const char *prefix, const char *lines);
+void bch2_print_string_as_lines_nonblocking(const char *prefix, const char *lines);
 
 typedef DARRAY(unsigned long) bch_stacktrace;
 int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *, unsigned, gfp_t);