mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-04-06 17:49:11 +03:00
Prevent arc_c collapse
Adjusting arc_c directly is racy because it can happen in the context
of multiple threads. It should always be >= 2 * maxblocksize. Set it
to a known valid value rather than adjusting it directly.
In addition refactor arc_shrink() to a simpler structure, protect against
underflow in the calculation of the new arc_c value.
Signed-off-by: Tim Chase <tim@chase2k.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reverts: 935434ef
Closes: #3904
Closes: #4161
This commit is contained in:
parent
957dc93242
commit
1b8951b319
@ -3183,13 +3183,10 @@ arc_flush(spa_t *spa, boolean_t retry)
|
|||||||
void
|
void
|
||||||
arc_shrink(int64_t to_free)
|
arc_shrink(int64_t to_free)
|
||||||
{
|
{
|
||||||
if (arc_c > arc_c_min) {
|
uint64_t c = arc_c;
|
||||||
|
|
||||||
if (arc_c > arc_c_min + to_free)
|
|
||||||
atomic_add_64(&arc_c, -to_free);
|
|
||||||
else
|
|
||||||
arc_c = arc_c_min;
|
|
||||||
|
|
||||||
|
if (c > to_free && c - to_free > arc_c_min) {
|
||||||
|
arc_c = c - to_free;
|
||||||
atomic_add_64(&arc_p, -(arc_p >> arc_shrink_shift));
|
atomic_add_64(&arc_p, -(arc_p >> arc_shrink_shift));
|
||||||
if (arc_c > arc_size)
|
if (arc_c > arc_size)
|
||||||
arc_c = MAX(arc_size, arc_c_min);
|
arc_c = MAX(arc_size, arc_c_min);
|
||||||
@ -3197,6 +3194,8 @@ arc_shrink(int64_t to_free)
|
|||||||
arc_p = (arc_c >> 1);
|
arc_p = (arc_c >> 1);
|
||||||
ASSERT(arc_c >= arc_c_min);
|
ASSERT(arc_c >= arc_c_min);
|
||||||
ASSERT((int64_t)arc_p >= 0);
|
ASSERT((int64_t)arc_p >= 0);
|
||||||
|
} else {
|
||||||
|
arc_c = arc_c_min;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arc_size > arc_c)
|
if (arc_size > arc_c)
|
||||||
@ -3767,7 +3766,6 @@ arc_adapt(int bytes, arc_state_t *state)
|
|||||||
* cache size, increment the target cache size
|
* cache size, increment the target cache size
|
||||||
*/
|
*/
|
||||||
ASSERT3U(arc_c, >=, 2ULL << SPA_MAXBLOCKSHIFT);
|
ASSERT3U(arc_c, >=, 2ULL << SPA_MAXBLOCKSHIFT);
|
||||||
arc_c = MAX(arc_c, 2ULL << SPA_MAXBLOCKSHIFT);
|
|
||||||
if (arc_size >= arc_c - (2ULL << SPA_MAXBLOCKSHIFT)) {
|
if (arc_size >= arc_c - (2ULL << SPA_MAXBLOCKSHIFT)) {
|
||||||
atomic_add_64(&arc_c, (int64_t)bytes);
|
atomic_add_64(&arc_c, (int64_t)bytes);
|
||||||
if (arc_c > arc_c_max)
|
if (arc_c > arc_c_max)
|
||||||
@ -5160,7 +5158,9 @@ arc_tempreserve_space(uint64_t reserve, uint64_t txg)
|
|||||||
int error;
|
int error;
|
||||||
uint64_t anon_size;
|
uint64_t anon_size;
|
||||||
|
|
||||||
if (reserve > arc_c/4 && !arc_no_grow)
|
if (!arc_no_grow &&
|
||||||
|
reserve > arc_c/4 &&
|
||||||
|
reserve * 4 > (2ULL << SPA_MAXBLOCKSHIFT))
|
||||||
arc_c = MIN(arc_c_max, reserve * 4);
|
arc_c = MIN(arc_c_max, reserve * 4);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user