diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 405670d7661d..53c22b64e972 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -111,6 +111,7 @@ struct inet_bind_hashbucket { #define LISTENING_NULLS_BASE (1U << 29) struct inet_listen_hashbucket { spinlock_t lock; + unsigned int count; union { struct hlist_head head; struct hlist_nulls_head nulls_head; diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 8e0451248fc0..2936676f86eb 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -209,6 +209,7 @@ static void inet_hash2(struct inet_hashinfo *h, struct sock *sk) else hlist_add_head_rcu(&inet_csk(sk)->icsk_listen_portaddr_node, &ilb2->head); + ilb2->count++; spin_unlock(&ilb2->lock); } @@ -224,6 +225,7 @@ static void inet_unhash2(struct inet_hashinfo *h, struct sock *sk) spin_lock(&ilb2->lock); hlist_del_init_rcu(&inet_csk(sk)->icsk_listen_portaddr_node); + ilb2->count--; spin_unlock(&ilb2->lock); } @@ -650,6 +652,7 @@ int __inet_hash(struct sock *sk, struct sock *osk) else __sk_nulls_add_node_rcu(sk, &ilb->nulls_head); inet_hash2(hashinfo, sk); + ilb->count++; sock_set_flag(sk, SOCK_RCU_FREE); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); unlock: @@ -681,6 +684,7 @@ static void __inet_unhash(struct sock *sk, struct inet_listen_hashbucket *ilb) struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; inet_unhash2(hashinfo, sk); + ilb->count--; } __sk_nulls_del_node_init_rcu(sk); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); @@ -863,6 +867,7 @@ void inet_hashinfo_init(struct inet_hashinfo *h) spin_lock_init(&h->listening_hash[i].lock); INIT_HLIST_NULLS_HEAD(&h->listening_hash[i].nulls_head, i + LISTENING_NULLS_BASE); + h->listening_hash[i].count = 0; } h->lhash2 = NULL; @@ -876,6 +881,7 @@ static void init_hashinfo_lhash2(struct inet_hashinfo *h) for (i = 0; i <= h->lhash2_mask; i++) { spin_lock_init(&h->lhash2[i].lock); INIT_HLIST_HEAD(&h->lhash2[i].head); + h->lhash2[i].count = 0; } }