All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] inet: fix fast path in __inet_hash_connect()
@ 2023-01-12 15:39 Pietro Borrello
  2023-01-13  0:48 ` Kuniyuki Iwashima
  0 siblings, 1 reply; 2+ messages in thread
From: Pietro Borrello @ 2023-01-12 15:39 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Hideaki YOSHIFUJI, David Ahern
  Cc: Cristiano Giuffrida, Bos, H.J.,
	Jakob Koschel, netdev, linux-kernel, Pietro Borrello

__inet_hash_connect() has a fast path taken if sk_head(&tb->owners) is
equal to the sk parameter.
sk_head() returns the list_entry() with respect to the sk_node field.
However entries in the tb->owners list are inserted with respect to the
sk_bind_node field with sk_add_bind_node().
Thus the check would never pass and the fast path never execute.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
---
 include/net/sock.h         | 10 ++++++++++
 net/ipv4/inet_hashtables.c |  2 +-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index dcd72e6285b2..23fc403284db 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -860,6 +860,16 @@ static inline void sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_hea
 	__sk_nulls_add_node_rcu(sk, list);
 }
 
+static inline struct sock *__sk_bind_head(const struct hlist_head *head)
+{
+	return hlist_entry(head->first, struct sock, sk_bind_node);
+}
+
+static inline struct sock *sk_bind_head(const struct hlist_head *head)
+{
+	return hlist_empty(head) ? NULL : __sk_bind_head(head);
+}
+
 static inline void __sk_del_bind_node(struct sock *sk)
 {
 	__hlist_del(&sk->sk_bind_node);
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index d039b4e732a3..a805e086fb48 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -998,7 +998,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 						  hinfo->bhash_size)];
 		tb = inet_csk(sk)->icsk_bind_hash;
 		spin_lock_bh(&head->lock);
-		if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
+		if (sk_bind_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
 			inet_ehash_nolisten(sk, NULL, NULL);
 			spin_unlock_bh(&head->lock);
 			return 0;

---
base-commit: 1b929c02afd37871d5afb9d498426f83432e71c2
change-id: 20230112-inet_hash_connect_bind_head-8f2dc98f08b1

Best regards,
-- 
Pietro Borrello <borrello@diag.uniroma1.it>

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

* Re: [PATCH] inet: fix fast path in __inet_hash_connect()
  2023-01-12 15:39 [PATCH] inet: fix fast path in __inet_hash_connect() Pietro Borrello
@ 2023-01-13  0:48 ` Kuniyuki Iwashima
  0 siblings, 0 replies; 2+ messages in thread
From: Kuniyuki Iwashima @ 2023-01-13  0:48 UTC (permalink / raw)
  To: borrello
  Cc: c.giuffrida, davem, dsahern, edumazet, h.j.bos, jkl820.git, kuba,
	linux-kernel, netdev, pabeni, yoshfuji, kuniyu

From:   Pietro Borrello <borrello@diag.uniroma1.it>
Date:   Thu, 12 Jan 2023 15:39:23 +0000
> __inet_hash_connect() has a fast path taken if sk_head(&tb->owners) is
> equal to the sk parameter.
> sk_head() returns the list_entry() with respect to the sk_node field.

nit: s/list_entry/hlist_entry/

> However entries in the tb->owners list are inserted with respect to the
> sk_bind_node field with sk_add_bind_node().
> Thus the check would never pass and the fast path never execute.
> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>

Good catch!
Other than the nit above, looks good to me.

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

Thank you.


> ---
>  include/net/sock.h         | 10 ++++++++++
>  net/ipv4/inet_hashtables.c |  2 +-
>  2 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/include/net/sock.h b/include/net/sock.h
> index dcd72e6285b2..23fc403284db 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -860,6 +860,16 @@ static inline void sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_hea
>  	__sk_nulls_add_node_rcu(sk, list);
>  }
>  
> +static inline struct sock *__sk_bind_head(const struct hlist_head *head)
> +{
> +	return hlist_entry(head->first, struct sock, sk_bind_node);
> +}
> +
> +static inline struct sock *sk_bind_head(const struct hlist_head *head)
> +{
> +	return hlist_empty(head) ? NULL : __sk_bind_head(head);
> +}
> +
>  static inline void __sk_del_bind_node(struct sock *sk)
>  {
>  	__hlist_del(&sk->sk_bind_node);
> diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
> index d039b4e732a3..a805e086fb48 100644
> --- a/net/ipv4/inet_hashtables.c
> +++ b/net/ipv4/inet_hashtables.c
> @@ -998,7 +998,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
>  						  hinfo->bhash_size)];
>  		tb = inet_csk(sk)->icsk_bind_hash;
>  		spin_lock_bh(&head->lock);
> -		if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
> +		if (sk_bind_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
>  			inet_ehash_nolisten(sk, NULL, NULL);
>  			spin_unlock_bh(&head->lock);
>  			return 0;
> 
> ---
> base-commit: 1b929c02afd37871d5afb9d498426f83432e71c2
> change-id: 20230112-inet_hash_connect_bind_head-8f2dc98f08b1
> 
> Best regards,
> -- 
> Pietro Borrello <borrello@diag.uniroma1.it>

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

end of thread, other threads:[~2023-01-13  0:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-12 15:39 [PATCH] inet: fix fast path in __inet_hash_connect() Pietro Borrello
2023-01-13  0:48 ` Kuniyuki Iwashima

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.