Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

jhash: Update jhash_[321]words functions to use correct initval

Looking over the implementation for jhash2 and comparing it to jhash_3words
I realized that the two hashes were in fact very different. Doing a bit of
digging led me to "The new jhash implementation" in which lookup2 was
supposed to have been replaced with lookup3.

In reviewing the patch I noticed that jhash2 had originally initialized a
and b to JHASH_GOLDENRATIO and c to initval, but after the patch a, b, and
c were initialized to initval + (length << 2) + JHASH_INITVAL. However the
changes in jhash_3words simply replaced the initialization of a and b with
JHASH_INITVAL.

This change corrects what I believe was an oversight so that a, b, and c in
jhash_3words all have the same value added consisting of initval + (length
<< 2) + JHASH_INITVAL so that jhash2 and jhash_3words will now produce the
same hash result given the same inputs.

Fixes: 60d509c823cca ("The new jhash implementation")
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Alexander Duyck and committed by
David S. Miller
2e7056c4 5c5e0ad3

+11 -6
+11 -6
include/linux/jhash.h
··· 145 145 } 146 146 147 147 148 - /* jhash_3words - hash exactly 3, 2 or 1 word(s) */ 149 - static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval) 148 + /* __jhash_nwords - hash exactly 3, 2 or 1 word(s) */ 149 + static inline u32 __jhash_nwords(u32 a, u32 b, u32 c, u32 initval) 150 150 { 151 - a += JHASH_INITVAL; 152 - b += JHASH_INITVAL; 151 + a += initval; 152 + b += initval; 153 153 c += initval; 154 154 155 155 __jhash_final(a, b, c); ··· 157 157 return c; 158 158 } 159 159 160 + static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval) 161 + { 162 + return __jhash_nwords(a, b, c, initval + JHASH_INITVAL + (3 << 2)); 163 + } 164 + 160 165 static inline u32 jhash_2words(u32 a, u32 b, u32 initval) 161 166 { 162 - return jhash_3words(a, b, 0, initval); 167 + return __jhash_nwords(a, b, 0, initval + JHASH_INITVAL + (2 << 2)); 163 168 } 164 169 165 170 static inline u32 jhash_1word(u32 a, u32 initval) 166 171 { 167 - return jhash_3words(a, 0, 0, initval); 172 + return __jhash_nwords(a, 0, 0, initval + JHASH_INITVAL + (1 << 2)); 168 173 } 169 174 170 175 #endif /* _LINUX_JHASH_H */