bcachefs: fix scheduling while atomic in break_cycle()

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2024-07-10 12:59:28 -04:00
parent 6f692b1672
commit fd80d14005
3 changed files with 24 additions and 4 deletions

View 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();
}

View 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,

View 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);