diff --git a/include/sys/dbuf.h b/include/sys/dbuf.h index d221eac4c8..6ae079c6a6 100644 --- a/include/sys/dbuf.h +++ b/include/sys/dbuf.h @@ -322,12 +322,12 @@ typedef struct dmu_buf_impl { } dmu_buf_impl_t; /* Note: the dbuf hash table is exposed only for the mdb module */ -#define DBUF_MUTEXES 8192 +#define DBUF_MUTEXES 2048 #define DBUF_HASH_MUTEX(h, idx) (&(h)->hash_mutexes[(idx) & (DBUF_MUTEXES-1)]) typedef struct dbuf_hash_table { uint64_t hash_table_mask; dmu_buf_impl_t **hash_table; - kmutex_t hash_mutexes[DBUF_MUTEXES]; + kmutex_t hash_mutexes[DBUF_MUTEXES] ____cacheline_aligned; } dbuf_hash_table_t; typedef void (*dbuf_prefetch_fn)(void *, boolean_t); diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 3484fff3b4..394ca1bfe4 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -740,29 +740,18 @@ taskq_t *arc_prune_taskq; * Hash table routines */ -#define HT_LOCK_ALIGN 64 -#define HT_LOCK_PAD (P2NPHASE(sizeof (kmutex_t), (HT_LOCK_ALIGN))) - -struct ht_lock { - kmutex_t ht_lock; -#ifdef _KERNEL - unsigned char pad[HT_LOCK_PAD]; -#endif -}; - -#define BUF_LOCKS 8192 +#define BUF_LOCKS 2048 typedef struct buf_hash_table { uint64_t ht_mask; arc_buf_hdr_t **ht_table; - struct ht_lock ht_locks[BUF_LOCKS]; + kmutex_t ht_locks[BUF_LOCKS] ____cacheline_aligned; } buf_hash_table_t; static buf_hash_table_t buf_hash_table; #define BUF_HASH_INDEX(spa, dva, birth) \ (buf_hash(spa, dva, birth) & buf_hash_table.ht_mask) -#define BUF_HASH_LOCK_NTRY(idx) (buf_hash_table.ht_locks[idx & (BUF_LOCKS-1)]) -#define BUF_HASH_LOCK(idx) (&(BUF_HASH_LOCK_NTRY(idx).ht_lock)) +#define BUF_HASH_LOCK(idx) (&buf_hash_table.ht_locks[idx & (BUF_LOCKS-1)]) #define HDR_LOCK(hdr) \ (BUF_HASH_LOCK(BUF_HASH_INDEX(hdr->b_spa, &hdr->b_dva, hdr->b_birth))) @@ -1111,7 +1100,7 @@ buf_fini(void) (buf_hash_table.ht_mask + 1) * sizeof (void *)); #endif for (i = 0; i < BUF_LOCKS; i++) - mutex_destroy(&buf_hash_table.ht_locks[i].ht_lock); + mutex_destroy(BUF_HASH_LOCK(i)); kmem_cache_destroy(hdr_full_cache); kmem_cache_destroy(hdr_full_crypt_cache); kmem_cache_destroy(hdr_l2only_cache); @@ -1276,10 +1265,8 @@ retry: for (ct = zfs_crc64_table + i, *ct = i, j = 8; j > 0; j--) *ct = (*ct >> 1) ^ (-(*ct & 1) & ZFS_CRC64_POLY); - for (i = 0; i < BUF_LOCKS; i++) { - mutex_init(&buf_hash_table.ht_locks[i].ht_lock, - NULL, MUTEX_DEFAULT, NULL); - } + for (i = 0; i < BUF_LOCKS; i++) + mutex_init(BUF_HASH_LOCK(i), NULL, MUTEX_DEFAULT, NULL); } #define ARC_MINTIME (hz>>4) /* 62 ms */ diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 9ce091b80d..289247c6ed 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -826,12 +826,12 @@ dbuf_init(void) int i; /* - * The hash table is big enough to fill all of physical memory + * The hash table is big enough to fill one eighth of physical memory * with an average block size of zfs_arc_average_blocksize (default 8K). * By default, the table will take up * totalmem * sizeof(void*) / 8K (1MB per GB with 8-byte pointers). */ - while (hsize * zfs_arc_average_blocksize < physmem * PAGESIZE) + while (hsize * zfs_arc_average_blocksize < arc_all_memory() / 8) hsize <<= 1; retry: @@ -3055,8 +3055,8 @@ dbuf_create(dnode_t *dn, uint8_t level, uint64_t blkid, db->db_state = DB_EVICTING; /* not worth logging this state change */ if ((odb = dbuf_hash_insert(db)) != NULL) { /* someone else inserted it first */ - kmem_cache_free(dbuf_kmem_cache, db); mutex_exit(&dn->dn_dbufs_mtx); + kmem_cache_free(dbuf_kmem_cache, db); DBUF_STAT_BUMP(hash_insert_race); return (odb); }