netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kuniyuki Iwashima <kuniyu@amazon.co.jp>
To: <kuniyu@amazon.co.jp>
Cc: <benh@amazon.com>, <davem@davemloft.net>,
	<eric.dumazet@gmail.com>, <kuba@kernel.org>, <kuni1840@gmail.com>,
	<netdev@vger.kernel.org>
Subject: Re: [PATCH v2 net-next 12/13] af_unix: Replace the big lock with small locks.
Date: Wed, 17 Nov 2021 09:16:11 +0900	[thread overview]
Message-ID: <20211117001611.74123-1-kuniyu@amazon.co.jp> (raw)
In-Reply-To: <20211114012428.81743-13-kuniyu@amazon.co.jp>

From:   Kuniyuki Iwashima <kuniyu@amazon.co.jp>
Date:   Sun, 14 Nov 2021 10:24:27 +0900
> The hash table of AF_UNIX sockets is protected by the single lock.  This
> patch replaces it with per-hash locks.
[...]
> +static void unix_table_double_lock(unsigned int hash1, unsigned int hash2)
> +{
> +	/* hash1 and hash2 is never the same because
> +	 * one is between 0 and UNIX_HASH_SIZE - 1, and
> +	 * another is between UNIX_HASH_SIZE and UNIX_HASH_SIZE * 2.
> +	 */
> +	if (hash1 > hash2)
> +		swap(hash1, hash2);
> +
> +	spin_lock(&unix_table_locks[hash1]);
> +	spin_lock_nested(&unix_table_locks[hash2], SINGLE_DEPTH_NESTING);
> +}
> +
> +static void unix_table_double_unlock(unsigned int hash1, unsigned int hash2)
> +{
> +	spin_unlock(&unix_table_locks[hash1]);
> +	spin_unlock(&unix_table_locks[hash2]);
> +}

The status is "Changes Requested" on patchwork because of some newly added
sparse warnings.  There are two kinds of warnings.  One is about
unix_table_double_lock/unlock() and the other is about unix_seq_start/stop().

https://patchwork.hopto.org/static/nipa/579645/12617773/build_32bit/summary

---8<---
+../net/unix/af_unix.c:159:13: warning: context imbalance in 'unix_table_double_lock' - wrong count at exit
+../net/unix/af_unix.c:172:13: warning: context imbalance in 'unix_table_double_unlock' - unexpected unlock
+../net/unix/af_unix.c:1258:13: warning: context imbalance in 'unix_state_double_lock' - wrong count at exit
+../net/unix/af_unix.c:1276:17: warning: context imbalance in 'unix_state_double_unlock' - unexpected unlock
+../net/unix/af_unix.c:1579:9: warning: context imbalance in 'unix_stream_connect' - different lock contexts for basic block
+../net/unix/af_unix.c:1944:25: warning: context imbalance in 'unix_dgram_sendmsg' - unexpected unlock
+../net/unix/af_unix.c:3255:28: warning: context imbalance in 'unix_next_socket' - unexpected unlock
+../net/unix/af_unix.c:3284:28: warning: context imbalance in 'unix_seq_stop' - unexpected unlock
---8<---


We can avoid the former by adding these annotations, but it seems a little
bit redundant.  Also, there has already been the same kind of warnings for
unix_state_double_lock() without sparse annotations.

---8<---
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 89a844e7141b..b26a2ea26029 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -157,6 +157,8 @@ static unsigned int unix_abstract_hash(struct sockaddr_un *sunaddr,
 }
 
 static void unix_table_double_lock(unsigned int hash1, unsigned int hash2)
