netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 net 0/2] rfs: annotate lockless accesses
@ 2023-06-06  7:41 Eric Dumazet
  2023-06-06  7:41 ` [PATCH v2 net 1/2] rfs: annotate lockless accesses to sk->sk_rxhash Eric Dumazet
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Eric Dumazet @ 2023-06-06  7:41 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, netdev, eric.dumazet, Eric Dumazet

rfs runs without locks held, so we should annotate
read and writes to shared variables.

It should prevent compilers forcing writes
in the following situation:

  if (var != val)
     var = val;

A compiler could indeed simply avoid the conditional:

    var = val;

This matters if var is shared between many cpus.

v2: aligns one closing bracket (Simon)
    adds Fixes: tags (Jakub)

Eric Dumazet (2):
  rfs: annotate lockless accesses to sk->sk_rxhash
  rfs: annotate lockless accesses to RFS sock flow table

 include/linux/netdevice.h |  7 +++++--
 include/net/sock.h        | 18 +++++++++++++-----
 net/core/dev.c            |  6 ++++--
 3 files changed, 22 insertions(+), 9 deletions(-)

-- 
2.41.0.rc0.172.g3f132b7071-goog


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 net 1/2] rfs: annotate lockless accesses to sk->sk_rxhash
  2023-06-06  7:41 [PATCH v2 net 0/2] rfs: annotate lockless accesses Eric Dumazet
@ 2023-06-06  7:41 ` Eric Dumazet
  2023-06-06  9:40   ` Simon Horman
  2023-06-06 17:40   ` Kuniyuki Iwashima
  2023-06-06  7:41 ` [PATCH v2 net 2/2] rfs: annotate lockless accesses to RFS sock flow table Eric Dumazet
  2023-06-07  9:20 ` [PATCH v2 net 0/2] rfs: annotate lockless accesses patchwork-bot+netdevbpf
  2 siblings, 2 replies; 8+ messages in thread
From: Eric Dumazet @ 2023-06-06  7:41 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, netdev, eric.dumazet, Eric Dumazet

Add READ_ONCE()/WRITE_ONCE() on accesses to sk->sk_rxhash.

This also prevents a (smart ?) compiler to remove the condition in:

if (sk->sk_rxhash != newval)
	sk->sk_rxhash = newval;

We need the condition to avoid dirtying a shared cache line.

Fixes: fec5e652e58f ("rfs: Receive Flow Steering")
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 include/net/sock.h | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index b418425d7230c8cee81df34fcc66d771ea5085e9..6f428a7f356755e73852c0e0006f2eb533fc7f57 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1152,8 +1152,12 @@ static inline void sock_rps_record_flow(const struct sock *sk)
 		 * OR	an additional socket flag
 		 * [1] : sk_state and sk_prot are in the same cache line.
 		 */
-		if (sk->sk_state == TCP_ESTABLISHED)
-			sock_rps_record_flow_hash(sk->sk_rxhash);
+		if (sk->sk_state == TCP_ESTABLISHED) {
+			/* This READ_ONCE() is paired with the WRITE_ONCE()
+			 * from sock_rps_save_rxhash() and sock_rps_reset_rxhash().
+			 */
+			sock_rps_record_flow_hash(READ_ONCE(sk->sk_rxhash));
+		}
 	}
 #endif
 }
@@ -1162,15 +1166,19 @@ static inline void sock_rps_save_rxhash(struct sock *sk,
 					const struct sk_buff *skb)
 {
 #ifdef CONFIG_RPS
-	if (unlikely(sk->sk_rxhash != skb->hash))
-		sk->sk_rxhash = skb->hash;
+	/* The following WRITE_ONCE() is paired with the READ_ONCE()
+	 * here, and another one in sock_rps_record_flow().
+	 */
+	if (unlikely(READ_ONCE(sk->sk_rxhash) != skb->hash))
+		WRITE_ONCE(sk->sk_rxhash, skb->hash);
 #endif
 }
 
 static inline void sock_rps_reset_rxhash(struct sock *sk)
 {
 #ifdef CONFIG_RPS
-	sk->sk_rxhash = 0;
+	/* Paired with READ_ONCE() in sock_rps_record_flow() */
+	WRITE_ONCE(sk->sk_rxhash, 0);
 #endif
 }
 
