diff options
author | Jorgen Lundman <[email protected]> | 2021-07-02 00:28:15 +0900 |
---|---|---|
committer | GitHub <[email protected]> | 2021-07-01 09:28:15 -0600 |
commit | c6d1112bf4125e5a22eb47ceb7b8cee01f0df9a1 (patch) | |
tree | 5ed4fbdfee28b0a46163a346d32a1984773eb31f /module/os/freebsd/zfs/abd_os.c | |
parent | eca174527e0b8416550e6ce87c405702fd379ada (diff) |
Fix abd leak, kmem_free correct size of abd_t
Fix a leak of abd_t that manifested mostly when using
raidzN with at least as many columns as N (e.g. a
four-disk raidz2 but not a three-disk raidz2).
Sufficiently heavy raidz use would eventually run a system
out of memory.
Additionally:
* Switch abd_cache arena to FIRSTFIT, which empirically
improves perofrmance.
* Make abd_chunk_cache more performant and debuggable.
* Allocate the abd_zero_buf from abd_chunk_cache rather
than the heap.
* Don't try to reap non-existent qcaches in abd_cache arena.
* KM_PUSHPAGE->KM_SLEEP when allocating chunks from their
own arena
Reviewed-by: Matthew Ahrens <[email protected]>
Reviewed-by: Alexander Motin <[email protected]>
Signed-off-by: Jorgen Lundman <[email protected]>
Co-authored-by: Sean Doran <[email protected]>
Closes #12295
Diffstat (limited to 'module/os/freebsd/zfs/abd_os.c')
-rw-r--r-- | module/os/freebsd/zfs/abd_os.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/module/os/freebsd/zfs/abd_os.c b/module/os/freebsd/zfs/abd_os.c index 47adc2278..4f5b33d94 100644 --- a/module/os/freebsd/zfs/abd_os.c +++ b/module/os/freebsd/zfs/abd_os.c @@ -374,14 +374,17 @@ abd_alloc_for_io(size_t size, boolean_t is_metadata) } abd_t * -abd_get_offset_scatter(abd_t *abd, abd_t *sabd, size_t off) +abd_get_offset_scatter(abd_t *abd, abd_t *sabd, size_t off, + size_t size) { abd_verify(sabd); ASSERT3U(off, <=, sabd->abd_size); size_t new_offset = ABD_SCATTER(sabd).abd_offset + off; - uint_t chunkcnt = abd_scatter_chunkcnt(sabd) - - (new_offset / zfs_abd_chunk_size); + size_t chunkcnt = abd_chunkcnt_for_bytes( + (new_offset % zfs_abd_chunk_size) + size); + + ASSERT3U(chunkcnt, <=, abd_scatter_chunkcnt(sabd)); /* * If an abd struct is provided, it is only the minimum size. If we |