diff options
author | Mark Johnston <[email protected]> | 2022-01-21 13:28:13 -0500 |
---|---|---|
committer | GitHub <[email protected]> | 2022-01-21 10:28:13 -0800 |
commit | 6e2a59181e286a397d260fa9f140b58688d60c58 (patch) | |
tree | 4c449311dc31f332edc403d11aa8521d27ea25a3 /include | |
parent | bc40713a8f2e78ce8b4bdef587d5233d313f06f1 (diff) |
Avoid memory allocations in the ARC eviction thread
When the eviction thread goes to shrink an ARC state, it allocates a set
of marker buffers used to hold its place in the state's sublists.
This can be problematic in low memory conditions, since
1) the allocation can be substantial, as we allocate NCPU markers;
2) on at least FreeBSD, page reclamation can block in
arc_wait_for_eviction()
In particular, in stress tests it's possible to hit a deadlock on
FreeBSD when the number of free pages is very low, wherein the system is
waiting for the page daemon to reclaim memory, the page daemon is
waiting for the ARC eviction thread to finish, and the ARC eviction
thread is blocked waiting for more memory.
Try to reduce the likelihood of such deadlocks by pre-allocating markers
for the eviction thread at ARC initialization time. When evicting
buffers from an ARC state, check to see if the current thread is the ARC
eviction thread, and use the pre-allocated markers for that purpose
rather than dynamically allocating them.
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Alexander Motin <[email protected]>
Reviewed-by: George Amanakis <[email protected]>
Signed-off-by: Mark Johnston <[email protected]>
Closes #12985
Diffstat (limited to 'include')
-rw-r--r-- | include/sys/zthr.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/sys/zthr.h b/include/sys/zthr.h index 19be89eee..4881b4572 100644 --- a/include/sys/zthr.h +++ b/include/sys/zthr.h @@ -38,6 +38,7 @@ extern void zthr_resume(zthr_t *t); extern void zthr_wait_cycle_done(zthr_t *t); extern boolean_t zthr_iscancelled(zthr_t *t); +extern boolean_t zthr_iscurthread(zthr_t *t); extern boolean_t zthr_has_waiters(zthr_t *t); #endif /* _SYS_ZTHR_H */ |