diff --git a/include/net/tcp.h b/include/net/tcp.h
index a7be6928b05e9eb14da53187a3fc87400c92897c..69630979810eed1d916be8971b7f27d01f7d10cb 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -84,16 +84,27 @@ struct tcp_ehash_bucket {
 struct tcp_bind_bucket {
 	unsigned short		port;
 	signed short		fastreuse;
-	struct tcp_bind_bucket	*next;
-	struct tcp_bind_bucket	**pprev;
+	struct hlist_node	node;
 	struct hlist_head	owners;
 };
 
+#define tb_for_each(tb, node, head) hlist_for_each_entry(tb, node, head, node)
+
 struct tcp_bind_hashbucket {
 	spinlock_t		lock;
-	struct tcp_bind_bucket	*chain;
+	struct hlist_head	chain;
 };
 
+static inline struct tcp_bind_bucket *__tb_head(struct tcp_bind_hashbucket *head)
+{
+	return hlist_entry(head->chain.first, struct tcp_bind_bucket, node);
+}
+
+static inline struct tcp_bind_bucket *tb_head(struct tcp_bind_hashbucket *head)
+{
+	return hlist_empty(&head->chain) ? NULL : __tb_head(head);
+}
+
 extern struct tcp_hashinfo {
 	/* This is for sockets with full identity only.  Sockets here will
 	 * always be without wildcards and will have the following invariant:
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index c1fbbff7546a7e6e812b4ca61839d5807d4b7564..619c4ce05f138b9c3e225619fc5c8292cffe979d 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2641,7 +2641,7 @@ void __init tcp_init(void)
 		panic("Failed to allocate TCP bind hash table\n");
 	for (i = 0; i < tcp_bhash_size; i++) {
 		tcp_bhash[i].lock = SPIN_LOCK_UNLOCKED;
-		tcp_bhash[i].chain = NULL;
+		INIT_HLIST_HEAD(&tcp_bhash[i].chain);
 	}
 
 	/* Try to be a bit smarter and adjust defaults depending
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 76ec332e3278207c3dccc576371d0dfeb4e49f40..ab2a3977c8477d64c049674a12ad3e3e19b8704f 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -134,10 +134,7 @@ struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head,
 		tb->port = snum;
 		tb->fastreuse = 0;
 		INIT_HLIST_HEAD(&tb->owners);
-		if ((tb->next = head->chain) != NULL)
-			tb->next->pprev = &tb->next;
-		head->chain = tb;
-		tb->pprev = &head->chain;
+		hlist_add_head(&tb->node, &head->chain);
 	}
 	return tb;
 }
@@ -146,9 +143,7 @@ struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head,
 void tcp_bucket_destroy(struct tcp_bind_bucket *tb)
 {
 	if (hlist_empty(&tb->owners)) {
-		if (tb->next)
-			tb->next->pprev = tb->pprev;
-		*(tb->pprev) = tb->next;
+		__hlist_del(&tb->node);
 		kmem_cache_free(tcp_bucket_cachep, tb);
 	}
 }
@@ -211,6 +206,7 @@ static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
 static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
 {
 	struct tcp_bind_hashbucket *head;
+	struct hlist_node *node;
 	struct tcp_bind_bucket *tb;
 	int ret;
 
@@ -229,7 +225,7 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
 				rover = low;
 			head = &tcp_bhash[tcp_bhashfn(rover)];
 			spin_lock(&head->lock);
-			for (tb = head->chain; tb; tb = tb->next)
+			tb_for_each(tb, node, &head->chain)
 				if (tb->port == rover)
 					goto next;
 			break;
@@ -248,15 +244,17 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
 		 * non-NULL and we hold it's mutex.
 		 */
 		snum = rover;
-		tb = NULL;
 	} else {
 		head = &tcp_bhash[tcp_bhashfn(snum)];
 		spin_lock(&head->lock);
-		for (tb = head->chain; tb; tb = tb->next)
+		tb_for_each(tb, node, &head->chain)
 			if (tb->port == snum)
-				break;
+				goto tb_found;
 	}
-	if (tb && !hlist_empty(&tb->owners)) {
+	tb = NULL;
+	goto tb_not_found;
+tb_found:
+	if (!hlist_empty(&tb->owners)) {
 		if (sk->sk_reuse > 1)
 			goto success;
 		if (tb->fastreuse > 0 &&
@@ -268,6 +266,7 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
 				goto fail_unlock;
 		}
 	}
+tb_not_found:
 	ret = 1;
 	if (!tb && (tb = tcp_bucket_create(head, snum)) == NULL)
 		goto fail_unlock;
@@ -646,6 +645,7 @@ static int tcp_v4_hash_connect(struct sock *sk)
  		int low = sysctl_local_port_range[0];
  		int high = sysctl_local_port_range[1];
  		int remaining = (high - low) + 1;
+		struct hlist_node *node;
  		struct tcp_tw_bucket *tw = NULL;
 
  		local_bh_disable();
@@ -677,7 +677,7 @@ static int tcp_v4_hash_connect(struct sock *sk)
  			 * because the established check is already
  			 * unique enough.
  			 */
- 			for (tb = head->chain; tb; tb = tb->next) {
+			tb_for_each(tb, node, &head->chain) {
  				if (tb->port == rover) {
  					BUG_TRAP(!hlist_empty(&tb->owners));
  					if (tb->fastreuse >= 0)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index c8261dd92731252f30bfed37154ec30faf140289..71ca875f7e71f8c928b865245684de5e2b5baa40 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -157,6 +157,7 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
 {
 	struct tcp_bind_hashbucket *head;
 	struct tcp_bind_bucket *tb;
+	struct hlist_node *node;
 	int ret;
 
 	local_bh_disable();
@@ -173,7 +174,7 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
 				rover = low;
 			head = &tcp_bhash[tcp_bhashfn(rover)];
 			spin_lock(&head->lock);
-			for (tb = head->chain; tb; tb = tb->next)
+			tb_for_each(tb, node, &head->chain)
 				if (tb->port == rover)
 					goto next;
 			break;
@@ -190,14 +191,16 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
 
 		/* OK, here is the one we will use. */
 		snum = rover;
-		tb = NULL;
 	} else {
 		head = &tcp_bhash[tcp_bhashfn(snum)];
 		spin_lock(&head->lock);
-		for (tb = head->chain; tb != NULL; tb = tb->next)
+		tb_for_each(tb, node, &head->chain)
 			if (tb->port == snum)
-				break;
+				goto tb_found;
 	}
+	tb = NULL;
+	goto tb_not_found;
+tb_found:
 	if (tb && !hlist_empty(&tb->owners)) {
 		if (tb->fastreuse > 0 && sk->sk_reuse &&
 		    sk->sk_state != TCP_LISTEN) {
@@ -208,9 +211,9 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
 				goto fail_unlock;
 		}
 	}
+tb_not_found:
 	ret = 1;
-	if (tb == NULL &&
-	    (tb = tcp_bucket_create(head, snum)) == NULL)
+	if (!tb && (tb = tcp_bucket_create(head, snum)) == NULL)
 		goto fail_unlock;
 	if (hlist_empty(&tb->owners)) {
 		if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
@@ -550,7 +553,7 @@ static int tcp_v6_hash_connect(struct sock *sk)
 	}
 
 	head = &tcp_bhash[tcp_bhashfn(inet_sk(sk)->num)];
-	tb = head->chain;
+	tb = tb_head(head);
 
 	spin_lock_bh(&head->lock);