Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dmu_objset: replace dnode_hash impl with cityhash4 #16483

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/zstream/zstream_redup.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ static void
rdt_insert(redup_table_t *rdt,
uint64_t guid, uint64_t object, uint64_t offset, uint64_t stream_offset)
{
uint64_t ch = cityhash4(guid, object, offset, 0);
uint64_t ch = cityhash3(guid, object, offset);
uint64_t hashcode = BF64_GET(ch, 0, rdt->numhashbits);
redup_entry_t **rdepp;

Expand All @@ -152,7 +152,7 @@ rdt_lookup(redup_table_t *rdt,
uint64_t guid, uint64_t object, uint64_t offset,
uint64_t *stream_offsetp)
{
uint64_t ch = cityhash4(guid, object, offset, 0);
uint64_t ch = cityhash3(guid, object, offset);
uint64_t hashcode = BF64_GET(ch, 0, rdt->numhashbits);

for (redup_entry_t *rde = rdt->redup_hash_array[hashcode];
Expand Down
7 changes: 7 additions & 0 deletions include/cityhash.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
extern "C" {
#endif

/*
* Define 1/2/3-argument specialized versions of cityhash4, which can reduce
* instruction count (especially multiplication) on some 32-bit arches.
*/
_SYS_CITYHASH_H uint64_t cityhash1(uint64_t);
_SYS_CITYHASH_H uint64_t cityhash2(uint64_t, uint64_t);
_SYS_CITYHASH_H uint64_t cityhash3(uint64_t, uint64_t, uint64_t);
_SYS_CITYHASH_H uint64_t cityhash4(uint64_t, uint64_t, uint64_t, uint64_t);

#ifdef __cplusplus
Expand Down
18 changes: 18 additions & 0 deletions lib/libzfs/libzfs.abi
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@
<elf-symbol name='avl_update_lt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='avl_walk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='bookmark_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='cityhash1' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='cityhash2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='cityhash3' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='cityhash4' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='color_end' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='color_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
Expand Down Expand Up @@ -9241,6 +9244,21 @@
</function-decl>
</abi-instr>
<abi-instr address-size='64' path='module/zcommon/cityhash.c' language='LANG_C99'>
<function-decl name='cityhash1' mangled-name='cityhash1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cityhash1'>
<parameter type-id='9c313c2d' name='w'/>
<return type-id='9c313c2d'/>
</function-decl>
<function-decl name='cityhash2' mangled-name='cityhash2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cityhash2'>
<parameter type-id='9c313c2d' name='w1'/>
<parameter type-id='9c313c2d' name='w2'/>
<return type-id='9c313c2d'/>
</function-decl>
<function-decl name='cityhash3' mangled-name='cityhash3' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cityhash3'>
<parameter type-id='9c313c2d' name='w1'/>
<parameter type-id='9c313c2d' name='w2'/>
<parameter type-id='9c313c2d' name='w3'/>
<return type-id='9c313c2d'/>
</function-decl>
<function-decl name='cityhash4' mangled-name='cityhash4' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cityhash4'>
<parameter type-id='9c313c2d' name='w1'/>
<parameter type-id='9c313c2d' name='w2'/>
Expand Down
4 changes: 2 additions & 2 deletions module/os/linux/zfs/zvol_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -551,8 +551,8 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
blk_mq_hw_queue =
rq->q->queue_hw_ctx[rq->q->mq_map[rq->cpu]]->queue_num;
#endif
taskq_hash = cityhash4((uintptr_t)zv, offset >> ZVOL_TASKQ_OFFSET_SHIFT,
blk_mq_hw_queue, 0);
taskq_hash = cityhash3((uintptr_t)zv, offset >> ZVOL_TASKQ_OFFSET_SHIFT,
blk_mq_hw_queue);
tq_idx = taskq_hash % ztqs->tqs_cnt;

if (rw == WRITE) {
Expand Down
33 changes: 31 additions & 2 deletions module/zcommon/cityhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ cityhash_helper(uint64_t u, uint64_t v, uint64_t mul)
return (b);
}

uint64_t
cityhash4(uint64_t w1, uint64_t w2, uint64_t w3, uint64_t w4)
static inline uint64_t
cityhash_impl(uint64_t w1, uint64_t w2, uint64_t w3, uint64_t w4)
{
uint64_t mul = HASH_K2 + 64;
uint64_t a = w1 * HASH_K1;
Expand All @@ -59,9 +59,38 @@ cityhash4(uint64_t w1, uint64_t w2, uint64_t w3, uint64_t w4)
uint64_t d = w3 * HASH_K2;
return (cityhash_helper(rotate(a + b, 43) + rotate(c, 30) + d,
a + rotate(b + HASH_K2, 18) + c, mul));
}

/*
* Passing w as the 2nd argument could save one 64-bit multiplication.
*/
uint64_t
cityhash1(uint64_t w)
{
return (cityhash_impl(0, w, 0, 0));
}

uint64_t
cityhash2(uint64_t w1, uint64_t w2)
{
return (cityhash_impl(w1, w2, 0, 0));
}

uint64_t
cityhash3(uint64_t w1, uint64_t w2, uint64_t w3)
{
return (cityhash_impl(w1, w2, w3, 0));
}

uint64_t
cityhash4(uint64_t w1, uint64_t w2, uint64_t w3, uint64_t w4)
{
return (cityhash_impl(w1, w2, w3, w4));
}

#if defined(_KERNEL)
EXPORT_SYMBOL(cityhash1);
EXPORT_SYMBOL(cityhash2);
EXPORT_SYMBOL(cityhash3);
EXPORT_SYMBOL(cityhash4);
#endif
19 changes: 3 additions & 16 deletions module/zfs/dmu_objset.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "zfs_namecheck.h"
#include <sys/vdev_impl.h>
#include <sys/arc.h>
#include <cityhash.h>

/*
* Needed to close a window in dnode_move() that allows the objset to be freed
Expand Down Expand Up @@ -404,27 +405,13 @@ dmu_objset_byteswap(void *buf, size_t size)
}

/*
* The hash is a CRC-based hash of the objset_t pointer and the object number.
* Runs cityhash on the objset_t pointer and the object number.
*/
static uint64_t
dnode_hash(const objset_t *os, uint64_t obj)
{
uintptr_t osv = (uintptr_t)os;
uint64_t crc = -1ULL;

ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY);
/*
* The lower 11 bits of the pointer don't have much entropy, because
* the objset_t is more than 1KB long and so likely aligned to 2KB.
*/
crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ (osv >> 11)) & 0xFF];
crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ (obj >> 0)) & 0xFF];
crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ (obj >> 8)) & 0xFF];
crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ (obj >> 16)) & 0xFF];

crc ^= (osv>>14) ^ (obj>>24);

return (crc);
return (cityhash2((uint64_t)osv, obj));
}

static unsigned int
Expand Down
4 changes: 2 additions & 2 deletions module/zfs/zio.c
Original file line number Diff line number Diff line change
Expand Up @@ -4182,8 +4182,8 @@ zio_alloc_zil(spa_t *spa, objset_t *os, uint64_t txg, blkptr_t *new_bp,
* some parallelism.
*/
int flags = METASLAB_ZIL;
int allocator = (uint_t)cityhash4(0, 0, 0,
os->os_dsl_dataset->ds_object) % spa->spa_alloc_count;
int allocator = (uint_t)cityhash1(os->os_dsl_dataset->ds_object)
% spa->spa_alloc_count;
error = metaslab_alloc(spa, spa_log_class(spa), size, new_bp, 1,
txg, NULL, flags, &io_alloc_list, NULL, allocator);
*slog = (error == 0);
Expand Down
Loading