[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250714-connect-port-search-harder-v3-1-b1a41f249865@cloudflare.com>
Date: Mon, 14 Jul 2025 18:03:04 +0200
From: Jakub Sitnicki <jakub@...udflare.com>
To: Eric Dumazet <edumazet@...gle.com>, Paolo Abeni <pabeni@...hat.com>,
"David S. Miller" <davem@...emloft.net>, Jakub Kicinski <kuba@...nel.org>,
Neal Cardwell <ncardwell@...gle.com>, Kuniyuki Iwashima <kuniyu@...gle.com>
Cc: netdev@...r.kernel.org, kernel-team@...udflare.com
Subject: [PATCH net-next v3 1/3] tcp: Add RCU management to
inet_bind2_bucket
Add RCU protection to inet_bind2_bucket structure akin to commit
d186f405fdf4 ("tcp: add RCU management to inet_bind_bucket").
This prepares us for walking (struct inet_bind_bucket *)->bhash2 list
without holding inet_bind_hashbucket spinlock.
Signed-off-by: Jakub Sitnicki <jakub@...udflare.com>
---
include/net/inet_hashtables.h | 4 ++--
include/net/inet_timewait_sock.h | 3 +--
net/ipv4/inet_connection_sock.c | 2 +-
net/ipv4/inet_hashtables.c | 16 ++++++++--------
net/ipv4/inet_timewait_sock.c | 8 +++-----
5 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 19dbd9081d5a..a2ff18eea990 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -108,6 +108,7 @@ struct inet_bind2_bucket {
struct hlist_node bhash_node;
/* List of sockets hashed to this bucket */
struct hlist_head owners;
+ struct rcu_head rcu;
};
static inline struct net *ib_net(const struct inet_bind_bucket *ib)
@@ -228,8 +229,7 @@ inet_bind2_bucket_create(struct kmem_cache *cachep, struct net *net,
struct inet_bind_bucket *tb,
const struct sock *sk);
-void inet_bind2_bucket_destroy(struct kmem_cache *cachep,
- struct inet_bind2_bucket *tb);
+void inet_bind2_bucket_destroy(struct inet_bind2_bucket *tb);
struct inet_bind2_bucket *
inet_bind2_bucket_find(const struct inet_bind_hashbucket *head,
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index 67a313575780..4f4e96b10cf3 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -92,8 +92,7 @@ static inline struct inet_timewait_sock *inet_twsk(const struct sock *sk)
void inet_twsk_free(struct inet_timewait_sock *tw);
void inet_twsk_put(struct inet_timewait_sock *tw);
-void inet_twsk_bind_unhash(struct inet_timewait_sock *tw,
- struct inet_hashinfo *hashinfo);
+void inet_twsk_bind_unhash(struct inet_timewait_sock *tw);
struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk,
struct inet_timewait_death_row *dr,
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 1e2df51427fe..f58b93d3fa0e 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -593,7 +593,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
fail_unlock:
if (ret) {
if (bhash2_created)
- inet_bind2_bucket_destroy(hinfo->bind2_bucket_cachep, tb2);
+ inet_bind2_bucket_destroy(tb2);
if (bhash_created)
inet_bind_bucket_destroy(tb);
}
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index ceeeec9b7290..d3ce6d0a514e 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -123,7 +123,7 @@ static void inet_bind2_bucket_init(struct inet_bind2_bucket *tb2,
#endif
INIT_HLIST_HEAD(&tb2->owners);
hlist_add_head(&tb2->node, &head->chain);
- hlist_add_head(&tb2->bhash_node, &tb->bhash2);
+ hlist_add_head_rcu(&tb2->bhash_node, &tb->bhash2);
}
struct inet_bind2_bucket *inet_bind2_bucket_create(struct kmem_cache *cachep,
@@ -141,12 +141,12 @@ struct inet_bind2_bucket *inet_bind2_bucket_create(struct kmem_cache *cachep,
}
/* Caller must hold hashbucket lock for this tb with local BH disabled */
-void inet_bind2_bucket_destroy(struct kmem_cache *cachep, struct inet_bind2_bucket *tb)
+void inet_bind2_bucket_destroy(struct inet_bind2_bucket *tb)
{
if (hlist_empty(&tb->owners)) {
__hlist_del(&tb->node);
- __hlist_del(&tb->bhash_node);
- kmem_cache_free(cachep, tb);
+ hlist_del_rcu(&tb->bhash_node);
+ kfree_rcu(tb, rcu);
}
}
@@ -198,7 +198,7 @@ static void __inet_put_port(struct sock *sk)
__sk_del_bind_node(sk);
inet_csk(sk)->icsk_bind2_hash = NULL;
- inet_bind2_bucket_destroy(hashinfo->bind2_bucket_cachep, tb2);
+ inet_bind2_bucket_destroy(tb2);
}
spin_unlock(&head2->lock);
@@ -951,7 +951,7 @@ static int __inet_bhash2_update_saddr(struct sock *sk, void *saddr, int family,
spin_lock(&head2->lock);
__sk_del_bind_node(sk);
- inet_bind2_bucket_destroy(hinfo->bind2_bucket_cachep, inet_csk(sk)->icsk_bind2_hash);
+ inet_bind2_bucket_destroy(inet_csk(sk)->icsk_bind2_hash);
spin_unlock(&head2->lock);
if (reset)
@@ -1154,7 +1154,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
inet_ehash_nolisten(sk, (struct sock *)tw, NULL);
}
if (tw)
- inet_twsk_bind_unhash(tw, hinfo);
+ inet_twsk_bind_unhash(tw);
spin_unlock(&head2->lock);
spin_unlock(&head->lock);
@@ -1179,7 +1179,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
inet_sk(sk)->inet_num = 0;
if (tw)
- inet_twsk_bind_unhash(tw, hinfo);
+ inet_twsk_bind_unhash(tw);
}
spin_unlock(&head2->lock);
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index 875ff923a8ed..ff286b179f4a 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -20,14 +20,12 @@
/**
* inet_twsk_bind_unhash - unhash a timewait socket from bind hash
* @tw: timewait socket
- * @hashinfo: hashinfo pointer
*
* unhash a timewait socket from bind hash, if hashed.
* bind hash lock must be held by caller.
* Returns 1 if caller should call inet_twsk_put() after lock release.
*/
-void inet_twsk_bind_unhash(struct inet_timewait_sock *tw,
- struct inet_hashinfo *hashinfo)
+void inet_twsk_bind_unhash(struct inet_timewait_sock *tw)
{
struct inet_bind2_bucket *tb2 = tw->tw_tb2;
struct inet_bind_bucket *tb = tw->tw_tb;
@@ -38,7 +36,7 @@ void inet_twsk_bind_unhash(struct inet_timewait_sock *tw,
__sk_del_bind_node((struct sock *)tw);
tw->tw_tb = NULL;
tw->tw_tb2 = NULL;
- inet_bind2_bucket_destroy(hashinfo->bind2_bucket_cachep, tb2);
+ inet_bind2_bucket_destroy(tb2);
inet_bind_bucket_destroy(tb);
__sock_put((struct sock *)tw);
@@ -63,7 +61,7 @@ static void inet_twsk_kill(struct inet_timewait_sock *tw)
spin_lock(&bhead->lock);
spin_lock(&bhead2->lock);
- inet_twsk_bind_unhash(tw, hashinfo);
+ inet_twsk_bind_unhash(tw);
spin_unlock(&bhead2->lock);
spin_unlock(&bhead->lock);
--
2.43.0
Powered by blists - more mailing lists