Commit 45cb3c6f authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'tcp-clean-up-syn-ack-rto-code-and-apply-max-rto'

Kuniyuki Iwashima says:

====================
tcp: Clean up SYN+ACK RTO code and apply max RTO.

Patch 1 - 4 are misc cleanup.

Patch 5 applies max RTO to non-TFO SYN+ACK.

Patch 6 adds a test for max RTO of SYN+ACK.
====================

Link: https://patch.msgid.link/20251106003357.273403-1-kuniyu@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents c6934c4e ffc56c90
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -267,8 +267,7 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
struct sock *inet_csk_reqsk_queue_add(struct sock *sk,
				      struct request_sock *req,
				      struct sock *child);
bool inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
				   unsigned long timeout);
bool inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req);
struct sock *inet_csk_complete_hashdance(struct sock *sk, struct sock *child,
					 struct request_sock *req,
					 bool own_req);
@@ -291,14 +290,6 @@ static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk)
bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req);
void inet_csk_reqsk_queue_drop_and_put(struct sock *sk, struct request_sock *req);

static inline unsigned long
reqsk_timeout(struct request_sock *req, unsigned long max_timeout)
{
	u64 timeout = (u64)req->timeout << req->num_timeout;

	return (unsigned long)min_t(u64, timeout, max_timeout);
}

void inet_csk_destroy_sock(struct sock *sk);
void inet_csk_prepare_for_destroy_sock(struct sock *sk);
void inet_csk_prepare_forced_close(struct sock *sk);
+0 −1
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ struct request_sock_ops {
				      struct sk_buff *skb,
				      enum sk_rst_reason reason);
	void		(*destructor)(struct request_sock *req);
	void		(*syn_ack_timeout)(const struct request_sock *req);
};

struct saved_syn {
+8 −0
Original line number Diff line number Diff line
@@ -841,6 +841,14 @@ static inline u32 __tcp_set_rto(const struct tcp_sock *tp)
	return usecs_to_jiffies((tp->srtt_us >> 3) + tp->rttvar_us);
}

static inline unsigned long tcp_reqsk_timeout(struct request_sock *req)
{
	u64 timeout = (u64)req->timeout << req->num_timeout;

	return (unsigned long)min_t(u64, timeout,
				    tcp_rto_max(req->rsk_listener));
}

u32 tcp_delack_max(const struct sock *sk);

/* Compute the actual rto_min value */
+9 −10
Original line number Diff line number Diff line
@@ -885,7 +885,6 @@ reqsk_alloc_noprof(const struct request_sock_ops *ops, struct sock *sk_listener,
	sk_tx_queue_clear(req_to_sk(req));
	req->saved_syn = NULL;
	req->syncookie = 0;
	req->timeout = 0;
	req->num_timeout = 0;
	req->num_retrans = 0;
	req->sk = NULL;
@@ -913,7 +912,6 @@ struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops,
		ireq->ireq_state = TCP_NEW_SYN_RECV;
		write_pnet(&ireq->ireq_net, sock_net(sk_listener));
		ireq->ireq_family = sk_listener->sk_family;
		req->timeout = TCP_TIMEOUT_INIT;
	}

	return req;
@@ -1096,16 +1094,18 @@ static void reqsk_timer_handler(struct timer_list *t)
			young <<= 1;
		}
	}

	syn_ack_recalc(req, max_syn_ack_retries, READ_ONCE(queue->rskq_defer_accept),
		       &expire, &resend);
	req->rsk_ops->syn_ack_timeout(req);
	tcp_syn_ack_timeout(req);

	if (!expire &&
	    (!resend ||
	     !tcp_rtx_synack(sk_listener, req) ||
	     inet_rsk(req)->acked)) {
		if (req->num_timeout++ == 0)
			atomic_dec(&queue->young);
		mod_timer(&req->rsk_timer, jiffies + reqsk_timeout(req, TCP_RTO_MAX));
		mod_timer(&req->rsk_timer, jiffies + tcp_reqsk_timeout(req));

		if (!nreq)
			return;
@@ -1142,8 +1142,7 @@ static void reqsk_timer_handler(struct timer_list *t)
	reqsk_put(oreq);
}

static bool reqsk_queue_hash_req(struct request_sock *req,
				 unsigned long timeout)
static bool reqsk_queue_hash_req(struct request_sock *req)
{
	bool found_dup_sk = false;

@@ -1151,8 +1150,9 @@ static bool reqsk_queue_hash_req(struct request_sock *req,
		return false;

	/* The timer needs to be setup after a successful insertion. */
	req->timeout = tcp_timeout_init((struct sock *)req);
	timer_setup(&req->rsk_timer, reqsk_timer_handler, TIMER_PINNED);
	mod_timer(&req->rsk_timer, jiffies + timeout);
	mod_timer(&req->rsk_timer, jiffies + req->timeout);

	/* before letting lookups find us, make sure all req fields
	 * are committed to memory and refcnt initialized.
@@ -1162,10 +1162,9 @@ static bool reqsk_queue_hash_req(struct request_sock *req,
	return true;
}

bool inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
				   unsigned long timeout)
bool inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req)
{
	if (!reqsk_queue_hash_req(req, timeout))
	if (!reqsk_queue_hash_req(req))
		return false;

	inet_csk_reqsk_queue_added(sk);
+5 −9
Original line number Diff line number Diff line
@@ -7531,16 +7531,12 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
		sock_put(fastopen_sk);
	} else {
		tcp_rsk(req)->tfo_listener = false;
		if (!want_cookie) {
			req->timeout = tcp_timeout_init((struct sock *)req);
			if (unlikely(!inet_csk_reqsk_queue_hash_add(sk, req,
								    req->timeout))) {
		if (!want_cookie &&
		    unlikely(!inet_csk_reqsk_queue_hash_add(sk, req))) {
			reqsk_free(req);
			dst_release(dst);
			return 0;
		}

		}
		af_ops->send_synack(sk, dst, &fl, req, &foc,
				    !want_cookie ? TCP_SYNACK_NORMAL :
						   TCP_SYNACK_COOKIE,
Loading