Skip to content

Commit b3f5620

Browse files
committed
Merge tag 'bcachefs-2024-08-08' of git://evilpiepirate.org/bcachefs
Pull bcachefs fixes from Kent Overstreet: "Assorted little stuff: - lockdep fixup for lockdep_set_notrack_class() - we can now remove a device when using erasure coding without deadlocking, though we still hit other issues - the 'allocator stuck' timeout is now configurable, and messages are ratelimited. The default timeout has been increased from 10 seconds to 30" * tag 'bcachefs-2024-08-08' of git://evilpiepirate.org/bcachefs: bcachefs: Use bch2_wait_on_allocator() in btree node alloc path bcachefs: Make allocator stuck timeout configurable, ratelimit messages bcachefs: Add missing path_traverse() to btree_iter_next_node() bcachefs: ec should not allocate from ro devs bcachefs: Improved allocator debugging for ec bcachefs: Add missing bch2_trans_begin() call bcachefs: Add a comment for bucket helper types bcachefs: Don't rely on implicit unsigned -> signed integer conversion lockdep: Fix lockdep_set_notrack_class() for CONFIG_LOCK_STAT bcachefs: Fix double free of ca->buckets_nouse
2 parents cb5b81b + 73dc165 commit b3f5620

16 files changed

+101
-31
lines changed

fs/bcachefs/alloc_background.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ static inline bool bucket_data_type_mismatch(enum bch_data_type bucket,
8282
bucket_data_type(bucket) != bucket_data_type(ptr);
8383
}
8484

85+
/*
86+
* It is my general preference to use unsigned types for unsigned quantities -
87+
* however, these helpers are used in disk accounting calculations run by
88+
* triggers where the output will be negated and added to an s64. unsigned is
89+
* right out even though all these quantities will fit in 32 bits, since it
90+
* won't be sign extended correctly; u64 will negate "correctly", but s64 is the
91+
* simpler option here.
92+
*/
8593
static inline s64 bch2_bucket_sectors_total(struct bch_alloc_v4 a)
8694
{
8795
return a.stripe_sectors + a.dirty_sectors + a.cached_sectors;
@@ -166,8 +174,8 @@ static inline u64 alloc_lru_idx_fragmentation(struct bch_alloc_v4 a,
166174
* avoid overflowing LRU_TIME_BITS on a corrupted fs, when
167175
* bucket_sectors_dirty is (much) bigger than bucket_size
168176
*/
169-
u64 d = min(bch2_bucket_sectors_dirty(a),
170-
ca->mi.bucket_size);
177+
u64 d = min_t(s64, bch2_bucket_sectors_dirty(a),
178+
ca->mi.bucket_size);
171179

172180
return div_u64(d * (1ULL << 31), ca->mi.bucket_size);
173181
}

fs/bcachefs/alloc_foreground.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,7 +1603,8 @@ void bch2_open_bucket_to_text(struct printbuf *out, struct bch_fs *c, struct ope
16031603
prt_newline(out);
16041604
}
16051605

1606-
void bch2_open_buckets_to_text(struct printbuf *out, struct bch_fs *c)
1606+
void bch2_open_buckets_to_text(struct printbuf *out, struct bch_fs *c,
1607+
struct bch_dev *ca)
16071608
{
16081609
struct open_bucket *ob;
16091610

@@ -1613,7 +1614,8 @@ void bch2_open_buckets_to_text(struct printbuf *out, struct bch_fs *c)
16131614
ob < c->open_buckets + ARRAY_SIZE(c->open_buckets);
16141615
ob++) {
16151616
spin_lock(&ob->lock);
1616-
if (ob->valid && !ob->on_partial_list)
1617+
if (ob->valid && !ob->on_partial_list &&
1618+
(!ca || ob->dev == ca->dev_idx))
16171619
bch2_open_bucket_to_text(out, c, ob);
16181620
spin_unlock(&ob->lock);
16191621
}
@@ -1756,11 +1758,12 @@ void bch2_dev_alloc_debug_to_text(struct printbuf *out, struct bch_dev *ca)
17561758
prt_printf(out, "buckets to invalidate\t%llu\r\n", should_invalidate_buckets(ca, stats));
17571759
}
17581760

