aboutsummaryrefslogtreecommitdiffstats
path: root/include/sys/zfs_refcount.h
diff options
context:
space:
mode:
authorAlexander Motin <[email protected]>2023-06-14 11:02:27 -0400
committerGitHub <[email protected]>2023-06-14 08:02:27 -0700
commitd057807ede05ce809e9ba1e2b47b12ada0d3b2ed (patch)
tree566bd7ea8eabce878a9fe85fecc0b9053cbdd61f /include/sys/zfs_refcount.h
parent8af1104f83eb44501b83218ed456e2d4b0ac3521 (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.h16
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;
/*