aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2022-09-19 11:07:15 -0700
committerBrian Behlendorf <[email protected]>2022-09-22 12:59:41 -0700
commit223b04d23d6e84dfb6c983c46f69d5986625125c (patch)
tree29696c28679e279b6dc87b5a87c4a32caf7064f6 /module/zfs
parente506a0ce40bd777a84ba1de8ed40df2154f7afb1 (diff)
Revert "Reduce dbuf_find() lock contention"
This reverts commit 34dbc618f50cfcd392f90af80c140398c38cbcd1. While this change resolved the lock contention observed for certain workloads, it inadventantly reduced the maximum hash inserts/removes per second. This appears to be due to the slightly higher acquisition cost of a rwlock vs a mutex. Reviewed-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/dbuf.c26
-rw-r--r--module/zfs/dbuf_stats.c4
2 files changed, 15 insertions, 15 deletions
diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c
index 80cab8177..9e36afd31 100644
--- a/module/zfs/dbuf.c
+++ b/module/zfs/dbuf.c
@@ -339,18 +339,18 @@ dbuf_find(objset_t *os, uint64_t obj, uint8_t level, uint64_t blkid)
hv = dbuf_hash(os, obj, level, blkid);
idx = hv & h->hash_table_mask;
- rw_enter(DBUF_HASH_RWLOCK(h, idx), RW_READER);
+ mutex_enter(DBUF_HASH_MUTEX(h, idx));
for (db = h->hash_table[idx]; db != NULL; db = db->db_hash_next) {
if (DBUF_EQUAL(db, os, obj, level, blkid)) {
mutex_enter(&db->db_mtx);
if (db->db_state != DB_EVICTING) {
- rw_exit(DBUF_HASH_RWLOCK(h, idx));
+ mutex_exit(DBUF_HASH_MUTEX(h, idx));
return (db);
}
mutex_exit(&db->db_mtx);
}
}
- rw_exit(DBUF_HASH_RWLOCK(h, idx));
+ mutex_exit(DBUF_HASH_MUTEX(h, idx));
return (NULL);
}
@@ -393,13 +393,13 @@ dbuf_hash_insert(dmu_buf_impl_t *db)
hv = dbuf_hash(os, obj, level, blkid);
idx = hv & h->hash_table_mask;
- rw_enter(DBUF_HASH_RWLOCK(h, idx), RW_WRITER);
+ mutex_enter(DBUF_HASH_MUTEX(h, idx));
for (dbf = h->hash_table[idx], i = 0; dbf != NULL;
dbf = dbf->db_hash_next, i++) {
if (DBUF_EQUAL(dbf, os, obj, level, blkid)) {
mutex_enter(&dbf->db_mtx);
if (dbf->db_state != DB_EVICTING) {
- rw_exit(DBUF_HASH_RWLOCK(h, idx));
+ mutex_exit(DBUF_HASH_MUTEX(h, idx));
return (dbf);
}
mutex_exit(&dbf->db_mtx);
@@ -417,7 +417,7 @@ dbuf_hash_insert(dmu_buf_impl_t *db)
mutex_enter(&db->db_mtx);
db->db_hash_next = h->hash_table[idx];
h->hash_table[idx] = db;
- rw_exit(DBUF_HASH_RWLOCK(h, idx));
+ mutex_exit(DBUF_HASH_MUTEX(h, idx));
uint64_t he = atomic_inc_64_nv(&dbuf_stats.hash_elements.value.ui64);
DBUF_STAT_MAX(hash_elements_max, he);
@@ -474,13 +474,13 @@ dbuf_hash_remove(dmu_buf_impl_t *db)
/*
* We mustn't hold db_mtx to maintain lock ordering:
- * DBUF_HASH_RWLOCK > db_mtx.
+ * DBUF_HASH_MUTEX > db_mtx.
*/
ASSERT(zfs_refcount_is_zero(&db->db_holds));
ASSERT(db->db_state == DB_EVICTING);
ASSERT(!MUTEX_HELD(&db->db_mtx));
- rw_enter(DBUF_HASH_RWLOCK(h, idx), RW_WRITER);
+ mutex_enter(DBUF_HASH_MUTEX(h, idx));
dbp = &h->hash_table[idx];
while ((dbf = *dbp) != db) {
dbp = &dbf->db_hash_next;
@@ -491,7 +491,7 @@ dbuf_hash_remove(dmu_buf_impl_t *db)
if (h->hash_table[idx] &&
h->hash_table[idx]->db_hash_next == NULL)
DBUF_STAT_BUMPDOWN(hash_chains);
- rw_exit(DBUF_HASH_RWLOCK(h, idx));
+ mutex_exit(DBUF_HASH_MUTEX(h, idx));
atomic_dec_64(&dbuf_stats.hash_elements.value.ui64);
}
@@ -914,8 +914,8 @@ retry:
sizeof (dmu_buf_impl_t),
0, dbuf_cons, dbuf_dest, NULL, NULL, NULL, 0);
- for (i = 0; i < DBUF_RWLOCKS; i++)
- rw_init(&h->hash_rwlocks[i], NULL, RW_DEFAULT, NULL);
+ for (i = 0; i < DBUF_MUTEXES; i++)
+ mutex_init(&h->hash_mutexes[i], NULL, MUTEX_DEFAULT, NULL);
dbuf_stats_init(h);
@@ -981,8 +981,8 @@ dbuf_fini(void)
dbuf_stats_destroy();
- for (i = 0; i < DBUF_RWLOCKS; i++)
- rw_destroy(&h->hash_rwlocks[i]);
+ for (i = 0; i < DBUF_MUTEXES; i++)
+ mutex_destroy(&h->hash_mutexes[i]);
#if defined(_KERNEL)
/*
* Large allocations which do not require contiguous pages
diff --git a/module/zfs/dbuf_stats.c b/module/zfs/dbuf_stats.c
index 747fc337d..e5dc2df30 100644
--- a/module/zfs/dbuf_stats.c
+++ b/module/zfs/dbuf_stats.c
@@ -137,7 +137,7 @@ dbuf_stats_hash_table_data(char *buf, size_t size, void *data)
if (size)
buf[0] = 0;
- rw_enter(DBUF_HASH_RWLOCK(h, dsh->idx), RW_READER);
+ mutex_enter(DBUF_HASH_MUTEX(h, dsh->idx));
for (db = h->hash_table[dsh->idx]; db != NULL; db = db->db_hash_next) {
/*
* Returning ENOMEM will cause the data and header functions
@@ -158,7 +158,7 @@ dbuf_stats_hash_table_data(char *buf, size_t size, void *data)
mutex_exit(&db->db_mtx);
}
- rw_exit(DBUF_HASH_RWLOCK(h, dsh->idx));
+ mutex_exit(DBUF_HASH_MUTEX(h, dsh->idx));
return (error);
}