Skip to content

Commit 5d4c851

Browse files
committed
Merge tag 'bcachefs-2024-07-12' of https://evilpiepirate.org/git/bcachefs
Pull more bcachefs fixes from Kent Overstreet: - revert the SLAB_ACCOUNT patch, something crazy is going on in memcg and someone forgot to test - minor fixes: missing rcu_read_lock(), scheduling while atomic (in an emergency shutdown path) - two lockdep fixes; these could have gone earlier, but were left to bake awhile * tag 'bcachefs-2024-07-12' of https://evilpiepirate.org/git/bcachefs: bcachefs: bch2_gc_btree() should not use btree_root_lock bcachefs: Set PF_MEMALLOC_NOFS when trans->locked bcachefs; Use trans_unlock_long() when waiting on allocator Revert "bcachefs: Mark bch_inode_info as SLAB_ACCOUNT" bcachefs: fix scheduling while atomic in break_cycle() bcachefs: Fix RCU splat
2 parents 43db1e0 + 1841027 commit 5d4c851

File tree

11 files changed

+87
-24
lines changed

11 files changed

+87
-24
lines changed

fs/bcachefs/btree_gc.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -641,16 +641,30 @@ static int bch2_gc_btree(struct btree_trans *trans, enum btree_id btree, bool in
641641
target_depth = 0;
642642

643643
/* root */
644-
mutex_lock(&c->btree_root_lock);
645-
struct btree *b = bch2_btree_id_root(c, btree)->b;
646-
if (!btree_node_fake(b)) {
644+
do {
645+
retry_root:
646+
bch2_trans_begin(trans);
647+
648+
struct btree_iter iter;
649+
bch2_trans_node_iter_init(trans, &iter, btree, POS_MIN,
650+
0, bch2_btree_id_root(c, btree)->b->c.level, 0);
651+
struct btree *b = bch2_btree_iter_peek_node(&iter);
652+
ret = PTR_ERR_OR_ZERO(b);
653+
if (ret)
654+
goto err_root;
655+
656+
if (b != btree_node_root(c, b)) {
657+
bch2_trans_iter_exit(trans, &iter);
658+
goto retry_root;
659+
}
660+
647661
gc_pos_set(c, gc_pos_btree(btree, b->c.level + 1, SPOS_MAX));
648-
ret = lockrestart_do(trans,
649-
bch2_gc_mark_key(trans, b->c.btree_id, b->c.level + 1,
650-
NULL, NULL, bkey_i_to_s_c(&b->key), initial));
662+
struct bkey_s_c k = bkey_i_to_s_c(&b->key);
663+
ret = bch2_gc_mark_key(trans, btree, b->c.level + 1, NULL, NULL, k, initial);
651664
level = b->c.level;
652-
}
653-
mutex_unlock(&c->btree_root_lock);
665+
err_root:
666+
bch2_trans_iter_exit(trans, &iter);
667+
} while (bch2_err_matches(ret, BCH_ERR_transaction_restart));
654668

655669
if (ret)
656670
return ret;

fs/bcachefs/btree_iter.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ static int bch2_btree_path_traverse_all(struct btree_trans *trans)
996996

997997
bch2_trans_unlock(trans);
998998
cond_resched();
999-
trans->locked = true;
999+
trans_set_locked(trans);
10001000

10011001
if (unlikely(trans->memory_allocation_failure)) {
10021002
struct closure cl;
@@ -3089,7 +3089,8 @@ u32 bch2_trans_begin(struct btree_trans *trans)
30893089
bch2_trans_srcu_unlock(trans);
30903090

30913091
trans->last_begin_ip = _RET_IP_;
3092-
trans->locked = true;
3092+
3093+
trans_set_locked(trans);
30933094

30943095
if (trans->restarted) {
30953096
bch2_btree_path_traverse_all(trans);
@@ -3159,7 +3160,6 @@ struct btree_trans *__bch2_trans_get(struct bch_fs *c, unsigned fn_idx)
31593160
trans->last_begin_time = local_clock();
31603161
trans->fn_idx = fn_idx;
31613162
trans->locking_wait.task = current;
3162-
trans->locked = true;
31633163
trans->journal_replay_not_finished =
31643164
unlikely(!test_bit(JOURNAL_replay_done, &c->journal.flags)) &&
31653165
atomic_inc_not_zero(&c->journal_keys.ref);
@@ -3193,6 +3193,7 @@ struct btree_trans *__bch2_trans_get(struct bch_fs *c, unsigned fn_idx)
31933193
trans->srcu_idx = srcu_read_lock(&c->btree_trans_barrier);
31943194
trans->srcu_lock_time = jiffies;
31953195
trans->srcu_held = true;
3196+
trans_set_locked(trans);
31963197

31973198
closure_init_stack_release(&trans->ref);
31983199
return trans;

fs/bcachefs/btree_locking.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ static noinline int break_cycle(struct lock_graph *g, struct printbuf *cycle)
231231
prt_newline(&buf);
232232
}
233233

234-
bch2_print_string_as_lines(KERN_ERR, buf.buf);
234+
bch2_print_string_as_lines_nonblocking(KERN_ERR, buf.buf);
235235
printbuf_exit(&buf);
236236
BUG();
237237
}
@@ -792,7 +792,7 @@ static inline int __bch2_trans_relock(struct btree_trans *trans, bool trace)
792792
return bch2_trans_relock_fail(trans, path, &f, trace);
793793
}
794794

