Re: [PATCH] rhashtable: detect when object movement between tables might have invalidated a lookup
From: NeilBrown
Date: Fri Nov 16 2018 - 01:59:37 EST
EOn Fri, Nov 16 2018, Herbert Xu wrote:
> On Thu, Nov 15, 2018 at 10:32:13AM +1100, NeilBrown wrote:
>>
>> +#define RHT_NULLS_MARKER(ptr) \
>> + ((void *)NULLS_MARKER(((unsigned long) (ptr)) >> 1))
>> #define INIT_RHT_NULLS_HEAD(ptr) \
>> - ((ptr) = (typeof(ptr)) NULLS_MARKER(0))
>> + ((ptr) = RHT_NULLS_MARKER(&(ptr)))
>
> Why are you shifting this by one?
NULLS_MARKER assumes a hash value in which the bottom bits are most
likely to be unique. To convert this to a pointer which certainly not
valid, it shifts left by 1 and sets the lsb.
We aren't passing a hash value, but are passing an address instead.
In this case the bottom 2 bits are certain to be 0, and the top bit
could contain valuable information (on a 32bit system).
The best way to turn a pointer into a certainly-invalid pointer
is to just set the lsb. By shifting right by one, we discard an
uninteresting bit, preserve all the interesting bits, and effectively
just set the lsb.
I could add a comment explaining that if you like.
>
>> diff --git a/lib/rhashtable.c b/lib/rhashtable.c
>> index 30526afa8343..852ffa5160f1 100644
>> --- a/lib/rhashtable.c
>> +++ b/lib/rhashtable.c
>> @@ -1179,8 +1179,7 @@ struct rhash_head __rcu **rht_bucket_nested(const struct bucket_table *tbl,
>> unsigned int hash)
>> {
>> const unsigned int shift = PAGE_SHIFT - ilog2(sizeof(void *));
>> - static struct rhash_head __rcu *rhnull =
>> - (struct rhash_head __rcu *)NULLS_MARKER(0);
>> + static struct rhash_head __rcu *rhnull;
>
> I don't understand why you can't continue to do NULLS_MARKER(0) or
> RHT_NULLS_MARKER(0).
Because then the test
+ } while (he != RHT_NULLS_MARKER(head));
in __rhashtable_lookup() would always succeed, and it would loop
forever.
Thanks for the review.
NeilBrown
>
> Cheers,
> --
> Email: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Attachment:
signature.asc
Description: PGP signature