diff options
author | Sowmini Varadhan <sowmini.varadhan@oracle.com> | 2016-06-13 12:44:26 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-15 02:50:41 -0400 |
commit | 0cb43965d42a21a7af41f88f1021b478dc102425 (patch) | |
tree | 628e5ac505d94dd9cf1f2551737d9139eb58662f | |
parent | dcf1158b275f9d51d6a742cf7166edc764ee4718 (diff) |
RDS: split out connection specific state from rds_connection to rds_conn_path
In preparation for multipath RDS, split the rds_connection
structure into a base structure, and a per-path struct rds_conn_path.
The base structure tracks information and locks common to all
paths. The workqs for send/recv/shutdown etc are tracked per
rds_conn_path. Thus the workq callbacks now work with rds_conn_path.
This commit allows for one rds_conn_path per rds_connection, and will
be extended into multiple conn_paths in subsequent commits.
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/rds/cong.c | 3 | ||||
-rw-r--r-- | net/rds/connection.c | 18 | ||||
-rw-r--r-- | net/rds/ib.c | 1 | ||||
-rw-r--r-- | net/rds/ib_cm.c | 1 | ||||
-rw-r--r-- | net/rds/ib_rdma.c | 1 | ||||
-rw-r--r-- | net/rds/ib_recv.c | 1 | ||||
-rw-r--r-- | net/rds/ib_send.c | 1 | ||||
-rw-r--r-- | net/rds/loop.c | 1 | ||||
-rw-r--r-- | net/rds/rdma_transport.c | 1 | ||||
-rw-r--r-- | net/rds/rds.h | 122 | ||||
-rw-r--r-- | net/rds/rds_single_path.h | 30 | ||||
-rw-r--r-- | net/rds/recv.c | 1 | ||||
-rw-r--r-- | net/rds/send.c | 1 | ||||
-rw-r--r-- | net/rds/tcp.c | 1 | ||||
-rw-r--r-- | net/rds/tcp_connect.c | 4 | ||||
-rw-r--r-- | net/rds/tcp_listen.c | 11 | ||||
-rw-r--r-- | net/rds/tcp_recv.c | 1 | ||||
-rw-r--r-- | net/rds/tcp_send.c | 1 | ||||
-rw-r--r-- | net/rds/threads.c | 92 |
19 files changed, 199 insertions, 93 deletions
diff --git a/net/rds/cong.c b/net/rds/cong.c index 6641bcf7c185..8398fee7c866 100644 --- a/net/rds/cong.c +++ b/net/rds/cong.c | |||
@@ -235,7 +235,8 @@ void rds_cong_queue_updates(struct rds_cong_map *map) | |||
235 | * therefore trigger warnings. | 235 | * therefore trigger warnings. |
236 | * Defer the xmit to rds_send_worker() instead. | 236 | * Defer the xmit to rds_send_worker() instead. |
237 | */ | 237 | */ |
238 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); | 238 | queue_delayed_work(rds_wq, |
239 | &conn->c_path[0].cp_send_w, 0); | ||
239 | } | 240 | } |
240 | } | 241 | } |
241 | 242 | ||
diff --git a/net/rds/connection.c b/net/rds/connection.c index e3b118cae81d..6fa2074044b9 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/export.h> | 36 | #include <linux/export.h> |
37 | #include <net/inet_hashtables.h> | 37 | #include <net/inet_hashtables.h> |
38 | 38 | ||
39 | #include "rds_single_path.h" | ||
39 | #include "rds.h" | 40 | #include "rds.h" |
40 | #include "loop.h" | 41 | #include "loop.h" |
41 | 42 | ||
@@ -155,6 +156,7 @@ static struct rds_connection *__rds_conn_create(struct net *net, | |||
155 | conn->c_faddr = faddr; | 156 | conn->c_faddr = faddr; |
156 | spin_lock_init(&conn->c_lock); | 157 | spin_lock_init(&conn->c_lock); |
157 | conn->c_next_tx_seq = 1; | 158 | conn->c_next_tx_seq = 1; |
159 | conn->c_path[0].cp_conn = conn; | ||
158 | rds_conn_net_set(conn, net); | 160 | rds_conn_net_set(conn, net); |
159 | 161 | ||
160 | init_waitqueue_head(&conn->c_waitq); | 162 | init_waitqueue_head(&conn->c_waitq); |
@@ -197,7 +199,7 @@ static struct rds_connection *__rds_conn_create(struct net *net, | |||
197 | 199 | ||
198 | atomic_set(&conn->c_state, RDS_CONN_DOWN); | 200 | atomic_set(&conn->c_state, RDS_CONN_DOWN); |
199 | conn->c_send_gen = 0; | 201 | conn->c_send_gen = 0; |
200 | conn->c_outgoing = (is_outgoing ? 1 : 0); | 202 | conn->c_path[0].cp_outgoing = (is_outgoing ? 1 : 0); |
201 | conn->c_reconnect_jiffies = 0; | 203 | conn->c_reconnect_jiffies = 0; |
202 | INIT_DELAYED_WORK(&conn->c_send_w, rds_send_worker); | 204 | INIT_DELAYED_WORK(&conn->c_send_w, rds_send_worker); |
203 | INIT_DELAYED_WORK(&conn->c_recv_w, rds_recv_worker); | 205 | INIT_DELAYED_WORK(&conn->c_recv_w, rds_recv_worker); |
@@ -320,8 +322,8 @@ void rds_conn_shutdown(struct rds_connection *conn) | |||
320 | if (!hlist_unhashed(&conn->c_hash_node)) { | 322 | if (!hlist_unhashed(&conn->c_hash_node)) { |
321 | rcu_read_unlock(); | 323 | rcu_read_unlock(); |
322 | if (conn->c_trans->t_type != RDS_TRANS_TCP || | 324 | if (conn->c_trans->t_type != RDS_TRANS_TCP || |
323 | conn->c_outgoing == 1) | 325 | conn->c_path[0].cp_outgoing == 1) |
324 | rds_queue_reconnect(conn); | 326 | rds_queue_reconnect(&conn->c_path[0]); |
325 | } else { | 327 | } else { |
326 | rcu_read_unlock(); | 328 | rcu_read_unlock(); |
327 | } | 329 | } |
@@ -553,10 +555,16 @@ void rds_conn_exit(void) | |||
553 | /* | 555 | /* |
554 | * Force a disconnect | 556 | * Force a disconnect |
555 | */ | 557 | */ |
558 | void rds_conn_path_drop(struct rds_conn_path *cp) | ||
559 | { | ||
560 | atomic_set(&cp->cp_state, RDS_CONN_ERROR); | ||
561 | queue_work(rds_wq, &cp->cp_down_w); | ||
562 | } | ||
563 | EXPORT_SYMBOL_GPL(rds_conn_path_drop); | ||
564 | |||
556 | void rds_conn_drop(struct rds_connection *conn) | 565 | void rds_conn_drop(struct rds_connection *conn) |
557 | { | 566 | { |
558 | atomic_set(&conn->c_state, RDS_CONN_ERROR); | 567 | rds_conn_path_drop(&conn->c_path[0]); |
559 | queue_work(rds_wq, &conn->c_down_w); | ||
560 | } | 568 | } |
561 | EXPORT_SYMBOL_GPL(rds_conn_drop); | 569 | EXPORT_SYMBOL_GPL(rds_conn_drop); |
562 | 570 | ||
diff --git a/net/rds/ib.c b/net/rds/ib.c index b5342fddaf98..44946a681a8c 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
41 | #include <linux/module.h> | 41 | #include <linux/module.h> |
42 | 42 | ||
43 | #include "rds_single_path.h" | ||
43 | #include "rds.h" | 44 | #include "rds.h" |
44 | #include "ib.h" | 45 | #include "ib.h" |
45 | #include "ib_mr.h" | 46 | #include "ib_mr.h" |
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 310cabce2311..4de5a35f5c40 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/vmalloc.h> | 36 | #include <linux/vmalloc.h> |
37 | #include <linux/ratelimit.h> | 37 | #include <linux/ratelimit.h> |
38 | 38 | ||
39 | #include "rds_single_path.h" | ||
39 | #include "rds.h" | 40 | #include "rds.h" |
40 | #include "ib.h" | 41 | #include "ib.h" |
41 | 42 | ||
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index a0f21b65a83c..977f69886c00 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/rculist.h> | 35 | #include <linux/rculist.h> |
36 | #include <linux/llist.h> | 36 | #include <linux/llist.h> |
37 | 37 | ||
38 | #include "rds_single_path.h" | ||
38 | #include "ib_mr.h" | 39 | #include "ib_mr.h" |
39 | 40 | ||
40 | struct workqueue_struct *rds_ib_mr_wq; | 41 | struct workqueue_struct *rds_ib_mr_wq; |
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index abc8cc805e8d..4ea8cb17cc7a 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
37 | #include <rdma/rdma_cm.h> | 37 | #include <rdma/rdma_cm.h> |
38 | 38 | ||
39 | #include "rds_single_path.h" | ||
39 | #include "rds.h" | 40 | #include "rds.h" |
40 | #include "ib.h" | 41 | #include "ib.h" |
41 | 42 | ||
diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index f27d2c82b036..6e4110aa5135 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/dmapool.h> | 36 | #include <linux/dmapool.h> |
37 | #include <linux/ratelimit.h> | 37 | #include <linux/ratelimit.h> |
38 | 38 | ||
39 | #include "rds_single_path.h" | ||
39 | #include "rds.h" | 40 | #include "rds.h" |
40 | #include "ib.h" | 41 | #include "ib.h" |
41 | 42 | ||
diff --git a/net/rds/loop.c b/net/rds/loop.c index 6b12b68541ae..268f07faaa1a 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/in.h> | 35 | #include <linux/in.h> |
36 | 36 | ||
37 | #include "rds_single_path.h" | ||
37 | #include "rds.h" | 38 | #include "rds.h" |
38 | #include "loop.h" | 39 | #include "loop.h" |
39 | 40 | ||
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index 7220bebcf558..345f09059e9f 100644 --- a/net/rds/rdma_transport.c +++ b/net/rds/rdma_transport.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <rdma/rdma_cm.h> | 34 | #include <rdma/rdma_cm.h> |
35 | 35 | ||
36 | #include "rds_single_path.h" | ||
36 | #include "rdma_transport.h" | 37 | #include "rdma_transport.h" |
37 | #include "ib.h" | 38 | #include "ib.h" |
38 | 39 | ||
diff --git a/net/rds/rds.h b/net/rds/rds.h index 387df5f32e49..ca31a07f70f5 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h | |||
@@ -84,56 +84,69 @@ enum { | |||
84 | #define RDS_IN_XMIT 2 | 84 | #define RDS_IN_XMIT 2 |
85 | #define RDS_RECV_REFILL 3 | 85 | #define RDS_RECV_REFILL 3 |
86 | 86 | ||
87 | /* Max number of multipaths per RDS connection. Must be a power of 2 */ | ||
88 | #define RDS_MPATH_WORKERS 1 | ||
89 | |||
90 | /* Per mpath connection state */ | ||
91 | struct rds_conn_path { | ||
92 | struct rds_connection *cp_conn; | ||
93 | struct rds_message *cp_xmit_rm; | ||
94 | unsigned long cp_xmit_sg; | ||
95 | unsigned int cp_xmit_hdr_off; | ||
96 | unsigned int cp_xmit_data_off; | ||
97 | unsigned int cp_xmit_atomic_sent; | ||
98 | unsigned int cp_xmit_rdma_sent; | ||
99 | unsigned int cp_xmit_data_sent; | ||
100 | |||
101 | spinlock_t cp_lock; /* protect msg queues */ | ||
102 | u64 cp_next_tx_seq; | ||
103 | struct list_head cp_send_queue; | ||
104 | struct list_head cp_retrans; | ||
105 | |||
106 | u64 cp_next_rx_seq; | ||
107 | |||
108 | void *cp_transport_data; | ||
109 | |||
110 | atomic_t cp_state; | ||
111 | unsigned long cp_send_gen; | ||
112 | unsigned long cp_flags; | ||
113 | unsigned long cp_reconnect_jiffies; | ||
114 | struct delayed_work cp_send_w; | ||
115 | struct delayed_work cp_recv_w; | ||
116 | struct delayed_work cp_conn_w; | ||
117 | struct work_struct cp_down_w; | ||
118 | struct mutex cp_cm_lock; /* protect cp_state & cm */ | ||
119 | wait_queue_head_t cp_waitq; | ||
120 | |||
121 | unsigned int cp_unacked_packets; | ||
122 | unsigned int cp_unacked_bytes; | ||
123 | unsigned int cp_outgoing:1, | ||
124 | cp_pad_to_32:31; | ||
125 | unsigned int cp_index; | ||
126 | }; | ||
127 | |||
128 | /* One rds_connection per RDS address pair */ | ||
87 | struct rds_connection { | 129 | struct rds_connection { |
88 | struct hlist_node c_hash_node; | 130 | struct hlist_node c_hash_node; |
89 | __be32 c_laddr; | 131 | __be32 c_laddr; |
90 | __be32 c_faddr; | 132 | __be32 c_faddr; |
91 | unsigned int c_loopback:1, | 133 | unsigned int c_loopback:1, |
92 | c_outgoing:1, | 134 | c_pad_to_32:31; |
93 | c_pad_to_32:30; | 135 | int c_npaths; |
94 | struct rds_connection *c_passive; | 136 | struct rds_connection *c_passive; |
137 | struct rds_transport *c_trans; | ||
95 | 138 | ||
96 | struct rds_cong_map *c_lcong; | 139 | struct rds_cong_map *c_lcong; |
97 | struct rds_cong_map *c_fcong; | 140 | struct rds_cong_map *c_fcong; |
98 | 141 | ||
99 | struct rds_message *c_xmit_rm; | 142 | /* Protocol version */ |
100 | unsigned long c_xmit_sg; | 143 | unsigned int c_version; |
101 | unsigned int c_xmit_hdr_off; | 144 | possible_net_t c_net; |
102 | unsigned int c_xmit_data_off; | ||
103 | unsigned int c_xmit_atomic_sent; | ||
104 | unsigned int c_xmit_rdma_sent; | ||
105 | unsigned int c_xmit_data_sent; | ||
106 | |||
107 | spinlock_t c_lock; /* protect msg queues */ | ||
108 | u64 c_next_tx_seq; | ||
109 | struct list_head c_send_queue; | ||
110 | struct list_head c_retrans; | ||
111 | |||
112 | u64 c_next_rx_seq; | ||
113 | |||
114 | struct rds_transport *c_trans; | ||
115 | void *c_transport_data; | ||
116 | |||
117 | atomic_t c_state; | ||
118 | unsigned long c_send_gen; | ||
119 | unsigned long c_flags; | ||
120 | unsigned long c_reconnect_jiffies; | ||
121 | struct delayed_work c_send_w; | ||
122 | struct delayed_work c_recv_w; | ||
123 | struct delayed_work c_conn_w; | ||
124 | struct work_struct c_down_w; | ||
125 | struct mutex c_cm_lock; /* protect conn state & cm */ | ||
126 | wait_queue_head_t c_waitq; | ||
127 | 145 | ||
128 | struct list_head c_map_item; | 146 | struct list_head c_map_item; |
129 | unsigned long c_map_queued; | 147 | unsigned long c_map_queued; |
130 | 148 | ||
131 | unsigned int c_unacked_packets; | 149 | struct rds_conn_path c_path[RDS_MPATH_WORKERS]; |
132 | unsigned int c_unacked_bytes; | ||
133 | |||
134 | /* Protocol version */ | ||
135 | unsigned int c_version; | ||
136 | possible_net_t c_net; | ||
137 | }; | 150 | }; |
138 | 151 | ||
139 | static inline | 152 | static inline |
@@ -639,6 +652,7 @@ struct rds_connection *rds_conn_create_outgoing(struct net *net, | |||
639 | void rds_conn_shutdown(struct rds_connection *conn); | 652 | void rds_conn_shutdown(struct rds_connection *conn); |
640 | void rds_conn_destroy(struct rds_connection *conn); | 653 | void rds_conn_destroy(struct rds_connection *conn); |
641 | void rds_conn_drop(struct rds_connection *conn); | 654 | void rds_conn_drop(struct rds_connection *conn); |
655 | void rds_conn_path_drop(struct rds_conn_path *cpath); | ||
642 | void rds_conn_connect_if_down(struct rds_connection *conn); | 656 | void rds_conn_connect_if_down(struct rds_connection *conn); |
643 | void rds_for_each_conn_info(struct socket *sock, unsigned int len, | 657 | void rds_for_each_conn_info(struct socket *sock, unsigned int len, |
644 | struct rds_info_iterator *iter, | 658 | struct rds_info_iterator *iter, |
@@ -651,27 +665,51 @@ void __rds_conn_error(struct rds_connection *conn, const char *, ...); | |||
651 | __rds_conn_error(conn, KERN_WARNING "RDS: " fmt) | 665 | __rds_conn_error(conn, KERN_WARNING "RDS: " fmt) |
652 | 666 | ||
653 | static inline int | 667 | static inline int |
668 | rds_conn_path_transition(struct rds_conn_path *cp, int old, int new) | ||
669 | { | ||
670 | return atomic_cmpxchg(&cp->cp_state, old, new) == old; | ||
671 | } | ||
672 | |||
673 | static inline int | ||
654 | rds_conn_transition(struct rds_connection *conn, int old, int new) | 674 | rds_conn_transition(struct rds_connection *conn, int old, int new) |
655 | { | 675 | { |
656 | return atomic_cmpxchg(&conn->c_state, old, new) == old; | 676 | return rds_conn_path_transition(&conn->c_path[0], old, new); |
677 | } | ||
678 | |||
679 | static inline int | ||
680 | rds_conn_path_state(struct rds_conn_path *cp) | ||
681 | { | ||
682 | return atomic_read(&cp->cp_state); | ||
657 | } | 683 | } |
658 | 684 | ||
659 | static inline int | 685 | static inline int |
660 | rds_conn_state(struct rds_connection *conn) | 686 | rds_conn_state(struct rds_connection *conn) |
661 | { | 687 | { |
662 | return atomic_read(&conn->c_state); | 688 | return rds_conn_path_state(&conn->c_path[0]); |
689 | } | ||
690 | |||
691 | static inline int | ||
692 | rds_conn_path_up(struct rds_conn_path *cp) | ||
693 | { | ||
694 | return atomic_read(&cp->cp_state) == RDS_CONN_UP; | ||
663 | } | 695 | } |
664 | 696 | ||
665 | static inline int | 697 | static inline int |
666 | rds_conn_up(struct rds_connection *conn) | 698 | rds_conn_up(struct rds_connection *conn) |
667 | { | 699 | { |
668 | return atomic_read(&conn->c_state) == RDS_CONN_UP; | 700 | return rds_conn_path_up(&conn->c_path[0]); |
701 | } | ||
702 | |||
703 | static inline int | ||
704 | rds_conn_path_connecting(struct rds_conn_path *cp) | ||
705 | { | ||
706 | return atomic_read(&cp->cp_state) == RDS_CONN_CONNECTING; | ||
669 | } | 707 | } |
670 | 708 | ||
671 | static inline int | 709 | static inline int |
672 | rds_conn_connecting(struct rds_connection *conn) | 710 | rds_conn_connecting(struct rds_connection *conn) |
673 | { | 711 | { |
674 | return atomic_read(&conn->c_state) == RDS_CONN_CONNECTING; | 712 | return rds_conn_path_connecting(&conn->c_path[0]); |
675 | } | 713 | } |
676 | 714 | ||
677 | /* message.c */ | 715 | /* message.c */ |
@@ -809,12 +847,12 @@ extern unsigned int rds_sysctl_trace_level; | |||
809 | int rds_threads_init(void); | 847 | int rds_threads_init(void); |
810 | void rds_threads_exit(void); | 848 | void rds_threads_exit(void); |
811 | extern struct workqueue_struct *rds_wq; | 849 | extern struct workqueue_struct *rds_wq; |
812 | void rds_queue_reconnect(struct rds_connection *conn); | 850 | void rds_queue_reconnect(struct rds_conn_path *cp); |
813 | void rds_connect_worker(struct work_struct *); | 851 | void rds_connect_worker(struct work_struct *); |
814 | void rds_shutdown_worker(struct work_struct *); | 852 | void rds_shutdown_worker(struct work_struct *); |
815 | void rds_send_worker(struct work_struct *); | 853 | void rds_send_worker(struct work_struct *); |
816 | void rds_recv_worker(struct work_struct *); | 854 | void rds_recv_worker(struct work_struct *); |
817 | void rds_connect_path_complete(struct rds_connection *conn, int curr); | 855 | void rds_connect_path_complete(struct rds_conn_path *conn, int curr); |
818 | void rds_connect_complete(struct rds_connection *conn); | 856 | void rds_connect_complete(struct rds_connection *conn); |
819 | 857 | ||
820 | /* transport.c */ | 858 | /* transport.c */ |
diff --git a/net/rds/rds_single_path.h b/net/rds/rds_single_path.h new file mode 100644 index 000000000000..e1241af7c1ad --- /dev/null +++ b/net/rds/rds_single_path.h | |||
@@ -0,0 +1,30 @@ | |||
1 | #ifndef _RDS_RDS_SINGLE_H | ||
2 | #define _RDS_RDS_SINGLE_H | ||
3 | |||
4 | #define c_xmit_rm c_path[0].cp_xmit_rm | ||
5 | #define c_xmit_sg c_path[0].cp_xmit_sg | ||
6 | #define c_xmit_hdr_off c_path[0].cp_xmit_hdr_off | ||
7 | #define c_xmit_data_off c_path[0].cp_xmit_data_off | ||
8 | #define c_xmit_atomic_sent c_path[0].cp_xmit_atomic_sent | ||
9 | #define c_xmit_rdma_sent c_path[0].cp_xmit_rdma_sent | ||
10 | #define c_xmit_data_sent c_path[0].cp_xmit_data_sent | ||
11 | #define c_lock c_path[0].cp_lock | ||
12 | #define c_next_tx_seq c_path[0].cp_next_tx_seq | ||
13 | #define c_send_queue c_path[0].cp_send_queue | ||
14 | #define c_retrans c_path[0].cp_retrans | ||
15 | #define c_next_rx_seq c_path[0].cp_next_rx_seq | ||
16 | #define c_transport_data c_path[0].cp_transport_data | ||
17 | #define c_state c_path[0].cp_state | ||
18 | #define c_send_gen c_path[0].cp_send_gen | ||
19 | #define c_flags c_path[0].cp_flags | ||
20 | #define c_reconnect_jiffies c_path[0].cp_reconnect_jiffies | ||
21 | #define c_send_w c_path[0].cp_send_w | ||
22 | #define c_recv_w c_path[0].cp_recv_w | ||
23 | #define c_conn_w c_path[0].cp_conn_w | ||
24 | #define c_down_w c_path[0].cp_down_w | ||
25 | #define c_cm_lock c_path[0].cp_cm_lock | ||
26 | #define c_waitq c_path[0].cp_waitq | ||
27 | #define c_unacked_packets c_path[0].cp_unacked_packets | ||
28 | #define c_unacked_bytes c_path[0].cp_unacked_bytes | ||
29 | |||
30 | #endif /* _RDS_RDS_SINGLE_H */ | ||
diff --git a/net/rds/recv.c b/net/rds/recv.c index 8413f6c99e13..78b5c430324d 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/time.h> | 38 | #include <linux/time.h> |
39 | #include <linux/rds.h> | 39 | #include <linux/rds.h> |
40 | 40 | ||
41 | #include "rds_single_path.h" | ||
41 | #include "rds.h" | 42 | #include "rds.h" |
42 | 43 | ||
43 | void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn, | 44 | void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn, |
diff --git a/net/rds/send.c b/net/rds/send.c index b1962f8e30f7..a3b3b35ad57a 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/export.h> | 40 | #include <linux/export.h> |
41 | #include <linux/sizes.h> | 41 | #include <linux/sizes.h> |
42 | 42 | ||
43 | #include "rds_single_path.h" | ||
43 | #include "rds.h" | 44 | #include "rds.h" |
44 | 45 | ||
45 | /* When transmitting messages in rds_send_xmit, we need to emerge from | 46 | /* When transmitting messages in rds_send_xmit, we need to emerge from |
diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 74ee126a6fe6..4bc1c153e93a 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <net/net_namespace.h> | 38 | #include <net/net_namespace.h> |
39 | #include <net/netns/generic.h> | 39 | #include <net/netns/generic.h> |
40 | 40 | ||
41 | #include "rds_single_path.h" | ||
41 | #include "rds.h" | 42 | #include "rds.h" |
42 | #include "tcp.h" | 43 | #include "tcp.h" |
43 | 44 | ||
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index fba13d0305fb..ba9ec67f4e41 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/in.h> | 34 | #include <linux/in.h> |
35 | #include <net/tcp.h> | 35 | #include <net/tcp.h> |
36 | 36 | ||
37 | #include "rds_single_path.h" | ||
37 | #include "rds.h" | 38 | #include "rds.h" |
38 | #include "tcp.h" | 39 | #include "tcp.h" |
39 | 40 | ||
@@ -60,7 +61,8 @@ void rds_tcp_state_change(struct sock *sk) | |||
60 | case TCP_SYN_RECV: | 61 | case TCP_SYN_RECV: |
61 | break; | 62 | break; |
62 | case TCP_ESTABLISHED: | 63 | case TCP_ESTABLISHED: |
63 | rds_connect_path_complete(conn, RDS_CONN_CONNECTING); | 64 | rds_connect_path_complete(&conn->c_path[0], |
65 | RDS_CONN_CONNECTING); | ||
64 | break; | 66 | break; |
65 | case TCP_CLOSE_WAIT: | 67 | case TCP_CLOSE_WAIT: |
66 | case TCP_CLOSE: | 68 | case TCP_CLOSE: |
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 686b1d03a558..22d9bb15f731 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/in.h> | 35 | #include <linux/in.h> |
36 | #include <net/tcp.h> | 36 | #include <net/tcp.h> |
37 | 37 | ||
38 | #include "rds_single_path.h" | ||
38 | #include "rds.h" | 39 | #include "rds.h" |
39 | #include "tcp.h" | 40 | #include "tcp.h" |
40 | 41 | ||
@@ -132,17 +133,19 @@ int rds_tcp_accept_one(struct socket *sock) | |||
132 | * c_transport_data. | 133 | * c_transport_data. |
133 | */ | 134 | */ |
134 | if (ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr) || | 135 | if (ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr) || |
135 | !conn->c_outgoing) { | 136 | !conn->c_path[0].cp_outgoing) { |
136 | goto rst_nsk; | 137 | goto rst_nsk; |
137 | } else { | 138 | } else { |
138 | rds_tcp_reset_callbacks(new_sock, conn); | 139 | rds_tcp_reset_callbacks(new_sock, conn); |
139 | conn->c_outgoing = 0; | 140 | conn->c_path[0].cp_outgoing = 0; |
140 | /* rds_connect_path_complete() marks RDS_CONN_UP */ | 141 | /* rds_connect_path_complete() marks RDS_CONN_UP */ |
141 | rds_connect_path_complete(conn, RDS_CONN_DISCONNECTING); | 142 | rds_connect_path_complete(&conn->c_path[0], |
143 | RDS_CONN_DISCONNECTING); | ||
142 | } | 144 | } |
143 | } else { | 145 | } else { |
144 | rds_tcp_set_callbacks(new_sock, conn); | 146 | rds_tcp_set_callbacks(new_sock, conn); |
145 | rds_connect_path_complete(conn, RDS_CONN_CONNECTING); | 147 | rds_connect_path_complete(&conn->c_path[0], |
148 | RDS_CONN_CONNECTING); | ||
146 | } | 149 | } |
147 | new_sock = NULL; | 150 | new_sock = NULL; |
148 | ret = 0; | 151 | ret = 0; |
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index c3196f9d070a..3f8fb38996c7 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <net/tcp.h> | 35 | #include <net/tcp.h> |
36 | 36 | ||
37 | #include "rds_single_path.h" | ||
37 | #include "rds.h" | 38 | #include "rds.h" |
38 | #include "tcp.h" | 39 | #include "tcp.h" |
39 | 40 | ||
diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index 22d0f2020a79..2b3414f3c45c 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/in.h> | 34 | #include <linux/in.h> |
35 | #include <net/tcp.h> | 35 | #include <net/tcp.h> |
36 | 36 | ||
37 | #include "rds_single_path.h" | ||
37 | #include "rds.h" | 38 | #include "rds.h" |
38 | #include "tcp.h" | 39 | #include "tcp.h" |
39 | 40 | ||
diff --git a/net/rds/threads.c b/net/rds/threads.c index 4a323045719b..6d0979b8dc63 100644 --- a/net/rds/threads.c +++ b/net/rds/threads.c | |||
@@ -71,30 +71,30 @@ | |||
71 | struct workqueue_struct *rds_wq; | 71 | struct workqueue_struct *rds_wq; |
72 | EXPORT_SYMBOL_GPL(rds_wq); | 72 | EXPORT_SYMBOL_GPL(rds_wq); |
73 | 73 | ||
74 | void rds_connect_path_complete(struct rds_connection *conn, int curr) | 74 | void rds_connect_path_complete(struct rds_conn_path *cp, int curr) |
75 | { | 75 | { |
76 | if (!rds_conn_transition(conn, curr, RDS_CONN_UP)) { | 76 | if (!rds_conn_path_transition(cp, curr, RDS_CONN_UP)) { |
77 | printk(KERN_WARNING "%s: Cannot transition to state UP, " | 77 | printk(KERN_WARNING "%s: Cannot transition to state UP, " |
78 | "current state is %d\n", | 78 | "current state is %d\n", |
79 | __func__, | 79 | __func__, |
80 | atomic_read(&conn->c_state)); | 80 | atomic_read(&cp->cp_state)); |
81 | rds_conn_drop(conn); | 81 | rds_conn_path_drop(cp); |
82 | return; | 82 | return; |
83 | } | 83 | } |
84 | 84 | ||
85 | rdsdebug("conn %p for %pI4 to %pI4 complete\n", | 85 | rdsdebug("conn %p for %pI4 to %pI4 complete\n", |
86 | conn, &conn->c_laddr, &conn->c_faddr); | 86 | cp->cp_conn, &cp->cp_conn->c_laddr, &cp->cp_conn->c_faddr); |
87 | 87 | ||
88 | conn->c_reconnect_jiffies = 0; | 88 | cp->cp_reconnect_jiffies = 0; |
89 | set_bit(0, &conn->c_map_queued); | 89 | set_bit(0, &cp->cp_conn->c_map_queued); |
90 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); | 90 | queue_delayed_work(rds_wq, &cp->cp_send_w, 0); |
91 | queue_delayed_work(rds_wq, &conn->c_recv_w, 0); | 91 | queue_delayed_work(rds_wq, &cp->cp_recv_w, 0); |
92 | } | 92 | } |
93 | EXPORT_SYMBOL_GPL(rds_connect_path_complete); | 93 | EXPORT_SYMBOL_GPL(rds_connect_path_complete); |
94 | 94 | ||
95 | void rds_connect_complete(struct rds_connection *conn) | 95 | void rds_connect_complete(struct rds_connection *conn) |
96 | { | 96 | { |
97 | rds_connect_path_complete(conn, RDS_CONN_CONNECTING); | 97 | rds_connect_path_complete(&conn->c_path[0], RDS_CONN_CONNECTING); |
98 | } | 98 | } |
99 | EXPORT_SYMBOL_GPL(rds_connect_complete); | 99 | EXPORT_SYMBOL_GPL(rds_connect_complete); |
100 | 100 | ||
@@ -116,46 +116,52 @@ EXPORT_SYMBOL_GPL(rds_connect_complete); | |||
116 | * We should *always* start with a random backoff; otherwise a broken connection | 116 | * We should *always* start with a random backoff; otherwise a broken connection |
117 | * will always take several iterations to be re-established. | 117 | * will always take several iterations to be re-established. |
118 | */ | 118 | */ |
119 | void rds_queue_reconnect(struct rds_connection *conn) | 119 | void rds_queue_reconnect(struct rds_conn_path *cp) |
120 | { | 120 | { |
121 | unsigned long rand; | 121 | unsigned long rand; |
122 | struct rds_connection *conn = cp->cp_conn; | ||
122 | 123 | ||
123 | rdsdebug("conn %p for %pI4 to %pI4 reconnect jiffies %lu\n", | 124 | rdsdebug("conn %p for %pI4 to %pI4 reconnect jiffies %lu\n", |
124 | conn, &conn->c_laddr, &conn->c_faddr, | 125 | conn, &conn->c_laddr, &conn->c_faddr, |
125 | conn->c_reconnect_jiffies); | 126 | cp->cp_reconnect_jiffies); |
126 | 127 | ||
127 | set_bit(RDS_RECONNECT_PENDING, &conn->c_flags); | 128 | set_bit(RDS_RECONNECT_PENDING, &cp->cp_flags); |
128 | if (conn->c_reconnect_jiffies == 0) { | 129 | if (cp->cp_reconnect_jiffies == 0) { |
129 | conn->c_reconnect_jiffies = rds_sysctl_reconnect_min_jiffies; | 130 | cp->cp_reconnect_jiffies = rds_sysctl_reconnect_min_jiffies; |
130 | queue_delayed_work(rds_wq, &conn->c_conn_w, 0); | 131 | queue_delayed_work(rds_wq, &cp->cp_conn_w, 0); |
131 | return; | 132 | return; |
132 | } | 133 | } |
133 | 134 | ||
134 | get_random_bytes(&rand, sizeof(rand)); | 135 | get_random_bytes(&rand, sizeof(rand)); |
135 | rdsdebug("%lu delay %lu ceil conn %p for %pI4 -> %pI4\n", | 136 | rdsdebug("%lu delay %lu ceil conn %p for %pI4 -> %pI4\n", |
136 | rand % conn->c_reconnect_jiffies, conn->c_reconnect_jiffies, | 137 | rand % cp->cp_reconnect_jiffies, cp->cp_reconnect_jiffies, |
137 | conn, &conn->c_laddr, &conn->c_faddr); | 138 | conn, &conn->c_laddr, &conn->c_faddr); |
138 | queue_delayed_work(rds_wq, &conn->c_conn_w, | 139 | queue_delayed_work(rds_wq, &cp->cp_conn_w, |
139 | rand % conn->c_reconnect_jiffies); | 140 | rand % cp->cp_reconnect_jiffies); |
140 | 141 | ||
141 | conn->c_reconnect_jiffies = min(conn->c_reconnect_jiffies * 2, | 142 | cp->cp_reconnect_jiffies = min(cp->cp_reconnect_jiffies * 2, |
142 | rds_sysctl_reconnect_max_jiffies); | 143 | rds_sysctl_reconnect_max_jiffies); |
143 | } | 144 | } |
144 | 145 | ||
145 | void rds_connect_worker(struct work_struct *work) | 146 | void rds_connect_worker(struct work_struct *work) |
146 | { | 147 | { |
147 | struct rds_connection *conn = container_of(work, struct rds_connection, c_conn_w.work); | 148 | struct rds_conn_path *cp = container_of(work, |
149 | struct rds_conn_path, | ||
150 | cp_conn_w.work); | ||
151 | struct rds_connection *conn = cp->cp_conn; | ||
148 | int ret; | 152 | int ret; |
149 | 153 | ||
150 | clear_bit(RDS_RECONNECT_PENDING, &conn->c_flags); | 154 | clear_bit(RDS_RECONNECT_PENDING, &cp->cp_flags); |
151 | if (rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING)) { | 155 | if (rds_conn_path_transition(cp, RDS_CONN_DOWN, RDS_CONN_CONNECTING)) { |
152 | ret = conn->c_trans->conn_connect(conn); | 156 | ret = conn->c_trans->conn_connect(conn); |
153 | rdsdebug("conn %p for %pI4 to %pI4 dispatched, ret %d\n", | 157 | rdsdebug("conn %p for %pI4 to %pI4 dispatched, ret %d\n", |
154 | conn, &conn->c_laddr, &conn->c_faddr, ret); | 158 | conn, &conn->c_laddr, &conn->c_faddr, ret); |
155 | 159 | ||
156 | if (ret) { | 160 | if (ret) { |
157 | if (rds_conn_transition(conn, RDS_CONN_CONNECTING, RDS_CONN_DOWN)) | 161 | if (rds_conn_path_transition(cp, |
158 | rds_queue_reconnect(conn); | 162 | RDS_CONN_CONNECTING, |
163 | RDS_CONN_DOWN)) | ||
164 | rds_queue_reconnect(cp); | ||
159 | else | 165 | else |
160 | rds_conn_error(conn, "RDS: connect failed\n"); | 166 | rds_conn_error(conn, "RDS: connect failed\n"); |
161 | } | 167 | } |
@@ -164,22 +170,24 @@ void rds_connect_worker(struct work_struct *work) | |||
164 | 170 | ||
165 | void rds_send_worker(struct work_struct *work) | 171 | void rds_send_worker(struct work_struct *work) |
166 | { | 172 | { |
167 | struct rds_connection *conn = container_of(work, struct rds_connection, c_send_w.work); | 173 | struct rds_conn_path *cp = container_of(work, |
174 | struct rds_conn_path, | ||
175 | cp_send_w.work); | ||
168 | int ret; | 176 | int ret; |
169 | 177 | ||
170 | if (rds_conn_state(conn) == RDS_CONN_UP) { | 178 | if (rds_conn_path_state(cp) == RDS_CONN_UP) { |
171 | clear_bit(RDS_LL_SEND_FULL, &conn->c_flags); | 179 | clear_bit(RDS_LL_SEND_FULL, &cp->cp_flags); |
172 | ret = rds_send_xmit(conn); | 180 | ret = rds_send_xmit(cp->cp_conn); |
173 | cond_resched(); | 181 | cond_resched(); |
174 | rdsdebug("conn %p ret %d\n", conn, ret); | 182 | rdsdebug("conn %p ret %d\n", cp->cp_conn, ret); |
175 | switch (ret) { | 183 | switch (ret) { |
176 | case -EAGAIN: | 184 | case -EAGAIN: |
177 | rds_stats_inc(s_send_immediate_retry); | 185 | rds_stats_inc(s_send_immediate_retry); |
178 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); | 186 | queue_delayed_work(rds_wq, &cp->cp_send_w, 0); |
179 | break; | 187 | break; |
180 | case -ENOMEM: | 188 | case -ENOMEM: |
181 | rds_stats_inc(s_send_delayed_retry); | 189 | rds_stats_inc(s_send_delayed_retry); |
182 | queue_delayed_work(rds_wq, &conn->c_send_w, 2); | 190 | queue_delayed_work(rds_wq, &cp->cp_send_w, 2); |
183 | default: | 191 | default: |
184 | break; | 192 | break; |
185 | } | 193 | } |
@@ -188,20 +196,22 @@ void rds_send_worker(struct work_struct *work) | |||
188 | 196 | ||
189 | void rds_recv_worker(struct work_struct *work) | 197 | void rds_recv_worker(struct work_struct *work) |
190 | { | 198 | { |
191 | struct rds_connection *conn = container_of(work, struct rds_connection, c_recv_w.work); | 199 | struct rds_conn_path *cp = container_of(work, |
200 | struct rds_conn_path, | ||
201 | cp_recv_w.work); | ||
192 | int ret; | 202 | int ret; |
193 | 203 | ||
194 | if (rds_conn_state(conn) == RDS_CONN_UP) { | 204 | if (rds_conn_path_state(cp) == RDS_CONN_UP) { |
195 | ret = conn->c_trans->recv(conn); | 205 | ret = cp->cp_conn->c_trans->recv(cp->cp_conn); |
196 | rdsdebug("conn %p ret %d\n", conn, ret); | 206 | rdsdebug("conn %p ret %d\n", cp->cp_conn, ret); |
197 | switch (ret) { | 207 | switch (ret) { |
198 | case -EAGAIN: | 208 | case -EAGAIN: |
199 | rds_stats_inc(s_recv_immediate_retry); | 209 | rds_stats_inc(s_recv_immediate_retry); |
200 | queue_delayed_work(rds_wq, &conn->c_recv_w, 0); | 210 | queue_delayed_work(rds_wq, &cp->cp_recv_w, 0); |
201 | break; | 211 | break; |
202 | case -ENOMEM: | 212 | case -ENOMEM: |
203 | rds_stats_inc(s_recv_delayed_retry); | 213 | rds_stats_inc(s_recv_delayed_retry); |
204 | queue_delayed_work(rds_wq, &conn->c_recv_w, 2); | 214 | queue_delayed_work(rds_wq, &cp->cp_recv_w, 2); |
205 | default: | 215 | default: |
206 | break; | 216 | break; |
207 | } | 217 | } |
@@ -210,9 +220,11 @@ void rds_recv_worker(struct work_struct *work) | |||
210 | 220 | ||
211 | void rds_shutdown_worker(struct work_struct *work) | 221 | void rds_shutdown_worker(struct work_struct *work) |
212 | { | 222 | { |
213 | struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w); | 223 | struct rds_conn_path *cp = container_of(work, |
224 | struct rds_conn_path, | ||
225 | cp_down_w); | ||
214 | 226 | ||
215 | rds_conn_shutdown(conn); | 227 | rds_conn_shutdown(cp->cp_conn); |
216 | } | 228 | } |
217 | 229 | ||
218 | void rds_threads_exit(void) | 230 | void rds_threads_exit(void) |