From cbd8f5b759a7903a04aa38d858bb36f5dac19cb5 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 5 Feb 2020 14:08:44 -0500 Subject: Few microoptimizations to dbuf layer Move db_link into the same cache line as db_blkid and db_level. It allows significantly reduce avl_add() time in dbuf_create() on systems with large RAM and huge number of dbufs per dnode. Avoid few accesses to dbuf_caches[].size, which is highly congested under high IOPS and never stays in cache for a long time. Use local value we are receiving from zfs_refcount_add_many() any way. Remove cache_size_bytes_max bump from dbuf_evict_one(). I don't see a point to do it on dbuf eviction after we done it on insertion in dbuf_rele_and_unlock(). Reviewed-by: Matt Ahrens Reviewed-by: Brian Behlendorf Signed-off-by: Alexander Motin Sponsored-By: iXsystems, Inc. Closes #9931 --- module/zfs/dbuf.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) (limited to 'module/zfs') diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 27586daa2..04fc2f7cd 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -627,13 +627,6 @@ dbuf_cache_lowater_bytes(void) (dbuf_cache_target * dbuf_cache_lowater_pct) / 100); } -static inline boolean_t -dbuf_cache_above_hiwater(void) -{ - return (zfs_refcount_count(&dbuf_caches[DB_DBUF_CACHE].size) > - dbuf_cache_hiwater_bytes()); -} - static inline boolean_t dbuf_cache_above_lowater(void) { @@ -673,8 +666,6 @@ dbuf_evict_one(void) ASSERT3U(db->db_caching_status, ==, DB_DBUF_CACHE); db->db_caching_status = DB_NO_CACHE; dbuf_destroy(db); - DBUF_STAT_MAX(cache_size_bytes_max, - zfs_refcount_count(&dbuf_caches[DB_DBUF_CACHE].size)); DBUF_STAT_BUMP(cache_total_evicts); } else { multilist_sublist_unlock(mls); @@ -730,16 +721,15 @@ dbuf_evict_thread(void *unused) * dbuf cache using the callers context. */ static void -dbuf_evict_notify(void) +dbuf_evict_notify(uint64_t size) { /* * We check if we should evict without holding the dbuf_evict_lock, * because it's OK to occasionally make the wrong decision here, * and grabbing the lock results in massive lock contention. */ - if (zfs_refcount_count(&dbuf_caches[DB_DBUF_CACHE].size) > - dbuf_cache_target_bytes()) { - if (dbuf_cache_above_hiwater()) + if (size > dbuf_cache_target_bytes()) { + if (size > dbuf_cache_hiwater_bytes()) dbuf_evict_one(); cv_signal(&dbuf_evict_cv); } @@ -3471,6 +3461,7 @@ void dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag, boolean_t evicting) { int64_t holds; + uint64_t size; ASSERT(MUTEX_HELD(&db->db_mtx)); DBUF_VERIFY(db); @@ -3567,7 +3558,7 @@ dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag, boolean_t evicting) db->db_caching_status = dcs; multilist_insert(dbuf_caches[dcs].cache, db); - (void) zfs_refcount_add_many( + size = zfs_refcount_add_many( &dbuf_caches[dcs].size, db->db.db_size, db); @@ -3575,8 +3566,7 @@ dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag, boolean_t evicting) DBUF_STAT_BUMP(metadata_cache_count); DBUF_STAT_MAX( metadata_cache_size_bytes_max, - zfs_refcount_count( - &dbuf_caches[dcs].size)); + size); } else { DBUF_STAT_BUMP( cache_levels[db->db_level]); @@ -3585,15 +3575,12 @@ dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag, boolean_t evicting) cache_levels_bytes[db->db_level], db->db.db_size); DBUF_STAT_MAX(cache_size_bytes_max, - zfs_refcount_count( - &dbuf_caches[dcs].size)); + size); } mutex_exit(&db->db_mtx); - if (db->db_caching_status == DB_DBUF_CACHE && - !evicting) { - dbuf_evict_notify(); - } + if (dcs == DB_DBUF_CACHE && !evicting) + dbuf_evict_notify(size); } if (do_arc_evict) -- cgit v1.2.3