Skip to content

Commit

Permalink
bcachefs: bch2_get_random_u64_below()
Browse files Browse the repository at this point in the history
steal the (clever) algorithm from get_random_u32_below()

this fixes a bug where we were passing roundup_pow_of_two() a 64 bit
number - we're squaring device latencies now:

[  +1.681698] ------------[ cut here ]------------
[  +0.000010] UBSAN: shift-out-of-bounds in ./include/linux/log2.h:57:13
[  +0.000011] shift exponent 64 is too large for 64-bit type 'long unsigned int'
[  +0.000011] CPU: 1 UID: 0 PID: 196 Comm: kworker/u32:13 Not tainted 6.14.0-rc6-dave+ #10
[  +0.000012] Hardware name: ASUS System Product Name/PRIME B460I-PLUS, BIOS 1301 07/13/2021
[  +0.000005] Workqueue: events_unbound __bch2_read_endio [bcachefs]
[  +0.000354] Call Trace:
[  +0.000005]  <TASK>
[  +0.000007]  dump_stack_lvl+0x5d/0x80
[  +0.000018]  ubsan_epilogue+0x5/0x30
[  +0.000008]  __ubsan_handle_shift_out_of_bounds.cold+0x61/0xe6
[  +0.000011]  bch2_rand_range.cold+0x17/0x20 [bcachefs]
[  +0.000231]  bch2_bkey_pick_read_device+0x547/0x920 [bcachefs]
[  +0.000229]  __bch2_read_extent+0x1e4/0x18e0 [bcachefs]
[  +0.000241]  ? bch2_btree_iter_peek_slot+0x3df/0x800 [bcachefs]
[  +0.000180]  ? bch2_read_retry_nodecode+0x270/0x330 [bcachefs]
[  +0.000230]  bch2_read_retry_nodecode+0x270/0x330 [bcachefs]
[  +0.000230]  bch2_rbio_retry+0x1fa/0x600 [bcachefs]
[  +0.000224]  ? bch2_printbuf_make_room+0x71/0xb0 [bcachefs]
[  +0.000243]  ? bch2_read_csum_err+0x4a4/0x610 [bcachefs]
[  +0.000278]  bch2_read_csum_err+0x4a4/0x610 [bcachefs]
[  +0.000227]  ? __bch2_read_endio+0x58b/0x870 [bcachefs]
[  +0.000220]  __bch2_read_endio+0x58b/0x870 [bcachefs]
[  +0.000268]  ? try_to_wake_up+0x31c/0x7f0
[  +0.000011]  ? process_one_work+0x176/0x330
[  +0.000008]  process_one_work+0x176/0x330
[  +0.000008]  worker_thread+0x252/0x390
[  +0.000008]  ? __pfx_worker_thread+0x10/0x10
[  +0.000006]  kthread+0xec/0x230
[  +0.000011]  ? __pfx_kthread+0x10/0x10
[  +0.000009]  ret_from_fork+0x31/0x50
[  +0.000009]  ? __pfx_kthread+0x10/0x10
[  +0.000008]  ret_from_fork_asm+0x1a/0x30
[  +0.000012]  </TASK>
[  +0.000046] ---[ end trace ]---

Reported-by: Roland Vet <vet.roland@protonmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
  • Loading branch information
Kent Overstreet committed Mar 13, 2025
1 parent 69a5a13 commit 9c18ea7
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 11 deletions.
2 changes: 1 addition & 1 deletion fs/bcachefs/extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static inline bool ptr_better(struct bch_fs *c,

/* Pick at random, biased in favor of the faster device: */

return bch2_rand_range(l1 + l2) > l1;
return bch2_get_random_u64_below(l1 + l2) > l1;
}

if (bch2_force_reconstruct_read)
Expand Down
23 changes: 14 additions & 9 deletions fs/bcachefs/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,19 +653,24 @@ int bch2_bio_alloc_pages(struct bio *bio, size_t size, gfp_t gfp_mask)
return 0;
}

size_t bch2_rand_range(size_t max)
u64 bch2_get_random_u64_below(u64 ceil)
{
size_t rand;
if (ceil <= U32_MAX)
return __get_random_u32_below(ceil);

if (!max)
return 0;
/* this is the same (clever) algorithm as in __get_random_u32_below() */
u64 rand = get_random_u64();
u64 mult = ceil * rand;

do {
rand = get_random_long();
rand &= roundup_pow_of_two(max) - 1;
} while (rand >= max);
if (unlikely(mult < ceil)) {
u64 bound = -ceil % ceil;
while (unlikely(mult < bound)) {
rand = get_random_u64();
mult = ceil * rand;
}
}

return rand;
return mul_u64_u64_shr(ceil, rand, 64);
}

void memcpy_to_bio(struct bio *dst, struct bvec_iter dst_iter, const void *src)
Expand Down
2 changes: 1 addition & 1 deletion fs/bcachefs/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ do { \
_ret; \
})

size_t bch2_rand_range(size_t);
u64 bch2_get_random_u64_below(u64);

void memcpy_to_bio(struct bio *, struct bvec_iter, const void *);
void memcpy_from_bio(void *, struct bio *, struct bvec_iter);
Expand Down

0 comments on commit 9c18ea7

Please sign in to comment.