aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/tcp_cong.c23
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: