diff options
author | Sowmini Varadhan <sowmini.varadhan@oracle.com> | 2016-06-30 19:11:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-01 16:45:17 -0400 |
commit | 02105b2ccdd6344146e0296172a9e0f17ff624ef (patch) | |
tree | 3be5ec1d994b348826c1cd0bf20f85441028fd39 /net/rds | |
parent | 26e4e6bb683028546f339018ab4cd394300a92a4 (diff) |
RDS: TCP: Make rds_tcp_connection track the rds_conn_path
The struct rds_tcp_connection is the transport-specific private
data structure that tracks TCP information per rds_conn_path.
Modify this structure to have a back-pointer to the rds_conn_path
for which it is the ->cp_transport_data.
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/rds')
-rw-r--r-- | net/rds/connection.c | 30 | ||||
-rw-r--r-- | net/rds/tcp.c | 44 | ||||
-rw-r--r-- | net/rds/tcp.h | 6 | ||||
-rw-r--r-- | net/rds/tcp_connect.c | 6 | ||||
-rw-r--r-- | net/rds/tcp_listen.c | 4 |
5 files changed, 48 insertions, 42 deletions
diff --git a/net/rds/connection.c b/net/rds/connection.c index 17c2f2591ac4..1b0c2a783b5e 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c | |||
@@ -253,9 +253,12 @@ static struct rds_connection *__rds_conn_create(struct net *net, | |||
253 | 253 | ||
254 | for (i = 0; i < RDS_MPATH_WORKERS; i++) { | 254 | for (i = 0; i < RDS_MPATH_WORKERS; i++) { |
255 | cp = &conn->c_path[i]; | 255 | cp = &conn->c_path[i]; |
256 | trans->conn_free(cp->cp_transport_data); | 256 | /* The ->conn_alloc invocation may have |
257 | if (!trans->t_mp_capable) | 257 | * allocated resource for all paths, so all |
258 | break; | 258 | * of them may have to be freed here. |
259 | */ | ||
260 | if (cp->cp_transport_data) | ||
261 | trans->conn_free(cp->cp_transport_data); | ||
259 | } | 262 | } |
260 | kmem_cache_free(rds_conn_slab, conn); | 263 | kmem_cache_free(rds_conn_slab, conn); |
261 | conn = found; | 264 | conn = found; |
@@ -367,6 +370,9 @@ static void rds_conn_path_destroy(struct rds_conn_path *cp) | |||
367 | { | 370 | { |
368 | struct rds_message *rm, *rtmp; | 371 | struct rds_message *rm, *rtmp; |
369 | 372 | ||
373 | if (!cp->cp_transport_data) | ||
374 | return; | ||
375 | |||
370 | rds_conn_path_drop(cp); | 376 | rds_conn_path_drop(cp); |
371 | flush_work(&cp->cp_down_w); | 377 | flush_work(&cp->cp_down_w); |
372 | 378 | ||
@@ -398,6 +404,8 @@ static void rds_conn_path_destroy(struct rds_conn_path *cp) | |||
398 | void rds_conn_destroy(struct rds_connection *conn) | 404 | void rds_conn_destroy(struct rds_connection *conn) |
399 | { | 405 | { |
400 | unsigned long flags; | 406 | unsigned long flags; |
407 | int i; | ||
408 | struct rds_conn_path *cp; | ||
401 | 409 | ||
402 | rdsdebug("freeing conn %p for %pI4 -> " | 410 | rdsdebug("freeing conn %p for %pI4 -> " |
403 | "%pI4\n", conn, &conn->c_laddr, | 411 | "%pI4\n", conn, &conn->c_laddr, |
@@ -410,18 +418,10 @@ void rds_conn_destroy(struct rds_connection *conn) | |||
410 | synchronize_rcu(); | 418 | synchronize_rcu(); |
411 | 419 | ||
412 | /* shut the connection down */ | 420 | /* shut the connection down */ |
413 | if (!conn->c_trans->t_mp_capable) { | 421 | for (i = 0; i < RDS_MPATH_WORKERS; i++) { |
414 | rds_conn_path_destroy(&conn->c_path[0]); | 422 | cp = &conn->c_path[i]; |
415 | BUG_ON(!list_empty(&conn->c_path[0].cp_retrans)); | 423 | rds_conn_path_destroy(cp); |
416 | } else { | 424 | BUG_ON(!list_empty(&cp->cp_retrans)); |
417 | int i; | ||
418 | struct rds_conn_path *cp; | ||
419 | |||
420 | for (i = 0; i < RDS_MPATH_WORKERS; i++) { | ||
421 | cp = &conn->c_path[i]; | ||
422 | rds_conn_path_destroy(cp); | ||
423 | BUG_ON(!list_empty(&cp->cp_retrans)); | ||
424 | } | ||
425 | } | 425 | } |
426 | 426 | ||
427 | /* | 427 | /* |
diff --git a/net/rds/tcp.c b/net/rds/tcp.c index c56fff28084f..c6b47f670990 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c | |||
@@ -221,7 +221,7 @@ void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn) | |||
221 | sock->sk->sk_data_ready = sock->sk->sk_user_data; | 221 | sock->sk->sk_data_ready = sock->sk->sk_user_data; |
222 | 222 | ||
223 | tc->t_sock = sock; | 223 | tc->t_sock = sock; |
224 | tc->conn = conn; | 224 | tc->t_cpath = &conn->c_path[0]; |
225 | tc->t_orig_data_ready = sock->sk->sk_data_ready; | 225 | tc->t_orig_data_ready = sock->sk->sk_data_ready; |
226 | tc->t_orig_write_space = sock->sk->sk_write_space; | 226 | tc->t_orig_write_space = sock->sk->sk_write_space; |
227 | tc->t_orig_state_change = sock->sk->sk_state_change; | 227 | tc->t_orig_state_change = sock->sk->sk_state_change; |
@@ -284,24 +284,29 @@ static int rds_tcp_laddr_check(struct net *net, __be32 addr) | |||
284 | static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) | 284 | static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) |
285 | { | 285 | { |
286 | struct rds_tcp_connection *tc; | 286 | struct rds_tcp_connection *tc; |
287 | int i; | ||
287 | 288 | ||
288 | tc = kmem_cache_alloc(rds_tcp_conn_slab, gfp); | 289 | for (i = 0; i < RDS_MPATH_WORKERS; i++) { |
289 | if (!tc) | 290 | tc = kmem_cache_alloc(rds_tcp_conn_slab, gfp); |
290 | return -ENOMEM; | 291 | if (!tc) |
292 | return -ENOMEM; | ||
291 | 293 | ||
292 | mutex_init(&tc->t_conn_lock); | 294 | mutex_init(&tc->t_conn_path_lock); |
293 | tc->t_sock = NULL; | 295 | tc->t_sock = NULL; |
294 | tc->t_tinc = NULL; | 296 | tc->t_tinc = NULL; |
295 | tc->t_tinc_hdr_rem = sizeof(struct rds_header); | 297 | tc->t_tinc_hdr_rem = sizeof(struct rds_header); |
296 | tc->t_tinc_data_rem = 0; | 298 | tc->t_tinc_data_rem = 0; |
297 | 299 | ||
298 | conn->c_transport_data = tc; | 300 | conn->c_path[i].cp_transport_data = tc; |
301 | tc->t_cpath = &conn->c_path[i]; | ||
299 | 302 | ||
300 | spin_lock_irq(&rds_tcp_conn_lock); | 303 | spin_lock_irq(&rds_tcp_conn_lock); |
301 | list_add_tail(&tc->t_tcp_node, &rds_tcp_conn_list); | 304 | list_add_tail(&tc->t_tcp_node, &rds_tcp_conn_list); |
302 | spin_unlock_irq(&rds_tcp_conn_lock); | 305 | spin_unlock_irq(&rds_tcp_conn_lock); |
306 | rdsdebug("rds_conn_path [%d] tc %p\n", i, | ||
307 | conn->c_path[i].cp_transport_data); | ||
308 | } | ||
303 | 309 | ||
304 | rdsdebug("alloced tc %p\n", conn->c_transport_data); | ||
305 | return 0; | 310 | return 0; |
306 | } | 311 | } |
307 | 312 | ||
@@ -330,7 +335,7 @@ static void rds_tcp_destroy_conns(void) | |||
330 | spin_unlock_irq(&rds_tcp_conn_lock); | 335 | spin_unlock_irq(&rds_tcp_conn_lock); |
331 | 336 | ||
332 | list_for_each_entry_safe(tc, _tc, &tmp_list, t_tcp_node) | 337 | list_for_each_entry_safe(tc, _tc, &tmp_list, t_tcp_node) |
333 | rds_conn_destroy(tc->conn); | 338 | rds_conn_destroy(tc->t_cpath->cp_conn); |
334 | } | 339 | } |
335 | 340 | ||
336 | static void rds_tcp_exit(void); | 341 | static void rds_tcp_exit(void); |
@@ -498,7 +503,7 @@ static void rds_tcp_kill_sock(struct net *net) | |||
498 | flush_work(&rtn->rds_tcp_accept_w); | 503 | flush_work(&rtn->rds_tcp_accept_w); |
499 | spin_lock_irq(&rds_tcp_conn_lock); | 504 | spin_lock_irq(&rds_tcp_conn_lock); |
500 | list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { | 505 | list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { |
501 | struct net *c_net = read_pnet(&tc->conn->c_net); | 506 | struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net); |
502 | 507 | ||
503 | if (net != c_net || !tc->t_sock) | 508 | if (net != c_net || !tc->t_sock) |
504 | continue; | 509 | continue; |
@@ -509,7 +514,7 @@ static void rds_tcp_kill_sock(struct net *net) | |||
509 | sk = tc->t_sock->sk; | 514 | sk = tc->t_sock->sk; |
510 | sk->sk_prot->disconnect(sk, 0); | 515 | sk->sk_prot->disconnect(sk, 0); |
511 | tcp_done(sk); | 516 | tcp_done(sk); |
512 | rds_conn_destroy(tc->conn); | 517 | rds_conn_destroy(tc->t_cpath->cp_conn); |
513 | } | 518 | } |
514 | } | 519 | } |
515 | 520 | ||
@@ -547,12 +552,13 @@ static void rds_tcp_sysctl_reset(struct net *net) | |||
547 | 552 | ||
548 | spin_lock_irq(&rds_tcp_conn_lock); | 553 | spin_lock_irq(&rds_tcp_conn_lock); |
549 | list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { | 554 | list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { |
550 | struct net *c_net = read_pnet(&tc->conn->c_net); | 555 | struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net); |
551 | 556 | ||
552 | if (net != c_net || !tc->t_sock) | 557 | if (net != c_net || !tc->t_sock) |
553 | continue; | 558 | continue; |
554 | 559 | ||
555 | rds_conn_drop(tc->conn); /* reconnect with new parameters */ | 560 | /* reconnect with new parameters */ |
561 | rds_conn_path_drop(tc->t_cpath); | ||
556 | } | 562 | } |
557 | spin_unlock_irq(&rds_tcp_conn_lock); | 563 | spin_unlock_irq(&rds_tcp_conn_lock); |
558 | } | 564 | } |
diff --git a/net/rds/tcp.h b/net/rds/tcp.h index 728abe22c9a3..e1ff16908c5e 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h | |||
@@ -11,11 +11,11 @@ struct rds_tcp_incoming { | |||
11 | struct rds_tcp_connection { | 11 | struct rds_tcp_connection { |
12 | 12 | ||
13 | struct list_head t_tcp_node; | 13 | struct list_head t_tcp_node; |
14 | struct rds_connection *conn; | 14 | struct rds_conn_path *t_cpath; |
15 | /* t_conn_lock synchronizes the connection establishment between | 15 | /* t_conn_path_lock synchronizes the connection establishment between |
16 | * rds_tcp_accept_one and rds_tcp_conn_connect | 16 | * rds_tcp_accept_one and rds_tcp_conn_connect |
17 | */ | 17 | */ |
18 | struct mutex t_conn_lock; | 18 | struct mutex t_conn_path_lock; |
19 | struct socket *t_sock; | 19 | struct socket *t_sock; |
20 | void *t_orig_write_space; | 20 | void *t_orig_write_space; |
21 | void *t_orig_data_ready; | 21 | void *t_orig_data_ready; |
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index aa65c1631c4b..146692c8afac 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c | |||
@@ -82,10 +82,10 @@ int rds_tcp_conn_connect(struct rds_connection *conn) | |||
82 | int ret; | 82 | int ret; |
83 | struct rds_tcp_connection *tc = conn->c_transport_data; | 83 | struct rds_tcp_connection *tc = conn->c_transport_data; |
84 | 84 | ||
85 | mutex_lock(&tc->t_conn_lock); | 85 | mutex_lock(&tc->t_conn_path_lock); |
86 | 86 | ||
87 | if (rds_conn_up(conn)) { | 87 | if (rds_conn_up(conn)) { |
88 | mutex_unlock(&tc->t_conn_lock); | 88 | mutex_unlock(&tc->t_conn_path_lock); |
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | ret = sock_create_kern(rds_conn_net(conn), PF_INET, | 91 | ret = sock_create_kern(rds_conn_net(conn), PF_INET, |
@@ -129,7 +129,7 @@ int rds_tcp_conn_connect(struct rds_connection *conn) | |||
129 | } | 129 | } |
130 | 130 | ||
131 | out: | 131 | out: |
132 | mutex_unlock(&tc->t_conn_lock); | 132 | mutex_unlock(&tc->t_conn_path_lock); |
133 | if (sock) | 133 | if (sock) |
134 | sock_release(sock); | 134 | sock_release(sock); |
135 | return ret; | 135 | return ret; |
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index f9cc945a77b3..d8933469ab13 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c | |||
@@ -121,7 +121,7 @@ int rds_tcp_accept_one(struct socket *sock) | |||
121 | */ | 121 | */ |
122 | rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data; | 122 | rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data; |
123 | rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING); | 123 | rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING); |
124 | mutex_lock(&rs_tcp->t_conn_lock); | 124 | mutex_lock(&rs_tcp->t_conn_path_lock); |
125 | conn_state = rds_conn_state(conn); | 125 | conn_state = rds_conn_state(conn); |
126 | if (conn_state != RDS_CONN_CONNECTING && conn_state != RDS_CONN_UP) | 126 | if (conn_state != RDS_CONN_CONNECTING && conn_state != RDS_CONN_UP) |
127 | goto rst_nsk; | 127 | goto rst_nsk; |
@@ -156,7 +156,7 @@ rst_nsk: | |||
156 | ret = 0; | 156 | ret = 0; |
157 | out: | 157 | out: |
158 | if (rs_tcp) | 158 | if (rs_tcp) |
159 | mutex_unlock(&rs_tcp->t_conn_lock); | 159 | mutex_unlock(&rs_tcp->t_conn_path_lock); |
160 | if (new_sock) | 160 | if (new_sock) |
161 | sock_release(new_sock); | 161 | sock_release(new_sock); |
162 | return ret; | 162 | return ret; |