-- 
2.41.0.rc0.172.g3f132b7071-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 net 2/2] rfs: annotate lockless accesses to RFS sock flow table
  2023-06-06  7:41 [PATCH v2 net 0/2] rfs: annotate lockless accesses Eric Dumazet
  2023-06-06  7:41 ` [PATCH v2 net 1/2] rfs: annotate lockless accesses to sk->sk_rxhash Eric Dumazet
@ 2023-06-06  7:41 ` Eric Dumazet
  2023-06-06  9:40   ` Simon Horman
  2023-06-06 17:42   ` Kuniyuki Iwashima
  2023-06-07  9:20 ` [PATCH v2 net 0/2] rfs: annotate lockless accesses patchwork-bot+netdevbpf
  2 siblings, 2 replies; 8+ messages in thread
From: Eric Dumazet @ 2023-06-06  7:41 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, netdev, eric.dumazet, Eric Dumazet

Add READ_ONCE()/WRITE_ONCE() on accesses to the sock flow table.

This also prevents a (smart ?) compiler to remove the condition in:

if (table->ents[index] != newval)
        table->ents[index] = newval;

We need the condition to avoid dirtying a shared cache line.

Fixes: fec5e652e58f ("rfs: Receive Flow Steering")
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 include/linux/netdevice.h | 7 +++++--
 net/core/dev.c            | 6 ++++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 08fbd4622ccf731daaee34ad99773d6dc2e82fa6..e6f22b7403d014a2cf4d81d931109a594ce1398e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -768,8 +768,11 @@ static inline void rps_record_sock_flow(struct rps_sock_flow_table *table,
 		/* We only give a hint, preemption can change CPU under us */
 		val |= raw_smp_processor_id();
 
-		if (table->ents[index] != val)
-			table->ents[index] = val;
+		/* The following WRITE_ONCE() is paired with the READ_ONCE()
+		 * here, and another one in get_rps_cpu().
+		 */
+		if (READ_ONCE(table->ents[index]) != val)
+			WRITE_ONCE(table->ents[index], val);
 	}
 }
 
diff --git a/net/core/dev.c b/net/core/dev.c
index b3c13e0419356b943e90b1f46dd7e035c6ec1a9c..1495f8aff288e944c8cab21297f244a6fcde752f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4471,8 +4471,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
 		u32 next_cpu;
 		u32 ident;
 
-		/* First check into global flow table if there is a match */
-		ident = sock_flow_table->ents[hash & sock_flow_table->mask];
+		/* First check into global flow table if there is a match.
+		 * This READ_ONCE() pairs with WRITE_ONCE() from rps_record_sock_flow().
+		 */
+		ident = READ_ONCE(sock_flow_table->ents[hash & sock_flow_table->mask]);
 		if ((ident ^ hash) & ~rps_cpu_mask)
 			goto try_rps;
 
-- 
2.41.0.rc0.172.g3f132b7071-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net 1/2] rfs: annotate lockless accesses to sk->sk_rxhash
  2023-06-06  7:41 ` [PATCH v2 net 1/2] rfs: annotate lockless accesses to sk->sk_rxhash Eric Dumazet
@ 2023-06-06  9:40   ` Simon Horman
  2023-06-06 17:40   ` Kuniyuki Iwashima
  1 sibling, 0 replies; 8+ messages in thread
From: Simon Horman @ 2023-06-06  9:40 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, netdev,
	eric.dumazet

On Tue, Jun 06, 2023 at 07:41:14AM +0000, Eric Dumazet wrote:
> Add READ_ONCE()/WRITE_ONCE() on accesses to sk->sk_rxhash.
> 
> This also prevents a (smart ?) compiler to remove the condition in:
> 
> if (sk->sk_rxhash != newval)
> 	sk->sk_rxhash = newval;
> 
> We need the condition to avoid dirtying a shared cache line.
> 
> Fixes: fec5e652e58f ("rfs: Receive Flow Steering")
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Reviewed-by: Simon Horman <simon.horman@corigine.com>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net 2/2] rfs: annotate lockless accesses to RFS sock flow table
  2023-06-06  7:41 ` [PATCH v2 net 2/2] rfs: annotate lockless accesses to RFS sock flow table Eric Dumazet
@ 2023-06-06  9:40   ` Simon Horman
  2023-06-06 17:42   ` Kuniyuki Iwashima
  1 sibling, 0 replies; 8+ messages in thread
From: Simon Horman @ 2023-06-06  9:40 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, netdev,
	eric.dumazet

On Tue, Jun 06, 2023 at 07:41:15AM +0000, Eric Dumazet wrote:
> Add READ_ONCE()/WRITE_ONCE() on accesses to the sock flow table.
> 
> This also prevents a (smart ?) compiler to remove the condition in:
> 
> if (table->ents[index] != newval)
>         table->ents[index] = newval;
> 
> We need the condition to avoid dirtying a shared cache line.
> 
> Fixes: fec5e652e58f ("rfs: Receive Flow Steering")
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Reviewed-by: Simon Horman <simon.horman@corigine.com>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net 1/2] rfs: annotate lockless accesses to sk->sk_rxhash
  2023-06-06  7:41 ` [PATCH v2 net 1/2] rfs: annotate lockless accesses to sk->sk_rxhash Eric Dumazet
  2023-06-06  9:40   ` Simon Horman
@ 2023-06-06 17:40   ` Kuniyuki Iwashima
  1 sibling, 0 replies; 8+ messages in thread
From: Kuniyuki Iwashima @ 2023-06-06 17:40 UTC (permalink / raw)
  To: edumazet; +Cc: davem, eric.dumazet, kuba, netdev, pabeni, simon.horman, kuniyu

From: Eric Dumazet <edumazet@google.com>
Date: Tue,  6 Jun 2023 07:41:14 +0000
> Add READ_ONCE()/WRITE_ONCE() on accesses to sk->sk_rxhash.
> 
> This also prevents a (smart ?) compiler to remove the condition in:
> 
> if (sk->sk_rxhash != newval)
> 	sk->sk_rxhash = newval;
> 
> We need the condition to avoid dirtying a shared cache line.
> 
> Fixes: fec5e652e58f ("rfs: Receive Flow Steering")
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>

Thank you!


> ---
>  include/net/sock.h | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/include/net/sock.h b/include/net/sock.h
> index b418425d7230c8cee81df34fcc66d771ea5085e9..6f428a7f356755e73852c0e0006f2eb533fc7f57 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -1152,8 +1152,12 @@ static inline void sock_rps_record_flow(const struct sock *sk)
>  		 * OR	an additional socket flag
>  		 * [1] : sk_state and sk_prot are in the same cache line.
>  		 */
> -		if (sk->sk_state == TCP_ESTABLISHED)
> -			sock_rps_record_flow_hash(sk->sk_rxhash);
> +		if (sk->sk_state == TCP_ESTABLISHED) {
> +			/* This READ_ONCE() is paired with the WRITE_ONCE()
> +			 * from sock_rps_save_rxhash() and sock_rps_reset_rxhash().
> +			 */
> +			sock_rps_record_flow_hash(READ_ONCE(sk->sk_rxhash));
> +		}
>  	}
>  #endif
>  }
> @@ -1162,15 +1166,19 @@ static inline void sock_rps_save_rxhash(struct sock *sk,
>  					const struct sk_buff *skb)
>  {
>  #ifdef CONFIG_RPS
> -	if (unlikely(sk->sk_rxhash != skb->hash))
> -		sk->sk_rxhash = skb->hash;
> +	/* The following WRITE_ONCE() is paired with the READ_ONCE()
> +	 * here, and another one in sock_rps_record_flow().
> +	 */
> +	if (unlikely(READ_ONCE(sk->sk_rxhash) != skb->hash))
> +		WRITE_ONCE(sk->sk_rxhash, skb->hash);
>  #endif
>  }
>  
>  static inline void sock_rps_reset_rxhash(struct sock *sk)
>  {
>  #ifdef CONFIG_RPS
> -	sk->sk_rxhash = 0;
> +	/* Paired with READ_ONCE() in sock_rps_record_flow() */
> +	WRITE_ONCE(sk->sk_rxhash, 0);
>  #endif
>  }
>  
> -- 
> 2.41.0.rc0.172.g3f132b7071-goog

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net 2/2] rfs: annotate lockless accesses to RFS sock flow table
  2023-06-06  7:41 ` [PATCH v2 net 2/2] rfs: annotate lockless accesses to RFS sock flow table Eric Dumazet
  2023-06-06  9:40   ` Simon Horman
