diff options
author | Alexander Motin <[email protected]> | 2023-06-14 11:02:27 -0400 |
---|---|---|
committer | GitHub <[email protected]> | 2023-06-14 08:02:27 -0700 |
commit | d057807ede05ce809e9ba1e2b47b12ada0d3b2ed (patch) | |
tree | 566bd7ea8eabce878a9fe85fecc0b9053cbdd61f /include/sys/zfs_refcount.h | |
parent | 8af1104f83eb44501b83218ed456e2d4b0ac3521 (diff) |
Switch refcount tracking from lists to AVL-trees.
With large number of tracked references list searches under the lock
become too expensive, creating enormous lock contention.
On my tests with ZFS_DEBUG enabled this increases write throughput
with 32KB blocks from ~1.2GB/s to ~7.5GB/s.
Reviewed-by: Brian Atkinson <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Alexander Motin <[email protected]>
Sponsored by: iXsystems, Inc.
Closes #14970
Diffstat (limited to 'include/sys/zfs_refcount.h')
-rw-r--r-- | include/sys/zfs_refcount.h | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/include/sys/zfs_refcount.h b/include/sys/zfs_refcount.h index 4efa266a5..77965a0aa 100644 --- a/include/sys/zfs_refcount.h +++ b/include/sys/zfs_refcount.h @@ -27,6 +27,7 @@ #define _SYS_ZFS_REFCOUNT_H #include <sys/inttypes.h> +#include <sys/avl.h> #include <sys/list.h> #include <sys/zfs_context.h> @@ -43,19 +44,22 @@ extern "C" { #ifdef ZFS_DEBUG typedef struct reference { - list_node_t ref_link; + union { + avl_node_t a; + list_node_t l; + } ref_link; const void *ref_holder; uint64_t ref_number; - uint8_t *ref_removed; + boolean_t ref_search; } reference_t; typedef struct refcount { + uint64_t rc_count; kmutex_t rc_mtx; - boolean_t rc_tracked; - list_t rc_list; + avl_tree_t rc_tree; list_t rc_removed; - uint64_t rc_count; - uint64_t rc_removed_count; + uint_t rc_removed_count; + boolean_t rc_tracked; } zfs_refcount_t; /* |