diff options
| -rw-r--r-- | net/ipv4/tcp_cong.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 5c8caf4a1244..34ae3f13483a 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
| @@ -77,18 +77,19 @@ void tcp_init_congestion_control(struct sock *sk) | |||
| 77 | struct inet_connection_sock *icsk = inet_csk(sk); | 77 | struct inet_connection_sock *icsk = inet_csk(sk); |
| 78 | struct tcp_congestion_ops *ca; | 78 | struct tcp_congestion_ops *ca; |
| 79 | 79 | ||
| 80 | if (icsk->icsk_ca_ops != &tcp_init_congestion_ops) | 80 | /* if no choice made yet assign the current value set as default */ |
| 81 | return; | 81 | if (icsk->icsk_ca_ops == &tcp_init_congestion_ops) { |
| 82 | rcu_read_lock(); | ||
| 83 | list_for_each_entry_rcu(ca, &tcp_cong_list, list) { | ||
| 84 | if (try_module_get(ca->owner)) { | ||
| 85 | icsk->icsk_ca_ops = ca; | ||
| 86 | break; | ||
| 87 | } | ||
| 82 | 88 | ||
| 83 | rcu_read_lock(); | 89 | /* fallback to next available */ |
| 84 | list_for_each_entry_rcu(ca, &tcp_cong_list, list) { | ||
| 85 | if (try_module_get(ca->owner)) { | ||
| 86 | icsk->icsk_ca_ops = ca; | ||
| 87 | break; | ||
| 88 | } | 90 | } |
| 89 | 91 | rcu_read_unlock(); | |
| 90 | } | 92 | } |
| 91 | rcu_read_unlock(); | ||
| 92 | 93 | ||
| 93 | if (icsk->icsk_ca_ops->init) | 94 | if (icsk->icsk_ca_ops->init) |
| 94 | icsk->icsk_ca_ops->init(sk); | 95 | icsk->icsk_ca_ops->init(sk); |
| @@ -236,6 +237,7 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) | |||
| 236 | 237 | ||
| 237 | rcu_read_lock(); | 238 | rcu_read_lock(); |
| 238 | ca = tcp_ca_find(name); | 239 | ca = tcp_ca_find(name); |
| 240 | |||
| 239 | /* no change asking for existing value */ | 241 | /* no change asking for existing value */ |
| 240 | if (ca == icsk->icsk_ca_ops) | 242 | if (ca == icsk->icsk_ca_ops) |
| 241 | goto out; | 243 | goto out; |
| @@ -261,7 +263,8 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) | |||
| 261 | else { | 263 | else { |
| 262 | tcp_cleanup_congestion_control(sk); | 264 | tcp_cleanup_congestion_control(sk); |
| 263 | icsk->icsk_ca_ops = ca; | 265 | icsk->icsk_ca_ops = ca; |
| 264 | if (icsk->icsk_ca_ops->init) | 266 | |
| 267 | if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init) | ||
| 265 | icsk->icsk_ca_ops->init(sk); | 268 | icsk->icsk_ca_ops->init(sk); |
| 266 | } | 269 | } |
| 267 | out: | 270 | out: |
