The "n" input is a GFN/MFN value and hence bounded by the physical address bits in use on a system. The hash quality won't improve by also including the upper always-zero bits in the calculation. To keep things as compile-time-constant as they were before, use PADDR_BITS (not paddr_bits) for loop bounding. This reduces loop iterations from 8 to 5.
While there also drop the unnecessary conversion to an array of unsigned char, moving the value off the stack altogether (at least with optimization enabled). Signed-off-by: Jan Beulich <[email protected]> --- I was tempted to also change the type "i" (unsigned) right here, but then thought this might be going too far ... --- v2: Also eliminate the unsigned char * alias of "n". --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -1397,10 +1397,13 @@ static unsigned int shadow_get_allocatio typedef u32 key_t; static inline key_t sh_hash(unsigned long n, unsigned int t) { - unsigned char *p = (unsigned char *)&n; key_t k = t; int i; - for ( i = 0; i < sizeof(n) ; i++ ) k = (u32)p[i] + (k<<6) + (k<<16) - k; + + BUILD_BUG_ON(PADDR_BITS > BITS_PER_LONG + PAGE_SHIFT); + for ( i = 0; i < (PADDR_BITS - PAGE_SHIFT + 7) / 8; i++, n >>= 8 ) + k = (uint8_t)n + (k << 6) + (k << 16) - k; + return k % SHADOW_HASH_BUCKETS; }
