inet: drop prev pointer handling in request sock

When request sock are put in ehash table, the whole notion
of having a previous request to update dl_next is pointless.

Also, following patch will get rid of big purge timer,
so we want to delete a request sock without holding listener lock.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h
index 74af137..15bd408 100644
--- a/include/net/inet6_connection_sock.h
+++ b/include/net/inet6_connection_sock.h
@@ -29,7 +29,6 @@
 				      const struct request_sock *req);
 
 struct request_sock *inet6_csk_search_req(const struct sock *sk,
-					  struct request_sock ***prevp,
 					  const __be16 rport,
 					  const struct in6_addr *raddr,
 					  const struct in6_addr *laddr,
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index b9a6b0a..423a461 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -257,7 +257,6 @@
 struct sock *inet_csk_accept(struct sock *sk, int flags, int *err);
 
 struct request_sock *inet_csk_search_req(const struct sock *sk,
-					 struct request_sock ***prevp,
 					 const __be16 rport,
 					 const __be32 raddr,
 					 const __be32 laddr);
@@ -310,17 +309,15 @@
 }
 
 static inline void inet_csk_reqsk_queue_unlink(struct sock *sk,
-					       struct request_sock *req,
-					       struct request_sock **prev)
+					       struct request_sock *req)
 {
-	reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req, prev);
+	reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req);
 }
 
 static inline void inet_csk_reqsk_queue_drop(struct sock *sk,
-					     struct request_sock *req,
-					     struct request_sock **prev)
+					     struct request_sock *req)
 {
-	inet_csk_reqsk_queue_unlink(sk, req, prev);
+	inet_csk_reqsk_queue_unlink(sk, req);
 	inet_csk_reqsk_queue_removed(sk, req);
 	reqsk_free(req);
 }
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index e7ef863..6522390 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -50,6 +50,7 @@
 struct request_sock {
 	struct sock_common		__req_common;
 #define rsk_refcnt			__req_common.skc_refcnt
+#define rsk_hash			__req_common.skc_hash
 
 	struct request_sock		*dl_next;
 	struct sock			*rsk_listener;
@@ -216,11 +217,16 @@
 }
 
 static inline void reqsk_queue_unlink(struct request_sock_queue *queue,
-				      struct request_sock *req,
-				      struct request_sock **prev_req)
+				      struct request_sock *req)
 {
+	struct listen_sock *lopt = queue->listen_opt;
+	struct request_sock **prev;
+
 	write_lock(&queue->syn_wait_lock);
-	*prev_req = req->dl_next;
+	prev = &lopt->syn_table[req->rsk_hash];
+	while (*prev != req)
+		prev = &(*prev)->dl_next;
+	*prev = req->dl_next;
 	write_unlock(&queue->syn_wait_lock);
 }
 
@@ -300,7 +306,6 @@
 	req->num_retrans = 0;
 	req->num_timeout = 0;
 	req->sk = NULL;
-	req->dl_next = lopt->syn_table[hash];
 
 	/* before letting lookups find us, make sure all req fields
 	 * are committed to memory and refcnt initialized.
@@ -308,7 +313,9 @@
 	smp_wmb();
 	atomic_set(&req->rsk_refcnt, 1);
 
+	req->rsk_hash = hash;
 	write_lock(&queue->syn_wait_lock);
+	req->dl_next = lopt->syn_table[hash];
 	lopt->syn_table[hash] = req;
 	write_unlock(&queue->syn_wait_lock);
 }
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 5b29835..082fd79 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -406,8 +406,7 @@
 					      struct sk_buff *skb,
 					      const struct tcphdr *th);
 struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
-			   struct request_sock *req, struct request_sock **prev,
-			   bool fastopen);
+			   struct request_sock *req, bool fastopen);
 int tcp_child_process(struct sock *parent, struct sock *child,
 		      struct sk_buff *skb);
 void tcp_enter_loss(struct sock *sk);