• Kuniyuki Iwashima's avatar
    af_unix: Define locking order for unix_table_double_lock(). · 3955802f
    Kuniyuki Iwashima authored
    When created, AF_UNIX socket is put into net->unx.table.buckets[],
    and the hash is stored in sk->sk_hash.
    
      * unbound socket  : 0 <= sk_hash <= UNIX_HASH_MOD
    
    When bind() is called, the socket could be moved to another bucket.
    
      * pathname socket : 0 <= sk_hash <= UNIX_HASH_MOD
      * abstract socket : UNIX_HASH_MOD + 1 <= sk_hash <= UNIX_HASH_MOD * 2 + 1
    
    Then, we call unix_table_double_lock() which locks a single bucket
    or two.
    
    Let's define the order as unix_table_lock_cmp_fn() instead of using
    spin_lock_nested().
    
    The locking is always done in ascending order of sk->sk_hash, which
    is the index of buckets/locks array allocated by kvmalloc_array().
    
      sk_hash_A < sk_hash_B
      <=> &locks[sk_hash_A].dep_map < &locks[sk_hash_B].dep_map
    
    So, the relation of two sk->sk_hash can be derived from the addresses
    of dep_map in the array of locks.
    Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
    Reviewed-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
    Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
    3955802f
af_unix.c 86.7 KB