[TCP]: Congestion control initialization.
Change to defer congestion control initialization. If setsockopt() was used to change TCP_CONGESTION before connection is established, then protocols that use sequence numbers to keep track of one RTT interval (vegas, illinois, ...) get confused. Change the init hook to be called after handshake. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c445a31cd7
commit
4d4d3d1e88
1 changed files with 13 additions and 10 deletions
|
@ -77,18 +77,19 @@ void tcp_init_congestion_control(struct sock *sk)
|
|||
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
struct tcp_congestion_ops *ca;
|
||||
|
||||
if (icsk->icsk_ca_ops != &tcp_init_congestion_ops)
|
||||
return;
|
||||
/* if no choice made yet assign the current value set as default */
|
||||
if (icsk->icsk_ca_ops == &tcp_init_congestion_ops) {
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
|
||||
if (try_module_get(ca->owner)) {
|
||||
icsk->icsk_ca_ops = ca;
|
||||
break;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
|
||||
if (try_module_get(ca->owner)) {
|
||||
icsk->icsk_ca_ops = ca;
|
||||
break;
|
||||
/* fallback to next available */
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (icsk->icsk_ca_ops->init)
|
||||
icsk->icsk_ca_ops->init(sk);
|
||||
|
@ -236,6 +237,7 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
|
|||
|
||||
rcu_read_lock();
|
||||
ca = tcp_ca_find(name);
|
||||
|
||||
/* no change asking for existing value */
|
||||
if (ca == icsk->icsk_ca_ops)
|
||||
goto out;
|
||||
|
@ -261,7 +263,8 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
|
|||
else {
|
||||
tcp_cleanup_congestion_control(sk);
|
||||
icsk->icsk_ca_ops = ca;
|
||||
if (icsk->icsk_ca_ops->init)
|
||||
|
||||
if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init)
|
||||
icsk->icsk_ca_ops->init(sk);
|
||||
}
|
||||
out:
|
||||
|
|
Loading…
Reference in a new issue