From 96a0c378c2e0a0c8f7e21404252e66944e163100 Mon Sep 17 00:00:00 2001 From: Mr NeilBrown Date: Mon, 9 Mar 2020 14:13:05 +1100 Subject: [PATCH] LU-10391 socklnd: factor out key calculation for ksnd_peers The hash_table library requires a "long" to be used as a key. We currently provide the nid, which at 64bits is a suitable long on 64bit hosts, but isn't really correct on 32bit hosts. When we change to an extend nid (which is 160bits) it will be even less appropriate. So create a separate function to compute a 'long' key, and implement by simply xoring 'long'-sized parts of the nid together. On a 64bit machine, this is currently optimized away for lnet_nid_t, but that will change when we convert to struct lnet_nid. This new function is placed in lnet-types.h as it will be more generally useful later. The hash_table library calls hash_long() on the key, so we don't need to do anything more interesting than xoring. Test-Parameters: trivial Test-Parameters: serverversion=2.12 serverdistro=el7.9 testlist=runtests Test-Parameters: clientversion=2.12 testlist=runtests Signed-off-by: Mr NeilBrown Change-Id: I22c59a87c9872bb59a2f47c2a8c57b287ed53ed3 Reviewed-on: https://review.whamcloud.com/42103 Tested-by: jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Chris Horn Reviewed-by: Serguei Smirnov Reviewed-by: Oleg Drokin --- lnet/include/uapi/linux/lnet/lnet-types.h | 10 ++++++++++ lnet/klnds/socklnd/socklnd.c | 17 +++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lnet/include/uapi/linux/lnet/lnet-types.h b/lnet/include/uapi/linux/lnet/lnet-types.h index f00d84f..da5b03c 100644 --- a/lnet/include/uapi/linux/lnet/lnet-types.h +++ b/lnet/include/uapi/linux/lnet/lnet-types.h @@ -158,6 +158,16 @@ static inline int nid_same(const struct lnet_nid *n1, n1->nid_addr[3] == n2->nid_addr[3]; } +/* This can be used when we need to hash a nid */ +static inline unsigned long nidhash(lnet_nid_t nid) +{ + unsigned long hash = 0; + + hash ^= LNET_NIDNET(nid); + hash ^= LNET_NIDADDR(nid); + return hash; +} + struct lnet_counters_health { __u32 lch_rst_alloc; __u32 lch_resend_count; diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c index 307e16c..ad93203 100644 --- a/lnet/klnds/socklnd/socklnd.c +++ b/lnet/klnds/socklnd/socklnd.c @@ -221,9 +221,10 @@ struct ksock_peer_ni * ksocknal_find_peer_locked(struct lnet_ni *ni, struct lnet_process_id id) { struct ksock_peer_ni *peer_ni; + unsigned long hash = nidhash(id.nid); hash_for_each_possible(ksocknal_data.ksnd_peers, peer_ni, - ksnp_list, id.nid) { + ksnp_list, hash) { LASSERT(!peer_ni->ksnp_closing); if (peer_ni->ksnp_ni != ni) @@ -598,7 +599,8 @@ ksocknal_add_peer(struct lnet_ni *ni, struct lnet_process_id id, peer_ni = peer2; } else { /* peer_ni table takes my ref on peer_ni */ - hash_add(ksocknal_data.ksnd_peers, &peer_ni->ksnp_list, id.nid); + hash_add(ksocknal_data.ksnd_peers, &peer_ni->ksnp_list, + nidhash(id.nid)); } ksocknal_add_conn_cb_locked(peer_ni, conn_cb); @@ -652,7 +654,8 @@ ksocknal_del_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ip) write_lock_bh(&ksocknal_data.ksnd_global_lock); if (id.nid != LNET_NID_ANY) { - lo = hash_min(id.nid, HASH_BITS(ksocknal_data.ksnd_peers)); + lo = hash_min(nidhash(id.nid), + HASH_BITS(ksocknal_data.ksnd_peers)); hi = lo; } else { lo = 0; @@ -924,7 +927,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_conn_cb *conn_cb, /* NB this puts an "empty" peer_ni in the peer_ni * table (which takes my ref) */ hash_add(ksocknal_data.ksnd_peers, - &peer_ni->ksnp_list, peerid.nid); + &peer_ni->ksnp_list, nidhash(peerid.nid)); } else { ksocknal_peer_decref(peer_ni); peer_ni = peer2; @@ -1544,7 +1547,8 @@ ksocknal_close_matching_conns(struct lnet_process_id id, __u32 ipaddr) write_lock_bh(&ksocknal_data.ksnd_global_lock); if (id.nid != LNET_NID_ANY) { - lo = hash_min(id.nid, HASH_BITS(ksocknal_data.ksnd_peers)); + lo = hash_min(nidhash(id.nid), + HASH_BITS(ksocknal_data.ksnd_peers)); hi = lo; } else { lo = 0; @@ -1638,7 +1642,8 @@ ksocknal_push(struct lnet_ni *ni, struct lnet_process_id id) int rc = -ENOENT; if (id.nid != LNET_NID_ANY) { - lo = hash_min(id.nid, HASH_BITS(ksocknal_data.ksnd_peers)); + lo = hash_min(nidhash(id.nid), + HASH_BITS(ksocknal_data.ksnd_peers)); hi = lo; } else { lo = 0; -- 1.8.3.1