From 7acd62b609e5afb107fe29bc4ceceab52679b6f7 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Sat, 28 Oct 2023 05:37:24 +0000 Subject: [PATCH] Employ zfs_refcount_remove_unless_last in sa_idx_tab_rele This avoids taking the lock in the common case. This almost halves contention on z_hold_mtx as it avoids extending its hold time by not contending on sa_lock. Performance does not improve because contention shifts to other global-ish locks. Before: 108608922 (sx:zfsvfs->z_hold_mtx[i]) 15464416 (sleep mutex:vnode_list) 12455346 (sx:os->os_lock) 10792604 (sx:sa->sa_lock) 3888049 (sx:zfsvfs->z_znodes_lock) 2863341 (sleep mutex:struct mount mtx) 835414 (sx:dn->dn_mtx) After: 57594050 (sx:zfsvfs->z_hold_mtx[i]) 22089617 (sleep mutex:vnode_list) 12148265 (sx:zfsvfs->z_znodes_lock) 9537666 (sx:os->os_lock) 6833254 (sleep mutex:struct mount mtx) 1131875 (sx:sa->sa_lock) 437455 (sx:dn->dn_mtx) Signed-off-by: Mateusz Guzik --- module/zfs/sa.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/module/zfs/sa.c b/module/zfs/sa.c index f9daaabbed..edd50cd475 100644 --- a/module/zfs/sa.c +++ b/module/zfs/sa.c @@ -1325,6 +1325,9 @@ sa_idx_tab_rele(objset_t *os, void *arg) if (idx_tab == NULL) return; + if (zfs_refcount_remove_not_last(&idx_tab->sa_refcount, NULL)) + return; + mutex_enter(&sa->sa_lock); if (zfs_refcount_remove(&idx_tab->sa_refcount, NULL) == 0) { list_remove(&idx_tab->sa_layout->lot_idx_tab, idx_tab);