162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#ifdef __KERNEL__ 362306a36Sopenharmony_ci# include <linux/crush/hash.h> 462306a36Sopenharmony_ci#else 562306a36Sopenharmony_ci# include "hash.h" 662306a36Sopenharmony_ci#endif 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci/* 962306a36Sopenharmony_ci * Robert Jenkins' function for mixing 32-bit values 1062306a36Sopenharmony_ci * https://burtleburtle.net/bob/hash/evahash.html 1162306a36Sopenharmony_ci * a, b = random bits, c = input and output 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci#define crush_hashmix(a, b, c) do { \ 1462306a36Sopenharmony_ci a = a-b; a = a-c; a = a^(c>>13); \ 1562306a36Sopenharmony_ci b = b-c; b = b-a; b = b^(a<<8); \ 1662306a36Sopenharmony_ci c = c-a; c = c-b; c = c^(b>>13); \ 1762306a36Sopenharmony_ci a = a-b; a = a-c; a = a^(c>>12); \ 1862306a36Sopenharmony_ci b = b-c; b = b-a; b = b^(a<<16); \ 1962306a36Sopenharmony_ci c = c-a; c = c-b; c = c^(b>>5); \ 2062306a36Sopenharmony_ci a = a-b; a = a-c; a = a^(c>>3); \ 2162306a36Sopenharmony_ci b = b-c; b = b-a; b = b^(a<<10); \ 2262306a36Sopenharmony_ci c = c-a; c = c-b; c = c^(b>>15); \ 2362306a36Sopenharmony_ci } while (0) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define crush_hash_seed 1315423911 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistatic __u32 crush_hash32_rjenkins1(__u32 a) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci __u32 hash = crush_hash_seed ^ a; 3062306a36Sopenharmony_ci __u32 b = a; 3162306a36Sopenharmony_ci __u32 x = 231232; 3262306a36Sopenharmony_ci __u32 y = 1232; 3362306a36Sopenharmony_ci crush_hashmix(b, x, hash); 3462306a36Sopenharmony_ci crush_hashmix(y, a, hash); 3562306a36Sopenharmony_ci return hash; 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic __u32 crush_hash32_rjenkins1_2(__u32 a, __u32 b) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci __u32 hash = crush_hash_seed ^ a ^ b; 4162306a36Sopenharmony_ci __u32 x = 231232; 4262306a36Sopenharmony_ci __u32 y = 1232; 4362306a36Sopenharmony_ci crush_hashmix(a, b, hash); 4462306a36Sopenharmony_ci crush_hashmix(x, a, hash); 4562306a36Sopenharmony_ci crush_hashmix(b, y, hash); 4662306a36Sopenharmony_ci return hash; 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic __u32 crush_hash32_rjenkins1_3(__u32 a, __u32 b, __u32 c) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci __u32 hash = crush_hash_seed ^ a ^ b ^ c; 5262306a36Sopenharmony_ci __u32 x = 231232; 5362306a36Sopenharmony_ci __u32 y = 1232; 5462306a36Sopenharmony_ci crush_hashmix(a, b, hash); 5562306a36Sopenharmony_ci crush_hashmix(c, x, hash); 5662306a36Sopenharmony_ci crush_hashmix(y, a, hash); 5762306a36Sopenharmony_ci crush_hashmix(b, x, hash); 5862306a36Sopenharmony_ci crush_hashmix(y, c, hash); 5962306a36Sopenharmony_ci return hash; 6062306a36Sopenharmony_ci} 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cistatic __u32 crush_hash32_rjenkins1_4(__u32 a, __u32 b, __u32 c, __u32 d) 6362306a36Sopenharmony_ci{ 6462306a36Sopenharmony_ci __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d; 6562306a36Sopenharmony_ci __u32 x = 231232; 6662306a36Sopenharmony_ci __u32 y = 1232; 6762306a36Sopenharmony_ci crush_hashmix(a, b, hash); 6862306a36Sopenharmony_ci crush_hashmix(c, d, hash); 6962306a36Sopenharmony_ci crush_hashmix(a, x, hash); 7062306a36Sopenharmony_ci crush_hashmix(y, b, hash); 7162306a36Sopenharmony_ci crush_hashmix(c, x, hash); 7262306a36Sopenharmony_ci crush_hashmix(y, d, hash); 7362306a36Sopenharmony_ci return hash; 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistatic __u32 crush_hash32_rjenkins1_5(__u32 a, __u32 b, __u32 c, __u32 d, 7762306a36Sopenharmony_ci __u32 e) 7862306a36Sopenharmony_ci{ 7962306a36Sopenharmony_ci __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d ^ e; 8062306a36Sopenharmony_ci __u32 x = 231232; 8162306a36Sopenharmony_ci __u32 y = 1232; 8262306a36Sopenharmony_ci crush_hashmix(a, b, hash); 8362306a36Sopenharmony_ci crush_hashmix(c, d, hash); 8462306a36Sopenharmony_ci crush_hashmix(e, x, hash); 8562306a36Sopenharmony_ci crush_hashmix(y, a, hash); 8662306a36Sopenharmony_ci crush_hashmix(b, x, hash); 8762306a36Sopenharmony_ci crush_hashmix(y, c, hash); 8862306a36Sopenharmony_ci crush_hashmix(d, x, hash); 8962306a36Sopenharmony_ci crush_hashmix(y, e, hash); 9062306a36Sopenharmony_ci return hash; 9162306a36Sopenharmony_ci} 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci__u32 crush_hash32(int type, __u32 a) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci switch (type) { 9762306a36Sopenharmony_ci case CRUSH_HASH_RJENKINS1: 9862306a36Sopenharmony_ci return crush_hash32_rjenkins1(a); 9962306a36Sopenharmony_ci default: 10062306a36Sopenharmony_ci return 0; 10162306a36Sopenharmony_ci } 10262306a36Sopenharmony_ci} 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci__u32 crush_hash32_2(int type, __u32 a, __u32 b) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci switch (type) { 10762306a36Sopenharmony_ci case CRUSH_HASH_RJENKINS1: 10862306a36Sopenharmony_ci return crush_hash32_rjenkins1_2(a, b); 10962306a36Sopenharmony_ci default: 11062306a36Sopenharmony_ci return 0; 11162306a36Sopenharmony_ci } 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci__u32 crush_hash32_3(int type, __u32 a, __u32 b, __u32 c) 11562306a36Sopenharmony_ci{ 11662306a36Sopenharmony_ci switch (type) { 11762306a36Sopenharmony_ci case CRUSH_HASH_RJENKINS1: 11862306a36Sopenharmony_ci return crush_hash32_rjenkins1_3(a, b, c); 11962306a36Sopenharmony_ci default: 12062306a36Sopenharmony_ci return 0; 12162306a36Sopenharmony_ci } 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci__u32 crush_hash32_4(int type, __u32 a, __u32 b, __u32 c, __u32 d) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci switch (type) { 12762306a36Sopenharmony_ci case CRUSH_HASH_RJENKINS1: 12862306a36Sopenharmony_ci return crush_hash32_rjenkins1_4(a, b, c, d); 12962306a36Sopenharmony_ci default: 13062306a36Sopenharmony_ci return 0; 13162306a36Sopenharmony_ci } 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci__u32 crush_hash32_5(int type, __u32 a, __u32 b, __u32 c, __u32 d, __u32 e) 13562306a36Sopenharmony_ci{ 13662306a36Sopenharmony_ci switch (type) { 13762306a36Sopenharmony_ci case CRUSH_HASH_RJENKINS1: 13862306a36Sopenharmony_ci return crush_hash32_rjenkins1_5(a, b, c, d, e); 13962306a36Sopenharmony_ci default: 14062306a36Sopenharmony_ci return 0; 14162306a36Sopenharmony_ci } 14262306a36Sopenharmony_ci} 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ciconst char *crush_hash_name(int type) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci switch (type) { 14762306a36Sopenharmony_ci case CRUSH_HASH_RJENKINS1: 14862306a36Sopenharmony_ci return "rjenkins1"; 14962306a36Sopenharmony_ci default: 15062306a36Sopenharmony_ci return "unknown"; 15162306a36Sopenharmony_ci } 15262306a36Sopenharmony_ci} 153