1759-
void bch2_print_allocator_stuck(struct bch_fs *c)
1761+
static noinline void bch2_print_allocator_stuck(struct bch_fs *c)
17601762
{
17611763
struct printbuf buf = PRINTBUF;
17621764

1763-
prt_printf(&buf, "Allocator stuck? Waited for 10 seconds\n");
1765+
prt_printf(&buf, "Allocator stuck? Waited for %u seconds\n",
1766+
c->opts.allocator_stuck_timeout);
17641767

17651768
prt_printf(&buf, "Allocator debug:\n");
17661769
printbuf_indent_add(&buf, 2);
@@ -1790,3 +1793,24 @@ void bch2_print_allocator_stuck(struct bch_fs *c)
17901793
bch2_print_string_as_lines(KERN_ERR, buf.buf);
17911794
printbuf_exit(&buf);
17921795
}
1796+
1797+
static inline unsigned allocator_wait_timeout(struct bch_fs *c)
1798+
{
1799+
if (c->allocator_last_stuck &&
1800+
time_after(c->allocator_last_stuck + HZ * 60 * 2, jiffies))
1801+
return 0;
1802+
1803+
return c->opts.allocator_stuck_timeout * HZ;
1804+
}
1805+
1806+
void __bch2_wait_on_allocator(struct bch_fs *c, struct closure *cl)
1807+
{
1808+
unsigned t = allocator_wait_timeout(c);
1809+
1810+
if (t && closure_sync_timeout(cl, t)) {
1811+
c->allocator_last_stuck = jiffies;
1812+
bch2_print_allocator_stuck(c);
1813+
}
1814+
1815+
closure_sync(cl);
1816+
}

