tcp: Link bhash2 to bhash.
authorKuniyuki Iwashima <kuniyu@amazon.com>
Tue, 19 Dec 2023 00:18:27 +0000 (09:18 +0900)
committerDavid S. Miller <davem@davemloft.net>
Fri, 22 Dec 2023 22:15:34 +0000 (22:15 +0000)
bhash2 added a new member sk_bind2_node in struct sock to link
sockets to bhash2 in addition to bhash.

bhash is still needed to search conflicting sockets efficiently
from a port for the wildcard address.  However, bhash itself need
not have sockets.

If we link each bhash2 bucket to the corresponding bhash bucket,
we can iterate the same set of the sockets from bhash2 via bhash.

This patch links bhash2 to bhash only, and the actual use will be
in the later patches.  Finally, we will remove sk_bind2_node.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/inet_hashtables.h
net/ipv4/inet_connection_sock.c
net/ipv4/inet_hashtables.c

index 260e673ede2222be7fb713c33b6b11ee34eeab0b..25ba471ba1616d9e77dec7d515c4e977855042ce 100644 (file)
@@ -89,6 +89,7 @@ struct inet_bind_bucket {
        bool                    fast_ipv6_only;
        struct hlist_node       node;
        struct hlist_head       owners;
+       struct hlist_head       bhash2;
 };
 
 struct inet_bind2_bucket {
@@ -104,6 +105,7 @@ struct inet_bind2_bucket {
 #endif
        /* Node in the bhash2 inet_bind_hashbucket chain */
        struct hlist_node       node;
+       struct hlist_node       bhash_node;
        /* List of sockets hashed to this bucket */
        struct hlist_head       owners;
        /* bhash has twsk in owners, but bhash2 has twsk in
@@ -239,7 +241,7 @@ bool inet_bind_bucket_match(const struct inet_bind_bucket *tb,
 struct inet_bind2_bucket *
 inet_bind2_bucket_create(struct kmem_cache *cachep, struct net *net,
                         struct inet_bind_hashbucket *head,
-                        unsigned short port, int l3mdev,
+                        struct inet_bind_bucket *tb,
                         const struct sock *sk);
 
 void inet_bind2_bucket_destroy(struct kmem_cache *cachep,
index d48255875f605865982c89a9766bcda60470666d..8b29056f454dc5f1d2abc00fc682e643790a5930 100644 (file)
@@ -572,7 +572,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
 
        if (!tb2) {
                tb2 = inet_bind2_bucket_create(hinfo->bind2_bucket_cachep,
-                                              net, head2, port, l3mdev, sk);
+                                              net, head2, tb, sk);
                if (!tb2)
                        goto fail_unlock;
                bhash2_created = true;
index 0a99197557091ae014451e19dc21a32ba316b1f7..7dc33dd1ba35d1d6ffdb3616e188da178f7718c7 100644 (file)
@@ -77,6 +77,7 @@ struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
                tb->fastreuse = 0;
                tb->fastreuseport = 0;
                INIT_HLIST_HEAD(&tb->owners);
+               INIT_HLIST_HEAD(&tb->bhash2);
                hlist_add_head(&tb->node, &head->chain);
        }
        return tb;
@@ -103,12 +104,12 @@ bool inet_bind_bucket_match(const struct inet_bind_bucket *tb, const struct net
 static void inet_bind2_bucket_init(struct inet_bind2_bucket *tb2,
                                   struct net *net,
                                   struct inet_bind_hashbucket *head,
-                                  unsigned short port, int l3mdev,
+                                  struct inet_bind_bucket *tb,
                                   const struct sock *sk)
 {
        write_pnet(&tb2->ib_net, net);
-       tb2->l3mdev = l3mdev;
-       tb2->port = port;
+       tb2->l3mdev = tb->l3mdev;
+       tb2->port = tb->port;
 #if IS_ENABLED(CONFIG_IPV6)
        BUILD_BUG_ON(USHRT_MAX < (IPV6_ADDR_ANY | IPV6_ADDR_MAPPED));
        if (sk->sk_family == AF_INET6) {
@@ -124,19 +125,19 @@ static void inet_bind2_bucket_init(struct inet_bind2_bucket *tb2,
        INIT_HLIST_HEAD(&tb2->owners);
        INIT_HLIST_HEAD(&tb2->deathrow);
        hlist_add_head(&tb2->node, &head->chain);
+       hlist_add_head(&tb2->bhash_node, &tb->bhash2);
 }
 
 struct inet_bind2_bucket *inet_bind2_bucket_create(struct kmem_cache *cachep,
                                                   struct net *net,
                                                   struct inet_bind_hashbucket *head,
-                                                  unsigned short port,
-                                                  int l3mdev,
+                                                  struct inet_bind_bucket *tb,
                                                   const struct sock *sk)
 {
        struct inet_bind2_bucket *tb2 = kmem_cache_alloc(cachep, GFP_ATOMIC);
 
        if (tb2)
-               inet_bind2_bucket_init(tb2, net, head, port, l3mdev, sk);
+               inet_bind2_bucket_init(tb2, net, head, tb, sk);
 
        return tb2;
 }
@@ -146,6 +147,7 @@ void inet_bind2_bucket_destroy(struct kmem_cache *cachep, struct inet_bind2_buck
 {
        if (hlist_empty(&tb->owners) && hlist_empty(&tb->deathrow)) {
                __hlist_del(&tb->node);
+               __hlist_del(&tb->bhash_node);
                kmem_cache_free(cachep, tb);
        }
 }
@@ -273,8 +275,7 @@ bhash2_find:
                tb2 = inet_bind2_bucket_find(head2, net, port, l3mdev, child);
                if (!tb2) {
                        tb2 = inet_bind2_bucket_create(table->bind2_bucket_cachep,
-                                                      net, head2, port,
-                                                      l3mdev, child);
+                                                      net, head2, tb, child);
                        if (!tb2)
                                goto error;
                }
@@ -954,7 +955,7 @@ static int __inet_bhash2_update_saddr(struct sock *sk, void *saddr, int family,
        tb2 = inet_bind2_bucket_find(head2, net, port, l3mdev, sk);
        if (!tb2) {
                tb2 = new_tb2;
-               inet_bind2_bucket_init(tb2, net, head2, port, l3mdev, sk);
+               inet_bind2_bucket_init(tb2, net, head2, inet_csk(sk)->icsk_bind_hash, sk);
        }
        sk_add_bind2_node(sk, &tb2->owners);
        inet_csk(sk)->icsk_bind2_hash = tb2;
@@ -1101,7 +1102,7 @@ ok:
        tb2 = inet_bind2_bucket_find(head2, net, port, l3mdev, sk);
        if (!tb2) {
                tb2 = inet_bind2_bucket_create(hinfo->bind2_bucket_cachep, net,
-                                              head2, port, l3mdev, sk);
+                                              head2, tb, sk);
                if (!tb2)
                        goto error;
        }