Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ac705b1 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

tcp: remove tcp_ecn_make_synack() socket argument



SYNACK packets might be sent without holding socket lock.

For DCTCP/ECN sake, we should call INET_ECN_xmit() while
socket lock is owned, and only when we init/change congestion control.

This also fixies a bug if congestion module is changed from
dctcp to another one on a listener : we now clear ECN bits
properly.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 37bfbdda
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -173,6 +173,10 @@ void tcp_assign_congestion_control(struct sock *sk)
	 */
	if (ca->get_info)
		memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv));
	if (ca->flags & TCP_CONG_NEEDS_ECN)
		INET_ECN_xmit(sk);
	else
		INET_ECN_dontxmit(sk);
}

void tcp_init_congestion_control(struct sock *sk)
@@ -181,6 +185,10 @@ void tcp_init_congestion_control(struct sock *sk)

	if (icsk->icsk_ca_ops->init)
		icsk->icsk_ca_ops->init(sk);
	if (tcp_ca_needs_ecn(sk))
		INET_ECN_xmit(sk);
	else
		INET_ECN_dontxmit(sk);
}

static void tcp_reinit_congestion_control(struct sock *sk,
@@ -192,8 +200,8 @@ static void tcp_reinit_congestion_control(struct sock *sk,
	icsk->icsk_ca_ops = ca;
	icsk->icsk_ca_setsockopt = 1;

	if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init)
		icsk->icsk_ca_ops->init(sk);
	if (sk->sk_state != TCP_CLOSE)
		tcp_init_congestion_control(sk);
}

/* Manage refcounts on socket close. */
+3 −7
Original line number Diff line number Diff line
@@ -357,14 +357,10 @@ static void tcp_ecn_clear_syn(struct sock *sk, struct sk_buff *skb)
}

static void
tcp_ecn_make_synack(const struct request_sock *req, struct tcphdr *th,
		    struct sock *sk)
tcp_ecn_make_synack(const struct request_sock *req, struct tcphdr *th)
{
	if (inet_rsk(req)->ecn_ok) {
	if (inet_rsk(req)->ecn_ok)
		th->ece = 1;
		if (tcp_ca_needs_ecn(sk))
			INET_ECN_xmit(sk);
	}
}

/* Set up ECN state for a packet on a ESTABLISHED socket that is about to
@@ -2998,7 +2994,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
	memset(th, 0, sizeof(struct tcphdr));
	th->syn = 1;
	th->ack = 1;
	tcp_ecn_make_synack(req, th, sk);
	tcp_ecn_make_synack(req, th);
	th->source = htons(ireq->ir_num);
	th->dest = ireq->ir_rmt_port;
	/* Setting of flags are superfluous here for callers (and ECE is