795-
trans->locked = true;
795+
trans_set_locked(trans);
796796
out:
797797
bch2_trans_verify_locks(trans);
798798
return 0;
@@ -812,16 +812,14 @@ void bch2_trans_unlock_noassert(struct btree_trans *trans)
812812
{
813813
__bch2_trans_unlock(trans);
814814

815-
trans->locked = false;
816-
trans->last_unlock_ip = _RET_IP_;
815+
trans_set_unlocked(trans);
817816
}
818817

819818
void bch2_trans_unlock(struct btree_trans *trans)
820819
{
821820
__bch2_trans_unlock(trans);
822821

823-
trans->locked = false;
824-
trans->last_unlock_ip = _RET_IP_;
822+
trans_set_unlocked(trans);
825823
}
826824

827825
void bch2_trans_unlock_long(struct btree_trans *trans)

fs/bcachefs/btree_locking.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,28 @@ int bch2_six_check_for_deadlock(struct six_lock *lock, void *p);
193193

194194
/* lock: */
195195

196+
static inline void trans_set_locked(struct btree_trans *trans)
197+
{
198+
if (!trans->locked) {
199+
trans->locked = true;
200+
trans->last_unlock_ip = 0;
201+
202+
trans->pf_memalloc_nofs = (current->flags & PF_MEMALLOC_NOFS) != 0;
203+
current->flags |= PF_MEMALLOC_NOFS;
204+
}
205+
}
206+
207+
static inline void trans_set_unlocked(struct btree_trans *trans)
208+
{
209+
if (trans->locked) {
210+
trans->locked = false;
211+
trans->last_unlock_ip = _RET_IP_;
212+
213+
if (!trans->pf_memalloc_nofs)
214+
current->flags &= ~PF_MEMALLOC_NOFS;
215+
}
216+
}
217+
196218
static inline int __btree_node_lock_nopath(struct btree_trans *trans,
197219
struct btree_bkey_cached_common *b,
198220
enum six_lock_type type,

fs/bcachefs/btree_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ struct btree_trans {
484484
bool lock_may_not_fail:1;
485485
bool srcu_held:1;
486486
bool locked:1;
487+
bool pf_memalloc_nofs:1;
487488
bool write_locked:1;
488489
bool used_mempool:1;
489490
bool in_traverse_all:1;

fs/bcachefs/buckets.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca,
805805
"bucket %u:%zu gen %u (mem gen %u) data type %s: stale dirty ptr (gen %u)\n"
806806
"while marking %s",
807807
ptr->dev, bucket_nr, b_gen,
808-
*bucket_gen(ca, bucket_nr),
808+
bucket_gen_get(ca, bucket_nr),
809809
bch2_data_type_str(bucket_data_type ?: ptr_data_type),
810810
ptr->gen,
811811
(printbuf_reset(&buf),

fs/bcachefs/buckets.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ static inline u8 *bucket_gen(struct bch_dev *ca, size_t b)
116116
return gens->b + b;
117117
}
118118

119+
static inline u8 bucket_gen_get(struct bch_dev *ca, size_t b)
120+
{
121+
rcu_read_lock();
122+
u8 gen = *bucket_gen(ca, b);
123+
rcu_read_unlock();
124+
return gen;
125+
}
126+
119127
static inline size_t PTR_BUCKET_NR(const struct bch_dev *ca,
120128
const struct bch_extent_ptr *ptr)
121129
{

fs/bcachefs/fs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,8 +2073,7 @@ int __init bch2_vfs_init(void)
20732073
{
20742074
int ret = -ENOMEM;
20752075

2076-
bch2_inode_cache = KMEM_CACHE(bch_inode_info, SLAB_RECLAIM_ACCOUNT |
2077-
SLAB_ACCOUNT);
2076+
bch2_inode_cache = KMEM_CACHE(bch_inode_info, SLAB_RECLAIM_ACCOUNT);
20782077
if (!bch2_inode_cache)
20792078
goto err;
20802079

fs/bcachefs/io_misc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ int bch2_extent_fallocate(struct btree_trans *trans,
125125
bch2_bkey_buf_exit(&old, c);
126126

127127
if (closure_nr_remaining(&cl) != 1) {
128-
bch2_trans_unlock(trans);
128+
bch2_trans_unlock_long(trans);
129129
closure_sync(&cl);
130130
}
131131

fs/bcachefs/util.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,24 +252,43 @@ void bch2_prt_u64_base2(struct printbuf *out, u64 v)
252252
bch2_prt_u64_base2_nbits(out, v, fls64(v) ?: 1);
253253
}
254254

255-
void bch2_print_string_as_lines(const char *prefix, const char *lines)
255+
static void __bch2_print_string_as_lines(const char *prefix, const char *lines,
256+
bool nonblocking)
256257
{
258+
bool locked = false;
257259
const char *p;
258260

259261
if (!lines) {
260262
printk("%s (null)\n", prefix);
261263
return;
262264
}
263265

264-
console_lock();
266+
if (!nonblocking) {
267+
console_lock();
268+
locked = true;
269+
} else {
270+
locked = console_trylock();
271+
}
272+
265273
while (1) {
266274
p = strchrnul(lines, '\n');
267275
printk("%s%.*s\n", prefix, (int) (p - lines), lines);
268276
if (!*p)
269277
break;
270278
lines = p + 1;
271279
}
272-
console_unlock();
280+
if (locked)
281+
console_unlock();
282+
}
283+
284+
void bch2_print_string_as_lines(const char *prefix, const char *lines)
285+
{
286+
return __bch2_print_string_as_lines(prefix, lines, false);
287+
}
288+
289+
void bch2_print_string_as_lines_nonblocking(const char *prefix, const char *lines)
290+
{
291+
return __bch2_print_string_as_lines(prefix, lines, true);
273292
}
274293

275294
int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *task, unsigned skipnr,

0 commit comments

Comments
 (0)