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

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
...@@ -173,6 +173,10 @@ void tcp_assign_congestion_control(struct sock *sk) ...@@ -173,6 +173,10 @@ void tcp_assign_congestion_control(struct sock *sk)
*/ */
if (ca->get_info) if (ca->get_info)
memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); 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) void tcp_init_congestion_control(struct sock *sk)
...@@ -181,6 +185,10 @@ 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) if (icsk->icsk_ca_ops->init)
icsk->icsk_ca_ops->init(sk); 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, static void tcp_reinit_congestion_control(struct sock *sk,
...@@ -192,8 +200,8 @@ 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_ops = ca;
icsk->icsk_ca_setsockopt = 1; icsk->icsk_ca_setsockopt = 1;
if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init) if (sk->sk_state != TCP_CLOSE)
icsk->icsk_ca_ops->init(sk); tcp_init_congestion_control(sk);
} }
/* Manage refcounts on socket close. */ /* Manage refcounts on socket close. */
......
...@@ -357,14 +357,10 @@ static void tcp_ecn_clear_syn(struct sock *sk, struct sk_buff *skb) ...@@ -357,14 +357,10 @@ static void tcp_ecn_clear_syn(struct sock *sk, struct sk_buff *skb)
} }
static void static void
tcp_ecn_make_synack(const struct request_sock *req, struct tcphdr *th, tcp_ecn_make_synack(const struct request_sock *req, struct tcphdr *th)
struct sock *sk)
{ {
if (inet_rsk(req)->ecn_ok) { if (inet_rsk(req)->ecn_ok)
th->ece = 1; 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 /* 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, ...@@ -2998,7 +2994,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
memset(th, 0, sizeof(struct tcphdr)); memset(th, 0, sizeof(struct tcphdr));
th->syn = 1; th->syn = 1;
th->ack = 1; th->ack = 1;
tcp_ecn_make_synack(req, th, sk); tcp_ecn_make_synack(req, th);
th->source = htons(ireq->ir_num); th->source = htons(ireq->ir_num);
th->dest = ireq->ir_rmt_port; th->dest = ireq->ir_rmt_port;
/* Setting of flags are superfluous here for callers (and ECE is /* Setting of flags are superfluous here for callers (and ECE is
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment