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 <mjguzik@gmail.com>
This commit is contained in:
parent
eee1810861
commit
7acd62b609
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue