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 <batkinson@lanl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <mav@FreeBSD.org>
Sponsored by:	iXsystems, Inc.
Closes #14970
This commit is contained in:
Alexander Motin
2023-06-14 11:02:27 -04:00
committed by GitHub
parent 8af1104f83
commit d057807ede
2 changed files with 110 additions and 97 deletions
+11 -7
View File
@@ -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 {
kmutex_t rc_mtx;
boolean_t rc_tracked;
list_t rc_list;
list_t rc_removed;
uint64_t rc_count;
uint64_t rc_removed_count;
kmutex_t rc_mtx;
avl_tree_t rc_tree;
list_t rc_removed;
uint_t rc_removed_count;
boolean_t rc_tracked;
} zfs_refcount_t;
/*