Commit d186f405 authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski
Browse files

tcp: add RCU management to inet_bind_bucket



Add RCU protection to inet_bind_bucket structure.

- Add rcu_head field to the structure definition.

- Use kfree_rcu() at destroy time, and remove inet_bind_bucket_destroy()
  first argument.

- Use hlist_del_rcu() and hlist_add_head_rcu() methods.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarJason Xing <kerneljasonxing@gmail.com>
Reviewed-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250302124237.3913746-4-edumazet@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ca79d80b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ struct inet_bind_bucket {
	bool			fast_ipv6_only;
	struct hlist_node	node;
	struct hlist_head	bhash2;
	struct rcu_head		rcu;
};

struct inet_bind2_bucket {
@@ -226,8 +227,7 @@ struct inet_bind_bucket *
inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net,
			struct inet_bind_hashbucket *head,
			const unsigned short snum, int l3mdev);
void inet_bind_bucket_destroy(struct kmem_cache *cachep,
			      struct inet_bind_bucket *tb);
void inet_bind_bucket_destroy(struct inet_bind_bucket *tb);

bool inet_bind_bucket_match(const struct inet_bind_bucket *tb,
			    const struct net *net, unsigned short port,
+1 −1
Original line number Diff line number Diff line
@@ -598,7 +598,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
		if (bhash2_created)
			inet_bind2_bucket_destroy(hinfo->bind2_bucket_cachep, tb2);
		if (bhash_created)
			inet_bind_bucket_destroy(hinfo->bind_bucket_cachep, tb);
			inet_bind_bucket_destroy(tb);
	}
	if (head2_lock_acquired)
		spin_unlock(&head2->lock);
+7 −7
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
		tb->fastreuse = 0;
		tb->fastreuseport = 0;
		INIT_HLIST_HEAD(&tb->bhash2);
		hlist_add_head(&tb->node, &head->chain);
		hlist_add_head_rcu(&tb->node, &head->chain);
	}
	return tb;
}
@@ -84,11 +84,11 @@ struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
/*
 * Caller must hold hashbucket lock for this tb with local BH disabled
 */
void inet_bind_bucket_destroy(struct kmem_cache *cachep, struct inet_bind_bucket *tb)
void inet_bind_bucket_destroy(struct inet_bind_bucket *tb)
{
	if (hlist_empty(&tb->bhash2)) {
		__hlist_del(&tb->node);
		kmem_cache_free(cachep, tb);
		hlist_del_rcu(&tb->node);
		kfree_rcu(tb, rcu);
	}
}

@@ -201,7 +201,7 @@ static void __inet_put_port(struct sock *sk)
	}
	spin_unlock(&head2->lock);

	inet_bind_bucket_destroy(hashinfo->bind_bucket_cachep, tb);
	inet_bind_bucket_destroy(tb);
	spin_unlock(&head->lock);
}

@@ -285,7 +285,7 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)

error:
	if (created_inet_bind_bucket)
		inet_bind_bucket_destroy(table->bind_bucket_cachep, tb);
		inet_bind_bucket_destroy(tb);
	spin_unlock(&head2->lock);
	spin_unlock(&head->lock);
	return -ENOMEM;
@@ -1162,7 +1162,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,

	spin_unlock(&head2->lock);
	if (tb_created)
		inet_bind_bucket_destroy(hinfo->bind_bucket_cachep, tb);
		inet_bind_bucket_destroy(tb);
	spin_unlock(&head->lock);

	if (tw)
+1 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ void inet_twsk_bind_unhash(struct inet_timewait_sock *tw,
	tw->tw_tb = NULL;
	tw->tw_tb2 = NULL;
	inet_bind2_bucket_destroy(hashinfo->bind2_bucket_cachep, tb2);
	inet_bind_bucket_destroy(hashinfo->bind_bucket_cachep, tb);
	inet_bind_bucket_destroy(tb);

	__sock_put((struct sock *)tw);
}