summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGvozden Neskovic <neskovic@gmail.com>2019-04-23 18:51:53 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2019-04-26 19:13:48 +0000
commitc4ab0d3f46036e85ad0700125c5a83cc139f55a3 (patch)
treec8dcb815ca1e1c138f826852abce1200a291c372
parent95fa23b1c91c8660ef64ef5a20acfcd53961746e (diff)
downloadillumos-joyent-c4ab0d3f46036e85ad0700125c5a83cc139f55a3.tar.gz
10809 Performance optimization of AVL tree comparator functions
Portions contributed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Richard Elling <richard.elling@gmail.com> Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed by: Toomas Soome <tsoome@me.com> Reviewed by: Robert Mustacchi <rm@joyent.com> Approved by: Richard Lowe <richlowe@richlowe.net>
-rw-r--r--usr/src/lib/libzfs/common/libzfs_dataset.c8
-rw-r--r--usr/src/lib/libzfs/common/libzfs_iter.c7
-rw-r--r--usr/src/lib/libzfs/common/libzfs_sendrecv.c11
-rw-r--r--usr/src/lib/libzpool/common/sys/zfs_context.h8
-rw-r--r--usr/src/uts/common/fs/zfs/ddt.c27
-rw-r--r--usr/src/uts/common/fs/zfs/dnode.c26
-rw-r--r--usr/src/uts/common/fs/zfs/dsl_deadlist.c11
-rw-r--r--usr/src/uts/common/fs/zfs/dsl_deleg.c9
-rw-r--r--usr/src/uts/common/fs/zfs/lz4.c5
-rw-r--r--usr/src/uts/common/fs/zfs/metaslab.c38
-rw-r--r--usr/src/uts/common/fs/zfs/range_tree.c19
-rw-r--r--usr/src/uts/common/fs/zfs/sa.c28
-rw-r--r--usr/src/uts/common/fs/zfs/spa.c13
-rw-r--r--usr/src/uts/common/fs/zfs/spa_misc.c20
-rw-r--r--usr/src/uts/common/fs/zfs/space_reftree.c18
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zfs_context.h8
-rw-r--r--usr/src/uts/common/fs/zfs/unique.c12
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_cache.c25
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_label.c16
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_queue.c34
-rw-r--r--usr/src/uts/common/fs/zfs/zap_micro.c14
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_fuid.c19
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_rlock.c12
-rw-r--r--usr/src/uts/common/fs/zfs/zil.c28
-rw-r--r--usr/src/uts/common/sys/avl.h7
25 files changed, 163 insertions, 260 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c
index 662e207eea..1b2bf860e2 100644
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c
@@ -774,15 +774,13 @@ typedef struct mnttab_node {
static int
libzfs_mnttab_cache_compare(const void *arg1, const void *arg2)
{
- const mnttab_node_t *mtn1 = arg1;
- const mnttab_node_t *mtn2 = arg2;
+ const mnttab_node_t *mtn1 = (const mnttab_node_t *)arg1;
+ const mnttab_node_t *mtn2 = (const mnttab_node_t *)arg2;
int rv;
rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special);
- if (rv == 0)
- return (0);
- return (rv > 0 ? 1 : -1);
+ return (AVL_ISIGN(rv));
}
void
diff --git a/usr/src/lib/libzfs/common/libzfs_iter.c b/usr/src/lib/libzfs/common/libzfs_iter.c
index b0cb1ff186..bdef9757ef 100644
--- a/usr/src/lib/libzfs/common/libzfs_iter.c
+++ b/usr/src/lib/libzfs/common/libzfs_iter.c
@@ -272,12 +272,7 @@ zfs_snapshot_compare(const void *larg, const void *rarg)
lcreate = zfs_prop_get_int(l, ZFS_PROP_CREATETXG);
rcreate = zfs_prop_get_int(r, ZFS_PROP_CREATETXG);
- if (lcreate < rcreate)
- return (-1);
- else if (lcreate > rcreate)
- return (+1);
- else
- return (0);
+ return (AVL_CMP(lcreate, rcreate));
}
int
diff --git a/usr/src/lib/libzfs/common/libzfs_sendrecv.c b/usr/src/lib/libzfs/common/libzfs_sendrecv.c
index e56aa7f7c1..7ed81fd0d1 100644
--- a/usr/src/lib/libzfs/common/libzfs_sendrecv.c
+++ b/usr/src/lib/libzfs/common/libzfs_sendrecv.c
@@ -482,15 +482,10 @@ typedef struct fsavl_node {
static int
fsavl_compare(const void *arg1, const void *arg2)
{
- const fsavl_node_t *fn1 = arg1;
- const fsavl_node_t *fn2 = arg2;
+ const fsavl_node_t *fn1 = (const fsavl_node_t *)arg1;
+ const fsavl_node_t *fn2 = (const fsavl_node_t *)arg2;
- if (fn1->fn_guid > fn2->fn_guid)
- return (+1);
- else if (fn1->fn_guid < fn2->fn_guid)
- return (-1);
- else
- return (0);
+ return (AVL_CMP(fn1->fn_guid, fn2->fn_guid));
}
/*
diff --git a/usr/src/lib/libzpool/common/sys/zfs_context.h b/usr/src/lib/libzpool/common/sys/zfs_context.h
index d1dce80196..8612aefb0f 100644
--- a/usr/src/lib/libzpool/common/sys/zfs_context.h
+++ b/usr/src/lib/libzpool/common/sys/zfs_context.h
@@ -285,6 +285,14 @@ extern vnode_t *rootdir;
#define minclsyspri 60
#define maxclsyspri 99
+#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
+#define _zfs_expect(expr, value) (__builtin_expect((expr), (value)))
+#else
+#define _zfs_expect(expr, value) (expr)
+#endif
+
+#define likely(x) _zfs_expect((x) != 0, 1)
+
#define CPU_SEQID (thr_self() & (max_ncpus - 1))
extern void kernel_init(int);
diff --git a/usr/src/uts/common/fs/zfs/ddt.c b/usr/src/uts/common/fs/zfs/ddt.c
index 06c51fe05b..963ecbd58f 100644
--- a/usr/src/uts/common/fs/zfs/ddt.c
+++ b/usr/src/uts/common/fs/zfs/ddt.c
@@ -755,22 +755,31 @@ ddt_prefetch(spa_t *spa, const blkptr_t *bp)
}
}
+/*
+ * Opaque struct used for ddt_key comparison
+ */
+#define DDT_KEY_CMP_LEN (sizeof (ddt_key_t) / sizeof (uint16_t))
+
+typedef struct ddt_key_cmp {
+ uint16_t u16[DDT_KEY_CMP_LEN];
+} ddt_key_cmp_t;
+
int
ddt_entry_compare(const void *x1, const void *x2)
{
const ddt_entry_t *dde1 = x1;
const ddt_entry_t *dde2 = x2;
- const uint64_t *u1 = (const uint64_t *)&dde1->dde_key;
- const uint64_t *u2 = (const uint64_t *)&dde2->dde_key;
-
- for (int i = 0; i < DDT_KEY_WORDS; i++) {
- if (u1[i] < u2[i])
- return (-1);
- if (u1[i] > u2[i])
- return (1);
+ const ddt_key_cmp_t *k1 = (const ddt_key_cmp_t *)&dde1->dde_key;
+ const ddt_key_cmp_t *k2 = (const ddt_key_cmp_t *)&dde2->dde_key;
+ int32_t cmp = 0;
+
+ for (int i = 0; i < DDT_KEY_CMP_LEN; i++) {
+ cmp = (int32_t)k1->u16[i] - (int32_t)k2->u16[i];
+ if (likely(cmp))
+ break;
}
- return (0);
+ return (AVL_ISIGN(cmp));
}
static ddt_t *
diff --git a/usr/src/uts/common/fs/zfs/dnode.c b/usr/src/uts/common/fs/zfs/dnode.c
index 2f9e188454..f360eb997e 100644
--- a/usr/src/uts/common/fs/zfs/dnode.c
+++ b/usr/src/uts/common/fs/zfs/dnode.c
@@ -90,19 +90,13 @@ dbuf_compare(const void *x1, const void *x2)
const dmu_buf_impl_t *d1 = x1;
const dmu_buf_impl_t *d2 = x2;
- if (d1->db_level < d2->db_level) {
- return (-1);
- }
- if (d1->db_level > d2->db_level) {
- return (1);
- }
+ int cmp = AVL_CMP(d1->db_level, d2->db_level);
+ if (likely(cmp))
+ return (cmp);
- if (d1->db_blkid < d2->db_blkid) {
- return (-1);
- }
- if (d1->db_blkid > d2->db_blkid) {
- return (1);
- }
+ cmp = AVL_CMP(d1->db_blkid, d2->db_blkid);
+ if (likely(cmp))
+ return (cmp);
if (d1->db_state == DB_SEARCH) {
ASSERT3S(d2->db_state, !=, DB_SEARCH);
@@ -112,13 +106,7 @@ dbuf_compare(const void *x1, const void *x2)
return (1);
}
- if ((uintptr_t)d1 < (uintptr_t)d2) {
- return (-1);
- }
- if ((uintptr_t)d1 > (uintptr_t)d2) {
- return (1);
- }
- return (0);
+ return (AVL_PCMP(d1, d2));
}
/* ARGSUSED */
diff --git a/usr/src/uts/common/fs/zfs/dsl_deadlist.c b/usr/src/uts/common/fs/zfs/dsl_deadlist.c
index 356e5b51c3..2f3647bc8e 100644
--- a/usr/src/uts/common/fs/zfs/dsl_deadlist.c
+++ b/usr/src/uts/common/fs/zfs/dsl_deadlist.c
@@ -55,15 +55,10 @@
static int
dsl_deadlist_compare(const void *arg1, const void *arg2)
{
- const dsl_deadlist_entry_t *dle1 = arg1;
- const dsl_deadlist_entry_t *dle2 = arg2;
+ const dsl_deadlist_entry_t *dle1 = (const dsl_deadlist_entry_t *)arg1;
+ const dsl_deadlist_entry_t *dle2 = (const dsl_deadlist_entry_t *)arg2;
- if (dle1->dle_mintxg < dle2->dle_mintxg)
- return (-1);
- else if (dle1->dle_mintxg > dle2->dle_mintxg)
- return (+1);
- else
- return (0);
+ return (AVL_CMP(dle1->dle_mintxg, dle2->dle_mintxg));
}
static void
diff --git a/usr/src/uts/common/fs/zfs/dsl_deleg.c b/usr/src/uts/common/fs/zfs/dsl_deleg.c
index b2f69045a6..e72c66ade6 100644
--- a/usr/src/uts/common/fs/zfs/dsl_deleg.c
+++ b/usr/src/uts/common/fs/zfs/dsl_deleg.c
@@ -384,14 +384,13 @@ typedef struct perm_set {
static int
perm_set_compare(const void *arg1, const void *arg2)
{
- const perm_set_t *node1 = arg1;
- const perm_set_t *node2 = arg2;
+ const perm_set_t *node1 = (const perm_set_t *)arg1;
+ const perm_set_t *node2 = (const perm_set_t *)arg2;
int val;
val = strcmp(node1->p_setname, node2->p_setname);
- if (val == 0)
- return (0);
- return (val > 0 ? 1 : -1);
+
+ return (AVL_ISIGN(val));
}
/*
diff --git a/usr/src/uts/common/fs/zfs/lz4.c b/usr/src/uts/common/fs/zfs/lz4.c
index 82a08939dc..6426ba67b2 100644
--- a/usr/src/uts/common/fs/zfs/lz4.c
+++ b/usr/src/uts/common/fs/zfs/lz4.c
@@ -284,8 +284,13 @@ lz4_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
#define expect(expr, value) (expr)
#endif
+#ifndef likely
#define likely(expr) expect((expr) != 0, 1)
+#endif
+
+#ifndef unlikely
#define unlikely(expr) expect((expr) != 0, 0)
+#endif
/* Basic types */
#if defined(_MSC_VER)
diff --git a/usr/src/uts/common/fs/zfs/metaslab.c b/usr/src/uts/common/fs/zfs/metaslab.c
index 1bd057de0c..0044f37964 100644
--- a/usr/src/uts/common/fs/zfs/metaslab.c
+++ b/usr/src/uts/common/fs/zfs/metaslab.c
@@ -453,8 +453,8 @@ metaslab_class_expandable_space(metaslab_class_t *mc)
static int
metaslab_compare(const void *x1, const void *x2)
{
- const metaslab_t *m1 = x1;
- const metaslab_t *m2 = x2;
+ const metaslab_t *m1 = (const metaslab_t *)x1;
+ const metaslab_t *m2 = (const metaslab_t *)x2;
int sort1 = 0;
int sort2 = 0;
@@ -480,22 +480,13 @@ metaslab_compare(const void *x1, const void *x2)
if (sort1 > sort2)
return (1);
- if (m1->ms_weight < m2->ms_weight)
- return (1);
- if (m1->ms_weight > m2->ms_weight)
- return (-1);
-
- /*
- * If the weights are identical, use the offset to force uniqueness.
- */
- if (m1->ms_start < m2->ms_start)
- return (-1);
- if (m1->ms_start > m2->ms_start)
- return (1);
+ int cmp = AVL_CMP(m2->ms_weight, m1->ms_weight);
+ if (likely(cmp))
+ return (cmp);
- ASSERT3P(m1, ==, m2);
+ IMPLY(AVL_CMP(m1->ms_start, m2->ms_start) == 0, m1 == m2);
- return (0);
+ return (AVL_CMP(m1->ms_start, m2->ms_start));
}
uint64_t
@@ -1130,18 +1121,11 @@ metaslab_rangesize_compare(const void *x1, const void *x2)
uint64_t rs_size1 = r1->rs_end - r1->rs_start;
uint64_t rs_size2 = r2->rs_end - r2->rs_start;
- if (rs_size1 < rs_size2)
- return (-1);
- if (rs_size1 > rs_size2)
- return (1);
-
- if (r1->rs_start < r2->rs_start)
- return (-1);
+ int cmp = AVL_CMP(rs_size1, rs_size2);
+ if (likely(cmp))
+ return (cmp);
- if (r1->rs_start > r2->rs_start)
- return (1);
-
- return (0);
+ return (AVL_CMP(r1->rs_start, r2->rs_start));
}
/*
diff --git a/usr/src/uts/common/fs/zfs/range_tree.c b/usr/src/uts/common/fs/zfs/range_tree.c
index c99d0e68fc..0a852a9c8d 100644
--- a/usr/src/uts/common/fs/zfs/range_tree.c
+++ b/usr/src/uts/common/fs/zfs/range_tree.c
@@ -109,20 +109,13 @@ range_tree_stat_decr(range_tree_t *rt, range_seg_t *rs)
static int
range_tree_seg_compare(const void *x1, const void *x2)
{
- const range_seg_t *r1 = x1;
- const range_seg_t *r2 = x2;
+ const range_seg_t *r1 = (const range_seg_t *)x1;
+ const range_seg_t *r2 = (const range_seg_t *)x2;
- if (r1->rs_start < r2->rs_start) {
- if (r1->rs_end > r2->rs_start)
- return (0);
- return (-1);
- }
- if (r1->rs_start > r2->rs_start) {
- if (r1->rs_start < r2->rs_end)
- return (0);
- return (1);
- }
- return (0);
+ ASSERT3U(r1->rs_start, <=, r1->rs_end);
+ ASSERT3U(r2->rs_start, <=, r2->rs_end);
+
+ return ((r1->rs_start >= r2->rs_end) - (r1->rs_end <= r2->rs_start));
}
range_tree_t *
diff --git a/usr/src/uts/common/fs/zfs/sa.c b/usr/src/uts/common/fs/zfs/sa.c
index d8cf42db5f..d3c0a3e8ef 100644
--- a/usr/src/uts/common/fs/zfs/sa.c
+++ b/usr/src/uts/common/fs/zfs/sa.c
@@ -243,31 +243,23 @@ sa_cache_fini(void)
static int
layout_num_compare(const void *arg1, const void *arg2)
{
- const sa_lot_t *node1 = arg1;
- const sa_lot_t *node2 = arg2;
+ const sa_lot_t *node1 = (const sa_lot_t *)arg1;
+ const sa_lot_t *node2 = (const sa_lot_t *)arg2;
- if (node1->lot_num > node2->lot_num)
- return (1);
- else if (node1->lot_num < node2->lot_num)
- return (-1);
- return (0);
+ return (AVL_CMP(node1->lot_num, node2->lot_num));
}
static int
layout_hash_compare(const void *arg1, const void *arg2)
{
- const sa_lot_t *node1 = arg1;
- const sa_lot_t *node2 = arg2;
+ const sa_lot_t *node1 = (const sa_lot_t *)arg1;
+ const sa_lot_t *node2 = (const sa_lot_t *)arg2;
- if (node1->lot_hash > node2->lot_hash)
- return (1);
- if (node1->lot_hash < node2->lot_hash)
- return (-1);
- if (node1->lot_instance > node2->lot_instance)
- return (1);
- if (node1->lot_instance < node2->lot_instance)
- return (-1);
- return (0);
+ int cmp = AVL_CMP(node1->lot_hash, node2->lot_hash);
+ if (likely(cmp))
+ return (cmp);
+
+ return (AVL_CMP(node1->lot_instance, node2->lot_instance));
}
boolean_t
diff --git a/usr/src/uts/common/fs/zfs/spa.c b/usr/src/uts/common/fs/zfs/spa.c
index 96fc30bf75..6348d133a9 100644
--- a/usr/src/uts/common/fs/zfs/spa.c
+++ b/usr/src/uts/common/fs/zfs/spa.c
@@ -900,19 +900,14 @@ spa_change_guid(spa_t *spa)
static int
spa_error_entry_compare(const void *a, const void *b)
{
- spa_error_entry_t *sa = (spa_error_entry_t *)a;
- spa_error_entry_t *sb = (spa_error_entry_t *)b;
+ const spa_error_entry_t *sa = (const spa_error_entry_t *)a;
+ const spa_error_entry_t *sb = (const spa_error_entry_t *)b;
int ret;
- ret = bcmp(&sa->se_bookmark, &sb->se_bookmark,
+ ret = memcmp(&sa->se_bookmark, &sb->se_bookmark,
sizeof (zbookmark_phys_t));
- if (ret < 0)
- return (-1);
- else if (ret > 0)
- return (1);
- else
- return (0);
+ return (AVL_ISIGN(ret));
}
/*
diff --git a/usr/src/uts/common/fs/zfs/spa_misc.c b/usr/src/uts/common/fs/zfs/spa_misc.c
index 45948c2a7a..9a80f89a8a 100644
--- a/usr/src/uts/common/fs/zfs/spa_misc.c
+++ b/usr/src/uts/common/fs/zfs/spa_misc.c
@@ -915,18 +915,13 @@ typedef struct spa_aux {
int aux_count;
} spa_aux_t;
-static int
+static inline int
spa_aux_compare(const void *a, const void *b)
{
- const spa_aux_t *sa = a;
- const spa_aux_t *sb = b;
+ const spa_aux_t *sa = (const spa_aux_t *)a;
+ const spa_aux_t *sb = (const spa_aux_t *)b;
- if (sa->aux_guid < sb->aux_guid)
- return (-1);
- else if (sa->aux_guid > sb->aux_guid)
- return (1);
- else
- return (0);
+ return (AVL_CMP(sa->aux_guid, sb->aux_guid));
}
void
@@ -1984,11 +1979,8 @@ spa_name_compare(const void *a1, const void *a2)
int s;
s = strcmp(s1->spa_name, s2->spa_name);
- if (s > 0)
- return (1);
- if (s < 0)
- return (-1);
- return (0);
+
+ return (AVL_ISIGN(s));
}
int
diff --git a/usr/src/uts/common/fs/zfs/space_reftree.c b/usr/src/uts/common/fs/zfs/space_reftree.c
index a866e65d54..aa289ba106 100644
--- a/usr/src/uts/common/fs/zfs/space_reftree.c
+++ b/usr/src/uts/common/fs/zfs/space_reftree.c
@@ -54,20 +54,14 @@
static int
space_reftree_compare(const void *x1, const void *x2)
{
- const space_ref_t *sr1 = x1;
- const space_ref_t *sr2 = x2;
+ const space_ref_t *sr1 = (const space_ref_t *)x1;
+ const space_ref_t *sr2 = (const space_ref_t *)x2;
- if (sr1->sr_offset < sr2->sr_offset)
- return (-1);
- if (sr1->sr_offset > sr2->sr_offset)
- return (1);
+ int cmp = AVL_CMP(sr1->sr_offset, sr2->sr_offset);
+ if (likely(cmp))
+ return (cmp);
- if (sr1 < sr2)
- return (-1);
- if (sr1 > sr2)
- return (1);
-
- return (0);
+ return (AVL_PCMP(sr1, sr2));
}
void
diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_context.h b/usr/src/uts/common/fs/zfs/sys/zfs_context.h
index 37de17b4a4..ebcdc7f111 100644
--- a/usr/src/uts/common/fs/zfs/sys/zfs_context.h
+++ b/usr/src/uts/common/fs/zfs/sys/zfs_context.h
@@ -73,6 +73,14 @@ extern "C" {
#include <sys/disp.h>
#include <sys/callo.h>
+#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
+#define _zfs_expect(expr, value) (__builtin_expect((expr), (value)))
+#else
+#define _zfs_expect(expr, value) (expr)
+#endif
+
+#define likely(x) _zfs_expect((x) != 0, 1)
+
#define CPU_SEQID (CPU->cpu_seqid)
#ifdef __cplusplus
diff --git a/usr/src/uts/common/fs/zfs/unique.c b/usr/src/uts/common/fs/zfs/unique.c
index fbe7b619a2..d33f451938 100644
--- a/usr/src/uts/common/fs/zfs/unique.c
+++ b/usr/src/uts/common/fs/zfs/unique.c
@@ -42,14 +42,10 @@ typedef struct unique {
static int
unique_compare(const void *a, const void *b)
{
- const unique_t *una = a;
- const unique_t *unb = b;
-
- if (una->un_value < unb->un_value)
- return (-1);
- if (una->un_value > unb->un_value)
- return (+1);
- return (0);
+ const unique_t *una = (const unique_t *)a;
+ const unique_t *unb = (const unique_t *)b;
+
+ return (AVL_CMP(una->un_value, unb->un_value));
}
void
diff --git a/usr/src/uts/common/fs/zfs/vdev_cache.c b/usr/src/uts/common/fs/zfs/vdev_cache.c
index 9b4755321d..34ae6d5270 100644
--- a/usr/src/uts/common/fs/zfs/vdev_cache.c
+++ b/usr/src/uts/common/fs/zfs/vdev_cache.c
@@ -105,29 +105,24 @@ static vdc_stats_t vdc_stats = {
#define VDCSTAT_BUMP(stat) atomic_inc_64(&vdc_stats.stat.value.ui64);
-static int
+static inline int
vdev_cache_offset_compare(const void *a1, const void *a2)
{
- const vdev_cache_entry_t *ve1 = a1;
- const vdev_cache_entry_t *ve2 = a2;
-
- if (ve1->ve_offset < ve2->ve_offset)
- return (-1);
- if (ve1->ve_offset > ve2->ve_offset)
- return (1);
- return (0);
+ const vdev_cache_entry_t *ve1 = (const vdev_cache_entry_t *)a1;
+ const vdev_cache_entry_t *ve2 = (const vdev_cache_entry_t *)a2;
+
+ return (AVL_CMP(ve1->ve_offset, ve2->ve_offset));
}
static int
vdev_cache_lastused_compare(const void *a1, const void *a2)
{
- const vdev_cache_entry_t *ve1 = a1;
- const vdev_cache_entry_t *ve2 = a2;
+ const vdev_cache_entry_t *ve1 = (const vdev_cache_entry_t *)a1;
+ const vdev_cache_entry_t *ve2 = (const vdev_cache_entry_t *)a2;
- if (ve1->ve_lastused < ve2->ve_lastused)
- return (-1);
- if (ve1->ve_lastused > ve2->ve_lastused)
- return (1);
+ int cmp = AVL_CMP(ve1->ve_lastused, ve2->ve_lastused);
+ if (likely(cmp))
+ return (cmp);
/*
* Among equally old entries, sort by offset to ensure uniqueness.
diff --git a/usr/src/uts/common/fs/zfs/vdev_label.c b/usr/src/uts/common/fs/zfs/vdev_label.c
index b11c528348..3c469ffe43 100644
--- a/usr/src/uts/common/fs/zfs/vdev_label.c
+++ b/usr/src/uts/common/fs/zfs/vdev_label.c
@@ -1013,19 +1013,13 @@ retry:
* among uberblocks with equal txg, choose the one with the latest timestamp.
*/
static int
-vdev_uberblock_compare(uberblock_t *ub1, uberblock_t *ub2)
+vdev_uberblock_compare(const uberblock_t *ub1, const uberblock_t *ub2)
{
- if (ub1->ub_txg < ub2->ub_txg)
- return (-1);
- if (ub1->ub_txg > ub2->ub_txg)
- return (1);
+ int cmp = AVL_CMP(ub1->ub_txg, ub2->ub_txg);
+ if (likely(cmp))
+ return (cmp);
- if (ub1->ub_timestamp < ub2->ub_timestamp)
- return (-1);
- if (ub1->ub_timestamp > ub2->ub_timestamp)
- return (1);
-
- return (0);
+ return (AVL_CMP(ub1->ub_timestamp, ub2->ub_timestamp));
}
struct ubl_cbdata {
diff --git a/usr/src/uts/common/fs/zfs/vdev_queue.c b/usr/src/uts/common/fs/zfs/vdev_queue.c
index f29f4eeb9d..dff83e3108 100644
--- a/usr/src/uts/common/fs/zfs/vdev_queue.c
+++ b/usr/src/uts/common/fs/zfs/vdev_queue.c
@@ -202,20 +202,15 @@ int zfs_vdev_def_queue_depth = 32;
int
vdev_queue_offset_compare(const void *x1, const void *x2)
{
- const zio_t *z1 = x1;
- const zio_t *z2 = x2;
+ const zio_t *z1 = (const zio_t *)x1;
+ const zio_t *z2 = (const zio_t *)x2;
- if (z1->io_offset < z2->io_offset)
- return (-1);
- if (z1->io_offset > z2->io_offset)
- return (1);
+ int cmp = AVL_CMP(z1->io_offset, z2->io_offset);
- if (z1 < z2)
- return (-1);
- if (z1 > z2)
- return (1);
+ if (likely(cmp))
+ return (cmp);
- return (0);
+ return (AVL_PCMP(z1, z2));
}
static inline avl_tree_t *
@@ -237,20 +232,15 @@ vdev_queue_type_tree(vdev_queue_t *vq, zio_type_t t)
int
vdev_queue_timestamp_compare(const void *x1, const void *x2)
{
- const zio_t *z1 = x1;
- const zio_t *z2 = x2;
+ const zio_t *z1 = (const zio_t *)x1;
+ const zio_t *z2 = (const zio_t *)x2;
- if (z1->io_timestamp < z2->io_timestamp)
- return (-1);
- if (z1->io_timestamp > z2->io_timestamp)
- return (1);
+ int cmp = AVL_CMP(z1->io_timestamp, z2->io_timestamp);
- if (z1 < z2)
- return (-1);
- if (z1 > z2)
- return (1);
+ if (likely(cmp))
+ return (cmp);
- return (0);
+ return (AVL_PCMP(z1, z2));
}
void
diff --git a/usr/src/uts/common/fs/zfs/zap_micro.c b/usr/src/uts/common/fs/zfs/zap_micro.c
index bb5da13ba1..48b0be6665 100644
--- a/usr/src/uts/common/fs/zfs/zap_micro.c
+++ b/usr/src/uts/common/fs/zfs/zap_micro.c
@@ -281,15 +281,11 @@ mze_compare(const void *arg1, const void *arg2)
const mzap_ent_t *mze1 = arg1;
const mzap_ent_t *mze2 = arg2;
- if (mze1->mze_hash > mze2->mze_hash)
- return (+1);
- if (mze1->mze_hash < mze2->mze_hash)
- return (-1);
- if (mze1->mze_cd > mze2->mze_cd)
- return (+1);
- if (mze1->mze_cd < mze2->mze_cd)
- return (-1);
- return (0);
+ int cmp = AVL_CMP(mze1->mze_hash, mze2->mze_hash);
+ if (likely(cmp))
+ return (cmp);
+
+ return (AVL_CMP(mze1->mze_cd, mze2->mze_cd));
}
static void
diff --git a/usr/src/uts/common/fs/zfs/zfs_fuid.c b/usr/src/uts/common/fs/zfs/zfs_fuid.c
index 6eb03c2c18..7877a97b49 100644
--- a/usr/src/uts/common/fs/zfs/zfs_fuid.c
+++ b/usr/src/uts/common/fs/zfs/zfs_fuid.c
@@ -71,14 +71,10 @@ static char *nulldomain = "";
static int
idx_compare(const void *arg1, const void *arg2)
{
- const fuid_domain_t *node1 = arg1;
- const fuid_domain_t *node2 = arg2;
+ const fuid_domain_t *node1 = (const fuid_domain_t *)arg1;
+ const fuid_domain_t *node2 = (const fuid_domain_t *)arg2;
- if (node1->f_idx < node2->f_idx)
- return (-1);
- else if (node1->f_idx > node2->f_idx)
- return (1);
- return (0);
+ return (AVL_CMP(node1->f_idx, node2->f_idx));
}
/*
@@ -87,14 +83,13 @@ idx_compare(const void *arg1, const void *arg2)
static int
domain_compare(const void *arg1, const void *arg2)
{
- const fuid_domain_t *node1 = arg1;
- const fuid_domain_t *node2 = arg2;
+ const fuid_domain_t *node1 = (const fuid_domain_t *)arg1;
+ const fuid_domain_t *node2 = (const fuid_domain_t *)arg2;
int val;
val = strcmp(node1->f_ksid->kd_name, node2->f_ksid->kd_name);
- if (val == 0)
- return (0);
- return (val > 0 ? 1 : -1);
+
+ return (AVL_ISIGN(val));
}
void
diff --git a/usr/src/uts/common/fs/zfs/zfs_rlock.c b/usr/src/uts/common/fs/zfs/zfs_rlock.c
index 4e80ab27cc..6c2f39bca3 100644
--- a/usr/src/uts/common/fs/zfs/zfs_rlock.c
+++ b/usr/src/uts/common/fs/zfs/zfs_rlock.c
@@ -106,14 +106,10 @@
static int
rangelock_compare(const void *arg1, const void *arg2)
{
- const locked_range_t *rl1 = arg1;
- const locked_range_t *rl2 = arg2;
-
- if (rl1->lr_offset > rl2->lr_offset)
- return (1);
- if (rl1->lr_offset < rl2->lr_offset)
- return (-1);
- return (0);
+ const locked_range_t *rl1 = (const locked_range_t *)arg1;
+ const locked_range_t *rl2 = (const locked_range_t *)arg2;
+
+ return (AVL_CMP(rl1->lr_offset, rl2->lr_offset));
}
/*
diff --git a/usr/src/uts/common/fs/zfs/zil.c b/usr/src/uts/common/fs/zfs/zil.c
index 64b2c5944b..546e4f3d1e 100644
--- a/usr/src/uts/common/fs/zfs/zil.c
+++ b/usr/src/uts/common/fs/zfs/zil.c
@@ -123,17 +123,11 @@ zil_bp_compare(const void *x1, const void *x2)
const dva_t *dva1 = &((zil_bp_node_t *)x1)->zn_dva;
const dva_t *dva2 = &((zil_bp_node_t *)x2)->zn_dva;
- if (DVA_GET_VDEV(dva1) < DVA_GET_VDEV(dva2))
- return (-1);
- if (DVA_GET_VDEV(dva1) > DVA_GET_VDEV(dva2))
- return (1);
-
- if (DVA_GET_OFFSET(dva1) < DVA_GET_OFFSET(dva2))
- return (-1);
- if (DVA_GET_OFFSET(dva1) > DVA_GET_OFFSET(dva2))
- return (1);
+ int cmp = AVL_CMP(DVA_GET_VDEV(dva1), DVA_GET_VDEV(dva2));
+ if (likely(cmp))
+ return (cmp);
- return (0);
+ return (AVL_CMP(DVA_GET_OFFSET(dva1), DVA_GET_OFFSET(dva2)));
}
static void
@@ -495,12 +489,7 @@ zil_lwb_vdev_compare(const void *x1, const void *x2)
const uint64_t v1 = ((zil_vdev_node_t *)x1)->zv_vdev;
const uint64_t v2 = ((zil_vdev_node_t *)x2)->zv_vdev;
- if (v1 < v2)
- return (-1);
- if (v1 > v2)
- return (1);
-
- return (0);
+ return (AVL_CMP(v1, v2));
}
static lwb_t *
@@ -1729,12 +1718,7 @@ zil_aitx_compare(const void *x1, const void *x2)
const uint64_t o1 = ((itx_async_node_t *)x1)->ia_foid;
const uint64_t o2 = ((itx_async_node_t *)x2)->ia_foid;
- if (o1 < o2)
- return (-1);
- if (o1 > o2)
- return (1);
-
- return (0);
+ return (AVL_CMP(o1, o2));
}
/*
diff --git a/usr/src/uts/common/sys/avl.h b/usr/src/uts/common/sys/avl.h
index cc4af828e6..ec2647a8bc 100644
--- a/usr/src/uts/common/sys/avl.h
+++ b/usr/src/uts/common/sys/avl.h
@@ -100,6 +100,13 @@ extern "C" {
* as is needed for any linked list implementation.
*/
+/*
+ * AVL comparator helpers
+ */
+#define AVL_ISIGN(a) (((a) > 0) - ((a) < 0))
+#define AVL_CMP(a, b) (((a) > (b)) - ((a) < (b)))
+#define AVL_PCMP(a, b) \
+ (((uintptr_t)(a) > (uintptr_t)(b)) - ((uintptr_t)(a) < (uintptr_t)(b)))
/*
* Type used for the root of the AVL tree.