From 9b6e27755507b9bb47a1d7b4aede6302a876a14d Mon Sep 17 00:00:00 2001 From: Serguei Smirnov Date: Thu, 20 Jan 2022 08:40:28 -0800 Subject: [PATCH] LU-14676 lnet: improve hash distribution across CPTs Change the nid-to-cpt allocation function to use (sum-by-multiplication of nid bytes) mod (number of CPTs) to match nid to a CPT. This patch only addresses IPV4 nids. Make the matching change for the nid-to-cpt function used by the 'lnetctl cpt-of-nid' utility. Test-parameters: trivial testlist=sanity-lnet Signed-off-by: Serguei Smirnov Change-Id: I1052414947c4cae8c63993ffa21f67cb389bb463 Reviewed-on: https://review.whamcloud.com/46233 Reviewed-by: Cyril Bordage Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lnet/lnet/api-ni.c | 23 ++++++++++++----------- lnet/utils/lnetconfig/liblnetconfig.c | 19 +++++++------------ 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index e2ec63f..ad990de 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -1520,20 +1520,21 @@ lnet_net_is_pref_rtr_locked(struct lnet_net *net, struct lnet_nid *rtr_nid) static unsigned int lnet_nid4_cpt_hash(lnet_nid_t nid, unsigned int number) { - __u64 key = nid; - unsigned int val; + __u64 key = nid; + __u64 pair_bits = 0x0001000100010001LLU; + __u64 mask = pair_bits * 0xFF; + __u64 pair_sum; - LASSERT(number >= 1 && number <= LNET_CPT_NUMBER); - - if (number == 1) - return 0; + /* Use (sum-by-multiplication of nid bytes) mod (number of CPTs) + * to match nid to a CPT. + */ + pair_sum = (key & mask) + ((key >> 8) & mask); + pair_sum = (pair_sum * pair_bits) >> 48; - val = hash_long(key, LNET_CPT_BITS); - /* NB: LNET_CP_NUMBER doesn't have to be PO2 */ - if (val < number) - return val; + CDEBUG(D_NET, "Match nid %s to cpt %u\n", + libcfs_nid2str(nid), (unsigned int)(pair_sum) % number); - return (unsigned int)(key + val + (val >> 1)) % number; + return (unsigned int)(pair_sum) % number; } unsigned int diff --git a/lnet/utils/lnetconfig/liblnetconfig.c b/lnet/utils/lnetconfig/liblnetconfig.c index 8db3f4d..9f0dabd 100644 --- a/lnet/utils/lnetconfig/liblnetconfig.c +++ b/lnet/utils/lnetconfig/liblnetconfig.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include "liblnd.h" #include @@ -3794,22 +3793,18 @@ out: unsigned int lnet_nid_cpt_hash(lnet_nid_t nid, long int number) { - __u64 key = nid; - unsigned int val; - int cpt_bits = 0; + __u64 key = nid; + __u64 pair_bits = 0x0001000100010001LLU; + __u64 mask = pair_bits * 0xFF; + __u64 pair_sum; if (number == 1) return 0; - while ((1 << cpt_bits) < number) - cpt_bits++; + pair_sum = (key & mask) + ((key >> 8) & mask); + pair_sum = (pair_sum * pair_bits) >> 48; - val = hash_long(key, cpt_bits); - /* NB: LNET_CP_NUMBER doesn't have to be PO2 */ - if (val < number) - return val; - - return (unsigned int)(key + val + (val >> 1)) % number; + return (unsigned int)(pair_sum) % number; } int lustre_lnet_calc_cpt_of_nid(char *nidc, long int ncpts) -- 1.8.3.1