diff options
-rw-r--r-- | include/net/inet_connection_sock.h | 3 | ||||
-rw-r--r-- | net/ipv4/tcp_cong.c | 5 | ||||
-rw-r--r-- | net/ipv4/tcp_minisocks.c | 5 |
3 files changed, 10 insertions, 3 deletions
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 497bc14cdb85..0320bbb7d7b5 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h | |||
@@ -98,7 +98,8 @@ struct inet_connection_sock { | |||
98 | const struct tcp_congestion_ops *icsk_ca_ops; | 98 | const struct tcp_congestion_ops *icsk_ca_ops; |
99 | const struct inet_connection_sock_af_ops *icsk_af_ops; | 99 | const struct inet_connection_sock_af_ops *icsk_af_ops; |
100 | unsigned int (*icsk_sync_mss)(struct sock *sk, u32 pmtu); | 100 | unsigned int (*icsk_sync_mss)(struct sock *sk, u32 pmtu); |
101 | __u8 icsk_ca_state:7, | 101 | __u8 icsk_ca_state:6, |
102 | icsk_ca_setsockopt:1, | ||
102 | icsk_ca_dst_locked:1; | 103 | icsk_ca_dst_locked:1; |
103 | __u8 icsk_retransmits; | 104 | __u8 icsk_retransmits; |
104 | __u8 icsk_pending; | 105 | __u8 icsk_pending; |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 7a5ae50c80c8..84be008c945c 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -187,6 +187,7 @@ static void tcp_reinit_congestion_control(struct sock *sk, | |||
187 | 187 | ||
188 | tcp_cleanup_congestion_control(sk); | 188 | tcp_cleanup_congestion_control(sk); |
189 | icsk->icsk_ca_ops = ca; | 189 | icsk->icsk_ca_ops = ca; |
190 | icsk->icsk_ca_setsockopt = 1; | ||
190 | 191 | ||
191 | if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init) | 192 | if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init) |
192 | icsk->icsk_ca_ops->init(sk); | 193 | icsk->icsk_ca_ops->init(sk); |
@@ -335,8 +336,10 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) | |||
335 | rcu_read_lock(); | 336 | rcu_read_lock(); |
336 | ca = __tcp_ca_find_autoload(name); | 337 | ca = __tcp_ca_find_autoload(name); |
337 | /* No change asking for existing value */ | 338 | /* No change asking for existing value */ |
338 | if (ca == icsk->icsk_ca_ops) | 339 | if (ca == icsk->icsk_ca_ops) { |
340 | icsk->icsk_ca_setsockopt = 1; | ||
339 | goto out; | 341 | goto out; |
342 | } | ||
340 | if (!ca) | 343 | if (!ca) |
341 | err = -ENOENT; | 344 | err = -ENOENT; |
342 | else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) || | 345 | else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) || |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index b5732a54f2ad..17e7339ee5ca 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -420,7 +420,10 @@ void tcp_ca_openreq_child(struct sock *sk, const struct dst_entry *dst) | |||
420 | rcu_read_unlock(); | 420 | rcu_read_unlock(); |
421 | } | 421 | } |
422 | 422 | ||
423 | if (!ca_got_dst && !try_module_get(icsk->icsk_ca_ops->owner)) | 423 | /* If no valid choice made yet, assign current system default ca. */ |
424 | if (!ca_got_dst && | ||
425 | (!icsk->icsk_ca_setsockopt || | ||
426 | !try_module_get(icsk->icsk_ca_ops->owner))) | ||
424 | tcp_assign_congestion_control(sk); | 427 | tcp_assign_congestion_control(sk); |
425 | 428 | ||
426 | tcp_set_ca_state(sk, TCP_CA_Open); | 429 | tcp_set_ca_state(sk, TCP_CA_Open); |