• NeilBrown's avatar
    rhashtable: don't hold lock on first table throughout insertion. · 4feb7c7a
    NeilBrown authored
    rhashtable_try_insert() currently holds a lock on the bucket in
    the first table, while also locking buckets in subsequent tables.
    This is unnecessary and looks like a hold-over from some earlier
    version of the implementation.
    
    As insert and remove always lock a bucket in each table in turn, and
    as insert only inserts in the final table, there cannot be any races
    that are not covered by simply locking a bucket in each table in turn.
    
    When an insert call reaches that last table it can be sure that there
    is no matchinf entry in any other table as it has searched them all, and
    insertion never happens anywhere but in the last table.  The fact that
    code tests for the existence of future_tbl while holding a lock on
    the relevant bucket ensures that two threads inserting the same key
    will make compatible decisions about which is the "last" table.
    
    This simplifies the code and allows the ->rehash field to be
    discarded.
    
    We still need a way to ensure that a dead bucket_table is never
    re-linked by rhashtable_walk_stop().  This can be achieved by calling
    call_rcu() inside the locked region, and checking with
    rcu_head_after_call_rcu() in rhashtable_walk_stop() to see if the
    bucket table is empty and dead.
    Acked-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
    Reviewed-by: default avatarPaul E. McKenney <paulmck@linux.ibm.com>
    Signed-off-by: default avatarNeilBrown <neilb@suse.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    4feb7c7a
rhashtable.c 29.1 KB