Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+87 -24
+22 -8
fs/bcachefs/btree_gc.c
··· 641 641 target_depth = 0; 642 642 643 643 /* 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 + 647 661 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); 651 664 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)); 654 668 655 669 if (ret) 656 670 return ret;
+4 -3
fs/bcachefs/btree_iter.c
··· 996 996 997 997 bch2_trans_unlock(trans); 998 998 cond_resched(); 999 - trans->locked = true; 999 + trans_set_locked(trans); 1000 1000 1001 1001 if (unlikely(trans->memory_allocation_failure)) { 1002 1002 struct closure cl; ··· 3089 3089 bch2_trans_srcu_unlock(trans); 3090 3090 3091 3091 trans->last_begin_ip = _RET_IP_; 3092 - trans->locked = true; 3092 + 3093 + trans_set_locked(trans); 3093 3094 3094 3095 if (trans->restarted) { 3095 3096 bch2_btree_path_traverse_all(trans); ··· 3160 3159 trans->last_begin_time = local_clock(); 3161 3160 trans->fn_idx = fn_idx; 3162 3161 trans->locking_wait.task = current; 3163 - trans->locked = true; 3164 3162 trans->journal_replay_not_finished = 3165 3163 unlikely(!test_bit(JOURNAL_replay_done, &c->journal.flags)) && 3166 3164 atomic_inc_not_zero(&c->journal_keys.ref); ··· 3193 3193 trans->srcu_idx = srcu_read_lock(&c->btree_trans_barrier); 3194 3194 trans->srcu_lock_time = jiffies; 3195 3195 trans->srcu_held = true; 3196 + trans_set_locked(trans); 3196 3197 3197 3198 closure_init_stack_release(&trans->ref); 3198 3199 return trans;
+4 -6
fs/bcachefs/btree_locking.c
··· 231 231 prt_newline(&buf); 232 232 } 233 233 234 - bch2_print_string_as_lines(KERN_ERR, buf.buf); 234 + bch2_print_string_as_lines_nonblocking(KERN_ERR, buf.buf); 235 235 printbuf_exit(&buf); 236 236 BUG(); 237 237 } ··· 792 792 return bch2_trans_relock_fail(trans, path, &f, trace); 793 793 } 794 794 795 - trans->locked = true; 795 + trans_set_locked(trans); 796 796 out: 797 797 bch2_trans_verify_locks(trans); 798 798 return 0; ··· 812 812 { 813 813 __bch2_trans_unlock(trans); 814 814 815 - trans->locked = false; 816 - trans->last_unlock_ip = _RET_IP_; 815 + trans_set_unlocked(trans); 817 816 } 818 817 819 818 void bch2_trans_unlock(struct btree_trans *trans) 820 819 { 821 820 __bch2_trans_unlock(trans); 822 821 823 - trans->locked = false; 824 - trans->last_unlock_ip = _RET_IP_; 822 + trans_set_unlocked(trans); 825 823 } 826 824 827 825 void bch2_trans_unlock_long(struct btree_trans *trans)
+22
fs/bcachefs/btree_locking.h
··· 193 193 194 194 /* lock: */ 195 195 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 + 196 218 static inline int __btree_node_lock_nopath(struct btree_trans *trans, 197 219 struct btree_bkey_cached_common *b, 198 220 enum six_lock_type type,
+1
fs/bcachefs/btree_types.h
··· 484 484 bool lock_may_not_fail:1; 485 485 bool srcu_held:1; 486 486 bool locked:1; 487 + bool pf_memalloc_nofs:1; 487 488 bool write_locked:1; 488 489 bool used_mempool:1; 489 490 bool in_traverse_all:1;
+1 -1
fs/bcachefs/buckets.c
··· 805 805 "bucket %u:%zu gen %u (mem gen %u) data type %s: stale dirty ptr (gen %u)\n" 806 806 "while marking %s", 807 807 ptr->dev, bucket_nr, b_gen, 808 - *bucket_gen(ca, bucket_nr), 808 + bucket_gen_get(ca, bucket_nr), 809 809 bch2_data_type_str(bucket_data_type ?: ptr_data_type), 810 810 ptr->gen, 811 811 (printbuf_reset(&buf),
+8
fs/bcachefs/buckets.h
··· 116 116 return gens->b + b; 117 117 } 118 118 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 + 119 127 static inline size_t PTR_BUCKET_NR(const struct bch_dev *ca, 120 128 const struct bch_extent_ptr *ptr) 121 129 {
+1 -2
fs/bcachefs/fs.c
··· 2073 2073 { 2074 2074 int ret = -ENOMEM; 2075 2075 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); 2078 2077 if (!bch2_inode_cache) 2079 2078 goto err; 2080 2079
+1 -1
fs/bcachefs/io_misc.c
··· 125 125 bch2_bkey_buf_exit(&old, c); 126 126 127 127 if (closure_nr_remaining(&cl) != 1) { 128 - bch2_trans_unlock(trans); 128 + bch2_trans_unlock_long(trans); 129 129 closure_sync(&cl); 130 130 } 131 131
+22 -3
fs/bcachefs/util.c
··· 252 252 bch2_prt_u64_base2_nbits(out, v, fls64(v) ?: 1); 253 253 } 254 254 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) 256 257 { 258 + bool locked = false; 257 259 const char *p; 258 260 259 261 if (!lines) { ··· 263 261 return; 264 262 } 265 263 266 - console_lock(); 264 + if (!nonblocking) { 265 + console_lock(); 266 + locked = true; 267 + } else { 268 + locked = console_trylock(); 269 + } 270 + 267 271 while (1) { 268 272 p = strchrnul(lines, '\n'); 269 273 printk("%s%.*s\n", prefix, (int) (p - lines), lines); ··· 277 269 break; 278 270 lines = p + 1; 279 271 } 280 - console_unlock(); 272 + if (locked) 273 + console_unlock(); 274 + } 275 + 276 + void bch2_print_string_as_lines(const char *prefix, const char *lines) 277 + { 278 + return __bch2_print_string_as_lines(prefix, lines, false); 279 + } 280 + 281 + void bch2_print_string_as_lines_nonblocking(const char *prefix, const char *lines) 282 + { 283 + return __bch2_print_string_as_lines(prefix, lines, true); 281 284 } 282 285 283 286 int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *task, unsigned skipnr,
+1
fs/bcachefs/util.h
··· 315 315 void bch2_prt_u64_base2(struct printbuf *, u64); 316 316 317 317 void bch2_print_string_as_lines(const char *prefix, const char *lines); 318 + void bch2_print_string_as_lines_nonblocking(const char *prefix, const char *lines); 318 319 319 320 typedef DARRAY(unsigned long) bch_stacktrace; 320 321 int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *, unsigned, gfp_t);