aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds
diff options
context:
space:
mode:
authorSowmini Varadhan <sowmini.varadhan@oracle.com>2016-06-30 19:11:12 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-01 16:45:17 -0400
commit02105b2ccdd6344146e0296172a9e0f17ff624ef (patch)
tree3be5ec1d994b348826c1cd0bf20f85441028fd39 /net/rds
parent26e4e6bb683028546f339018ab4cd394300a92a4 (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.c30
-rw-r--r--net/rds/tcp.c44
-rw-r--r--net/rds/tcp.h6
-rw-r--r--net/rds/tcp_connect.c6
-rw-r--r--net/rds/tcp_listen.c4
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)
398void rds_conn_destroy(struct rds_connection *conn) 404void 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)
284static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) 284static 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
336static void rds_tcp_exit(void); 341static 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 {
11struct rds_tcp_connection { 11struct 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
131out: 131out:
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;
157out: 157out:
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;