Skip to content

Commit 917f13a

Browse files
amotinbehlendorf
authored andcommitted
Compact dbuf/buf hashes and lock arrays
With default dbuf cache size of 1/32 of ARC, it makes no sense to have hash table of the same size (or even bigger on Linux). Reduce it to 1/8 of ARC's one, still leaving some slack, assuming higher I/O rate via dbuf cache than via ARC. Remove padding from ARC hash locks array. The idea behind padding is to avoid false sharing between locks. It would have sense if there would be a limited number of very busy locks. But since we have no limit on the number, using the same memory for more locks we can achieve even lower lock contention with the same false sharing, or we can use less memory for the same contention level. Reduce number of hash locks from 8192 to 2048. The number is still big enough to not cause contention, but reduced memory size improves cache hit rate for mutex_tryenter() in ARC eviction thread, saving about 1% of the thread time. Reviewed-by: Matthew Ahrens <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Closes #12289
1 parent 802eff1 commit 917f13a

File tree

3 files changed

+11
-24
lines changed

3 files changed

+11
-24
lines changed

include/sys/dbuf.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,12 @@ typedef struct dmu_buf_impl {
322322
} dmu_buf_impl_t;
323323

324324
/* Note: the dbuf hash table is exposed only for the mdb module */
325-
#define DBUF_MUTEXES 8192
325+
#define DBUF_MUTEXES 2048
326326
#define DBUF_HASH_MUTEX(h, idx) (&(h)->hash_mutexes[(idx) & (DBUF_MUTEXES-1)])
327327
typedef struct dbuf_hash_table {
328328
uint64_t hash_table_mask;
329329
dmu_buf_impl_t **hash_table;
330-
kmutex_t hash_mutexes[DBUF_MUTEXES];
330+
kmutex_t hash_mutexes[DBUF_MUTEXES] ____cacheline_aligned;
331331
} dbuf_hash_table_t;
332332

333333
typedef void (*dbuf_prefetch_fn)(void *, boolean_t);

module/zfs/arc.c

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -740,29 +740,18 @@ taskq_t *arc_prune_taskq;
740740
* Hash table routines
741741
*/
742742

743-
#define HT_LOCK_ALIGN 64
744-
#define HT_LOCK_PAD (P2NPHASE(sizeof (kmutex_t), (HT_LOCK_ALIGN)))
745-
746-
struct ht_lock {
747-
kmutex_t ht_lock;
748-
#ifdef _KERNEL
749-
unsigned char pad[HT_LOCK_PAD];
750-
#endif
751-
};
752-
753-
#define BUF_LOCKS 8192
743+
#define BUF_LOCKS 2048
754744
typedef struct buf_hash_table {
755745
uint64_t ht_mask;
756746
arc_buf_hdr_t **ht_table;
757-
struct ht_lock ht_locks[BUF_LOCKS];
747+
kmutex_t ht_locks[BUF_LOCKS] ____cacheline_aligned;
758748
} buf_hash_table_t;
759749

760750
static buf_hash_table_t buf_hash_table;
761751

762752
#define BUF_HASH_INDEX(spa, dva, birth) \
763753
(buf_hash(spa, dva, birth) & buf_hash_table.ht_mask)
764-
#define BUF_HASH_LOCK_NTRY(idx) (buf_hash_table.ht_locks[idx & (BUF_LOCKS-1)])
765-
#define BUF_HASH_LOCK(idx) (&(BUF_HASH_LOCK_NTRY(idx).ht_lock))
754+
#define BUF_HASH_LOCK(idx) (&buf_hash_table.ht_locks[idx & (BUF_LOCKS-1)])
766755
#define HDR_LOCK(hdr) \
767756
(BUF_HASH_LOCK(BUF_HASH_INDEX(hdr->b_spa, &hdr->b_dva, hdr->b_birth)))
768757

@@ -1111,7 +1100,7 @@ buf_fini(void)
11111100
(buf_hash_table.ht_mask + 1) * sizeof (void *));
11121101
#endif
11131102
for (i = 0; i < BUF_LOCKS; i++)
1114-
mutex_destroy(&buf_hash_table.ht_locks[i].ht_lock);
1103+
mutex_destroy(BUF_HASH_LOCK(i));
11151104
kmem_cache_destroy(hdr_full_cache);
11161105
kmem_cache_destroy(hdr_full_crypt_cache);
11171106
kmem_cache_destroy(hdr_l2only_cache);
@@ -1276,10 +1265,8 @@ buf_init(void)
12761265
for (ct = zfs_crc64_table + i, *ct = i, j = 8; j > 0; j--)
12771266
*ct = (*ct >> 1) ^ (-(*ct & 1) & ZFS_CRC64_POLY);
12781267

1279-
for (i = 0; i < BUF_LOCKS; i++) {
1280-
mutex_init(&buf_hash_table.ht_locks[i].ht_lock,
1281-
NULL, MUTEX_DEFAULT, NULL);
1282-
}
1268+
for (i = 0; i < BUF_LOCKS; i++)
1269+
mutex_init(BUF_HASH_LOCK(i), NULL, MUTEX_DEFAULT, NULL);
12831270
}
12841271

12851272
#define ARC_MINTIME (hz>>4) /* 62 ms */

module/zfs/dbuf.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -826,12 +826,12 @@ dbuf_init(void)
826826
int i;
827827

828828
/*
829-
* The hash table is big enough to fill all of physical memory
829+
* The hash table is big enough to fill one eighth of physical memory
830830
* with an average block size of zfs_arc_average_blocksize (default 8K).
831831
* By default, the table will take up
832832
* totalmem * sizeof(void*) / 8K (1MB per GB with 8-byte pointers).
833833
*/
834-
while (hsize * zfs_arc_average_blocksize < physmem * PAGESIZE)
834+
while (hsize * zfs_arc_average_blocksize < arc_all_memory() / 8)
835835
hsize <<= 1;
836836

837837
retry:
@@ -3057,8 +3057,8 @@ dbuf_create(dnode_t *dn, uint8_t level, uint64_t blkid,
30573057
db->db_state = DB_EVICTING; /* not worth logging this state change */
30583058
if ((odb = dbuf_hash_insert(db)) != NULL) {
30593059
/* someone else inserted it first */
3060-
kmem_cache_free(dbuf_kmem_cache, db);
30613060
mutex_exit(&dn->dn_dbufs_mtx);
3061+
kmem_cache_free(dbuf_kmem_cache, db);
30623062
DBUF_STAT_BUMP(hash_insert_race);
30633063
return (odb);
30643064
}

0 commit comments

Comments
 (0)