fs/bcachefs/alloc_foreground.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,19 @@ static inline struct write_point_specifier writepoint_ptr(struct write_point *wp
223223
void bch2_fs_allocator_foreground_init(struct bch_fs *);
224224

225225
void bch2_open_bucket_to_text(struct printbuf *, struct bch_fs *, struct open_bucket *);
226-
void bch2_open_buckets_to_text(struct printbuf *, struct bch_fs *);
226+
void bch2_open_buckets_to_text(struct printbuf *, struct bch_fs *, struct bch_dev *);
227227
void bch2_open_buckets_partial_to_text(struct printbuf *, struct bch_fs *);
228228

229229
void bch2_write_points_to_text(struct printbuf *, struct bch_fs *);
230230

231231
void bch2_fs_alloc_debug_to_text(struct printbuf *, struct bch_fs *);
232232
void bch2_dev_alloc_debug_to_text(struct printbuf *, struct bch_dev *);
233233

234-
void bch2_print_allocator_stuck(struct bch_fs *);
234+
void __bch2_wait_on_allocator(struct bch_fs *, struct closure *);
235+
static inline void bch2_wait_on_allocator(struct bch_fs *c, struct closure *cl)
236+
{
237+
if (cl->closure_get_happened)
238+
__bch2_wait_on_allocator(c, cl);
239+
}
235240

236241
#endif /* _BCACHEFS_ALLOC_FOREGROUND_H */

fs/bcachefs/bcachefs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,8 @@ struct bch_fs {
893893
struct bch_fs_usage_base __percpu *usage;
894894
u64 __percpu *online_reserved;
895895

896+
unsigned long allocator_last_stuck;
897+
896898
struct io_clock io_clock[2];
897899

898900
/* JOURNAL SEQ BLACKLIST */

fs/bcachefs/bcachefs_format.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,8 @@ LE64_BITMASK(BCH_SB_BACKGROUND_COMPRESSION_TYPE_HI,
836836

837837
LE64_BITMASK(BCH_SB_VERSION_UPGRADE_COMPLETE,
838838
struct bch_sb, flags[5], 0, 16);
839+
LE64_BITMASK(BCH_SB_ALLOCATOR_STUCK_TIMEOUT,
840+
struct bch_sb, flags[5], 16, 32);
839841

840842
static inline __u64 BCH_SB_COMPRESSION_TYPE(const struct bch_sb *sb)
841843
{

fs/bcachefs/btree_iter.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,6 +1921,11 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
19211921
bch2_trans_verify_not_in_restart(trans);
19221922
bch2_btree_iter_verify(iter);
19231923

1924+
ret = bch2_btree_path_traverse(trans, iter->path, iter->flags);
1925+
if (ret)
1926+
goto err;
1927+
1928+
19241929
struct btree_path *path = btree_iter_path(trans, iter);
19251930

19261931
/* already at end? */

fs/bcachefs/btree_update_interior.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,7 @@ bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
12641264
ret = bch2_btree_reserve_get(trans, as, nr_nodes, flags, &cl);
12651265

12661266
bch2_trans_unlock(trans);
1267-
closure_sync(&cl);
1267+
bch2_wait_on_allocator(c, &cl);
12681268
} while (bch2_err_matches(ret, BCH_ERR_operation_blocked));
12691269
}
12701270

fs/bcachefs/ec.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,9 @@ static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_
18091809
BUG_ON(v->nr_blocks != h->s->nr_data + h->s->nr_parity);
18101810
BUG_ON(v->nr_redundant != h->s->nr_parity);
18111811

1812+
/* * We bypass the sector allocator which normally does this: */
1813+
bitmap_and(devs.d, devs.d, c->rw_devs[BCH_DATA_user].d, BCH_SB_MEMBERS_MAX);
1814+
18121815
for_each_set_bit(i, h->s->blocks_gotten, v->nr_blocks) {
18131816
__clear_bit(v->ptrs[i].dev, devs.d);
18141817
if (i < h->s->nr_data)
@@ -2235,6 +2238,23 @@ void bch2_stripes_heap_to_text(struct printbuf *out, struct bch_fs *c)
22352238
mutex_unlock(&c->ec_stripes_heap_lock);
22362239
}
22372240

2241+
static void bch2_new_stripe_to_text(struct printbuf *out, struct bch_fs *c,
2242+
struct ec_stripe_new *s)
2243+
{
2244+
prt_printf(out, "\tidx %llu blocks %u+%u allocated %u ref %u %u %s obs",
2245+
s->idx, s->nr_data, s->nr_parity,
2246+
bitmap_weight(s->blocks_allocated, s->nr_data),
2247+
atomic_read(&s->ref[STRIPE_REF_io]),
2248+
atomic_read(&s->ref[STRIPE_REF_stripe]),
2249+
bch2_watermarks[s->h->watermark]);
2250+
2251+
struct bch_stripe *v = &bkey_i_to_stripe(&s->new_stripe.key)->v;
2252+
unsigned i;
2253+
for_each_set_bit(i, s->blocks_gotten, v->nr_blocks)
2254+
prt_printf(out, " %u", s->blocks[i]);
2255+
prt_newline(out);
2256+
}
2257+
22382258
void bch2_new_stripes_to_text(struct printbuf *out, struct bch_fs *c)
22392259
{
22402260
struct ec_stripe_head *h;
@@ -2247,23 +2267,15 @@ void bch2_new_stripes_to_text(struct printbuf *out, struct bch_fs *c)
22472267
bch2_watermarks[h->watermark]);
22482268

22492269
if (h->s)
2250-
prt_printf(out, "\tidx %llu blocks %u+%u allocated %u\n",
2251-
h->s->idx, h->s->nr_data, h->s->nr_parity,
2252-
bitmap_weight(h->s->blocks_allocated,
2253-
h->s->nr_data));
2270+
bch2_new_stripe_to_text(out, c, h->s);
22542271
}
22552272
mutex_unlock(&c->ec_stripe_head_lock);
22562273

22572274
prt_printf(out, "in flight:\n");
22582275

22592276
mutex_lock(&c->ec_stripe_new_lock);
2260-
list_for_each_entry(s, &c->ec_stripe_new_list, list) {
2261-
prt_printf(out, "\tidx %llu blocks %u+%u ref %u %u %s\n",
2262-
s->idx, s->nr_data, s->nr_parity,
2263-
atomic_read(&s->ref[STRIPE_REF_io]),
2264-
atomic_read(&s->ref[STRIPE_REF_stripe]),
2265-
bch2_watermarks[s->h->watermark]);
2266-
}
2277+
list_for_each_entry(s, &c->ec_stripe_new_list, list)
2278+
bch2_new_stripe_to_text(out, c, s);
22672279
mutex_unlock(&c->ec_stripe_new_lock);
22682280
}
22692281

fs/bcachefs/io_misc.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,7 @@ int bch2_extent_fallocate(struct btree_trans *trans,
126126

127127
if (closure_nr_remaining(&cl) != 1) {
128128
bch2_trans_unlock_long(trans);
129-
130-
if (closure_sync_timeout(&cl, HZ * 10)) {
131-
bch2_print_allocator_stuck(c);
132-
closure_sync(&cl);
133-
}
129+
bch2_wait_on_allocator(c, &cl);
134130
}
135131

136132
return ret;

fs/bcachefs/io_read.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ static void bch2_read_retry_nodecode(struct bch_fs *c, struct bch_read_bio *rbio
406406
bch2_trans_iter_init(trans, &iter, rbio->data_btree,
407407
rbio->read_pos, BTREE_ITER_slots);
408408
retry:
409+
bch2_trans_begin(trans);
409410
rbio->bio.bi_status = 0;
410411

411412
k = bch2_btree_iter_peek_slot(&iter);

0 commit comments

Comments
 (0)