@ 2023-06-06 17:42   ` Kuniyuki Iwashima
  1 sibling, 0 replies; 8+ messages in thread
From: Kuniyuki Iwashima @ 2023-06-06 17:42 UTC (permalink / raw)
  To: edumazet; +Cc: davem, eric.dumazet, kuba, netdev, pabeni, simon.horman, kuniyu

From: Eric Dumazet <edumazet@google.com>
Date: Tue,  6 Jun 2023 07:41:15 +0000
> Add READ_ONCE()/WRITE_ONCE() on accesses to the sock flow table.
> 
> This also prevents a (smart ?) compiler to remove the condition in:
> 
> if (table->ents[index] != newval)
>         table->ents[index] = newval;
> 
> We need the condition to avoid dirtying a shared cache line.
> 
> Fixes: fec5e652e58f ("rfs: Receive Flow Steering")
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>


> ---
>  include/linux/netdevice.h | 7 +++++--
>  net/core/dev.c            | 6 ++++--
>  2 files changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 08fbd4622ccf731daaee34ad99773d6dc2e82fa6..e6f22b7403d014a2cf4d81d931109a594ce1398e 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -768,8 +768,11 @@ static inline void rps_record_sock_flow(struct rps_sock_flow_table *table,
>  		/* We only give a hint, preemption can change CPU under us */
>  		val |= raw_smp_processor_id();
>  
> -		if (table->ents[index] != val)
> -			table->ents[index] = val;
> +		/* The following WRITE_ONCE() is paired with the READ_ONCE()
> +		 * here, and another one in get_rps_cpu().
> +		 */
> +		if (READ_ONCE(table->ents[index]) != val)
> +			WRITE_ONCE(table->ents[index], val);
>  	}
>  }
>  
> diff --git a/net/core/dev.c b/net/core/dev.c
> index b3c13e0419356b943e90b1f46dd7e035c6ec1a9c..1495f8aff288e944c8cab21297f244a6fcde752f 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -4471,8 +4471,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
>  		u32 next_cpu;
>  		u32 ident;
>  
> -		/* First check into global flow table if there is a match */
> -		ident = sock_flow_table->ents[hash & sock_flow_table->mask];
> +		/* First check into global flow table if there is a match.
> +		 * This READ_ONCE() pairs with WRITE_ONCE() from rps_record_sock_flow().
> +		 */
> +		ident = READ_ONCE(sock_flow_table->ents[hash & sock_flow_table->mask]);
>  		if ((ident ^ hash) & ~rps_cpu_mask)
>  			goto try_rps;
>  
> -- 
> 2.41.0.rc0.172.g3f132b7071-goog

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net 0/2] rfs: annotate lockless accesses
  2023-06-06  7:41 [PATCH v2 net 0/2] rfs: annotate lockless accesses Eric Dumazet
  2023-06-06  7:41 ` [PATCH v2 net 1/2] rfs: annotate lockless accesses to sk->sk_rxhash Eric Dumazet
  2023-06-06  7:41 ` [PATCH v2 net 2/2] rfs: annotate lockless accesses to RFS sock flow table Eric Dumazet
@ 2023-06-07  9:20 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-06-07  9:20 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: davem, kuba, pabeni, simon.horman, netdev, eric.dumazet

Hello:

This series was applied to netdev/net.git (main)
by David S. Miller <davem@davemloft.net>:

On Tue,  6 Jun 2023 07:41:13 +0000 you wrote:
> rfs runs without locks held, so we should annotate
> read and writes to shared variables.
> 
> It should prevent compilers forcing writes
> in the following situation:
> 
>   if (var != val)
>      var = val;
> 
> [...]

Here is the summary with links:
  - [v2,net,1/2] rfs: annotate lockless accesses to sk->sk_rxhash
    https://git.kernel.org/netdev/net/c/1e5c647c3f6d
  - [v2,net,2/2] rfs: annotate lockless accesses to RFS sock flow table
    https://git.kernel.org/netdev/net/c/5c3b74a92aa2

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-06-07  9:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-06  7:41 [PATCH v2 net 0/2] rfs: annotate lockless accesses Eric Dumazet
2023-06-06  7:41 ` [PATCH v2 net 1/2] rfs: annotate lockless accesses to sk->sk_rxhash Eric Dumazet
2023-06-06  9:40   ` Simon Horman
2023-06-06 17:40   ` Kuniyuki Iwashima
2023-06-06  7:41 ` [PATCH v2 net 2/2] rfs: annotate lockless accesses to RFS sock flow table Eric Dumazet
2023-06-06  9:40   ` Simon Horman
2023-06-06 17:42   ` Kuniyuki Iwashima
2023-06-07  9:20 ` [PATCH v2 net 0/2] rfs: annotate lockless accesses patchwork-bot+netdevbpf

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).