+	__acquires(unix_table_locks)
+	__acquires(unix_table_locks)
 {
 	/* hash1 and hash2 is never the same because
 	 * one is between 0 and UNIX_HASH_SIZE - 1, and
@@ -170,6 +172,8 @@ static void unix_table_double_lock(unsigned int hash1, unsigned int hash2)
 }
 
 static void unix_table_double_unlock(unsigned int hash1, unsigned int hash2)
+	__releases(unix_table_locks)
+	__releases(unix_table_locks)
 {
 	spin_unlock(&unix_table_locks[hash1]);
 	spin_unlock(&unix_table_locks[hash2]);
---8<---


[...]
> @@ -3216,7 +3235,7 @@ static struct sock *unix_next_socket(struct seq_file *seq,
>  				     struct sock *sk,
>  				     loff_t *pos)
>  {
> -	unsigned long bucket;
> +	unsigned long bucket = get_bucket(*pos);
>  
>  	while (sk > (struct sock *)SEQ_START_TOKEN) {
>  		sk = sk_next(sk);
> @@ -3227,12 +3246,13 @@ static struct sock *unix_next_socket(struct seq_file *seq,
>  	}
>  
>  	do {
> +		spin_lock(&unix_table_locks[bucket]);
>  		sk = unix_from_bucket(seq, pos);
>  		if (sk)
>  			return sk;
>  
>  next_bucket:
> -		bucket = get_bucket(*pos) + 1;
> +		spin_unlock(&unix_table_locks[bucket++]);
>  		*pos = set_bucket_offset(bucket, 1);
>  	} while (bucket < ARRAY_SIZE(unix_socket_table));
>  
> @@ -3240,10 +3260,7 @@ static struct sock *unix_next_socket(struct seq_file *seq,
>  }
>  
>  static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
> -	__acquires(unix_table_lock)
>  {
> -	spin_lock(&unix_table_lock);
> -
>  	if (!*pos)
>  		return SEQ_START_TOKEN;
>  
> @@ -3260,9 +3277,11 @@ static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
>  }
>  
>  static void unix_seq_stop(struct seq_file *seq, void *v)
> -	__releases(unix_table_lock)
>  {
> -	spin_unlock(&unix_table_lock);
> +	struct sock *sk = v;
> +
> +	if (sk)
> +		spin_unlock(&unix_table_locks[sk->sk_hash]);
>  }
>  
>  static int unix_seq_show(struct seq_file *seq, void *v)
[...]

The latter happens by replacing the big lock with per-hash locks.
It moves spin_lock() from unix_seq_start() to unix_next_socket().
unix_next_socket() keeps holding a lock until it returns NULL, so Sparse
cannot understand the logic.  At least, we can add __releases annotation in
unix_seq_stop(), but it rather increases warnings.  And tcp_seq_stop() does
not have annotations.

Are these warnings acceptable, or is there any better way?

  reply	other threads:[~2021-11-17  0:16 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-14  1:24 [PATCH v2 net-next 00/13] af_unix: Replace unix_table_lock with per-hash locks Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 01/13] af_unix: Use offsetof() instead of sizeof() Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 02/13] af_unix: Pass struct sock to unix_autobind() Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 03/13] af_unix: Factorise unix_find_other() based on address types Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 04/13] af_unix: Return an error as a pointer in unix_find_other() Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 05/13] af_unix: Cut unix_validate_addr() out of unix_mkname() Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 06/13] af_unix: Copy unix_mkname() into unix_find_(bsd|abstract)() Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 07/13] af_unix: Remove unix_mkname() Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 08/13] af_unix: Allocate unix_address in unix_bind_(bsd|abstract)() Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 09/13] af_unix: Remove UNIX_ABSTRACT() macro and test sun_path[0] instead Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 10/13] af_unix: Add helpers to calculate hashes Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 11/13] af_unix: Save hash in sk_hash Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 12/13] af_unix: Replace the big lock with small locks Kuniyuki Iwashima
2021-11-17  0:16   ` Kuniyuki Iwashima [this message]
2021-11-18  5:43   ` Kuniyuki Iwashima
2021-11-14  1:24 ` [PATCH v2 net-next 13/13] af_unix: Relax race in unix_autobind() Kuniyuki Iwashima

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211117001611.74123-1-kuniyu@amazon.co.jp \
    --to=kuniyu@amazon.co.jp \
    --cc=benh@amazon.com \
    --cc=davem@davemloft.net \
    --cc=eric.dumazet@gmail.com \
    --cc=kuba@kernel.org \
    --cc=kuni1840@gmail.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).