Skip to content

Commit 4d841a1

Browse files
committed
ARC: Avoid overflows in arc_evict_adj()
With certain combinations of target ARC states balance and ghost hit rates it was possible to get the fractions outside of allowed range. This patch limits maximum balance adjustment speed, which should make it impossible, and also asserts it. Fixes openzfs#17210
1 parent ba03054 commit 4d841a1

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

module/zfs/arc.c

+10-5
Original file line numberDiff line numberDiff line change
@@ -4225,15 +4225,17 @@ static uint64_t
42254225
arc_evict_adj(uint64_t frac, uint64_t total, uint64_t up, uint64_t down,
42264226
uint_t balance)
42274227
{
4228-
if (total < 8 || up + down == 0)
4228+
if (total < 32 || up + down == 0)
42294229
return (frac);
42304230

42314231
/*
4232-
* We should not have more ghost hits than ghost size, but they
4233-
* may get close. Restrict maximum adjustment in that case.
4232+
* We should not have more ghost hits than ghost size, but they may
4233+
* get close. To avoid overflows below up/down should not be bigger
4234+
* than 1/5 of total. But to limit maximum adjustment speed restrict
4235+
* it some more.
42344236
*/
4235-
if (up + down >= total / 4) {
4236-
uint64_t scale = (up + down) / (total / 8);
4237+
if (up + down >= total / 16) {
4238+
uint64_t scale = (up + down) / (total / 32);
42374239
up /= scale;
42384240
down /= scale;
42394241
}
@@ -4242,6 +4244,7 @@ arc_evict_adj(uint64_t frac, uint64_t total, uint64_t up, uint64_t down,
42424244
int s = highbit64(total);
42434245
s = MIN(64 - s, 32);
42444246

4247+
ASSERT3U(frac, <=, 1ULL << 32);
42454248
uint64_t ofrac = (1ULL << 32) - frac;
42464249

42474250
if (frac >= 4 * ofrac)
@@ -4252,6 +4255,8 @@ arc_evict_adj(uint64_t frac, uint64_t total, uint64_t up, uint64_t down,
42524255
down = (down << s) / (total >> (32 - s));
42534256
down = down * 100 / balance;
42544257

4258+
ASSERT3U(up, <=, (1ULL << 32) - frac);
4259+
ASSERT3U(down, <=, frac);
42554260
return (frac + up - down);
42564261
}
42574262

0 commit comments

Comments
 (0)