tcp.c (afb4164d91c7486a1d4ab098a1b88e27b5e25772) | tcp.c (ea3b1ea53930879c9847044f5cb9c97411cae797) |
---|---|
1/* 2 * Copyright (c) 2006 Oracle. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: --- 122 unchanged lines hidden (view full) --- 131 * returns the existing tc->t_sock. 132 * 133 * The only functions that set tc->t_sock are rds_tcp_set_callbacks 134 * and rds_tcp_reset_callbacks. Send and receive trust that 135 * it is set. The absence of RDS_CONN_UP bit protects those paths 136 * from being called while it isn't set. 137 */ 138void rds_tcp_reset_callbacks(struct socket *sock, | 1/* 2 * Copyright (c) 2006 Oracle. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: --- 122 unchanged lines hidden (view full) --- 131 * returns the existing tc->t_sock. 132 * 133 * The only functions that set tc->t_sock are rds_tcp_set_callbacks 134 * and rds_tcp_reset_callbacks. Send and receive trust that 135 * it is set. The absence of RDS_CONN_UP bit protects those paths 136 * from being called while it isn't set. 137 */ 138void rds_tcp_reset_callbacks(struct socket *sock, |
139 struct rds_connection *conn) | 139 struct rds_conn_path *cp) |
140{ | 140{ |
141 struct rds_tcp_connection *tc = conn->c_transport_data; | 141 struct rds_tcp_connection *tc = cp->cp_transport_data; |
142 struct socket *osock = tc->t_sock; 143 144 if (!osock) 145 goto newsock; 146 147 /* Need to resolve a duelling SYN between peers. 148 * We have an outstanding SYN to this peer, which may 149 * potentially have transitioned to the RDS_CONN_UP state, 150 * so we must quiesce any send threads before resetting | 142 struct socket *osock = tc->t_sock; 143 144 if (!osock) 145 goto newsock; 146 147 /* Need to resolve a duelling SYN between peers. 148 * We have an outstanding SYN to this peer, which may 149 * potentially have transitioned to the RDS_CONN_UP state, 150 * so we must quiesce any send threads before resetting |
151 * c_transport_data. We quiesce these threads by setting 152 * c_state to something other than RDS_CONN_UP, and then | 151 * cp_transport_data. We quiesce these threads by setting 152 * cp_state to something other than RDS_CONN_UP, and then |
153 * waiting for any existing threads in rds_send_xmit to 154 * complete release_in_xmit(). (Subsequent threads entering 155 * rds_send_xmit() will bail on !rds_conn_up(). 156 * 157 * However an incoming syn-ack at this point would end up 158 * marking the conn as RDS_CONN_UP, and would again permit 159 * rds_send_xmi() threads through, so ideally we would 160 * synchronize on RDS_CONN_UP after lock_sock(), but cannot 161 * do that: waiting on !RDS_IN_XMIT after lock_sock() may 162 * end up deadlocking with tcp_sendmsg(), and the RDS_IN_XMIT 163 * would not get set. As a result, we set c_state to 164 * RDS_CONN_RESETTTING, to ensure that rds_tcp_state_change 165 * cannot mark rds_conn_path_up() in the window before lock_sock() 166 */ | 153 * waiting for any existing threads in rds_send_xmit to 154 * complete release_in_xmit(). (Subsequent threads entering 155 * rds_send_xmit() will bail on !rds_conn_up(). 156 * 157 * However an incoming syn-ack at this point would end up 158 * marking the conn as RDS_CONN_UP, and would again permit 159 * rds_send_xmi() threads through, so ideally we would 160 * synchronize on RDS_CONN_UP after lock_sock(), but cannot 161 * do that: waiting on !RDS_IN_XMIT after lock_sock() may 162 * end up deadlocking with tcp_sendmsg(), and the RDS_IN_XMIT 163 * would not get set. As a result, we set c_state to 164 * RDS_CONN_RESETTTING, to ensure that rds_tcp_state_change 165 * cannot mark rds_conn_path_up() in the window before lock_sock() 166 */ |
167 atomic_set(&conn->c_state, RDS_CONN_RESETTING); 168 wait_event(conn->c_waitq, !test_bit(RDS_IN_XMIT, &conn->c_flags)); | 167 atomic_set(&cp->cp_state, RDS_CONN_RESETTING); 168 wait_event(cp->cp_waitq, !test_bit(RDS_IN_XMIT, &cp->cp_flags)); |
169 lock_sock(osock->sk); 170 /* reset receive side state for rds_tcp_data_recv() for osock */ 171 if (tc->t_tinc) { 172 rds_inc_put(&tc->t_tinc->ti_inc); 173 tc->t_tinc = NULL; 174 } 175 tc->t_tinc_hdr_rem = sizeof(struct rds_header); 176 tc->t_tinc_data_rem = 0; --- 4 unchanged lines hidden (view full) --- 181 osock->sk->sk_user_data = NULL; 182 osock->sk->sk_data_ready = tc->t_orig_data_ready; 183 osock->sk->sk_write_space = tc->t_orig_write_space; 184 osock->sk->sk_state_change = tc->t_orig_state_change; 185 write_unlock_bh(&osock->sk->sk_callback_lock); 186 release_sock(osock->sk); 187 sock_release(osock); 188newsock: | 169 lock_sock(osock->sk); 170 /* reset receive side state for rds_tcp_data_recv() for osock */ 171 if (tc->t_tinc) { 172 rds_inc_put(&tc->t_tinc->ti_inc); 173 tc->t_tinc = NULL; 174 } 175 tc->t_tinc_hdr_rem = sizeof(struct rds_header); 176 tc->t_tinc_data_rem = 0; --- 4 unchanged lines hidden (view full) --- 181 osock->sk->sk_user_data = NULL; 182 osock->sk->sk_data_ready = tc->t_orig_data_ready; 183 osock->sk->sk_write_space = tc->t_orig_write_space; 184 osock->sk->sk_state_change = tc->t_orig_state_change; 185 write_unlock_bh(&osock->sk->sk_callback_lock); 186 release_sock(osock->sk); 187 sock_release(osock); 188newsock: |
189 rds_send_path_reset(&conn->c_path[0]); | 189 rds_send_path_reset(cp); |
190 lock_sock(sock->sk); 191 write_lock_bh(&sock->sk->sk_callback_lock); 192 tc->t_sock = sock; | 190 lock_sock(sock->sk); 191 write_lock_bh(&sock->sk->sk_callback_lock); 192 tc->t_sock = sock; |
193 sock->sk->sk_user_data = conn; | 193 tc->t_cpath = cp; 194 sock->sk->sk_user_data = cp; |
194 sock->sk->sk_data_ready = rds_tcp_data_ready; 195 sock->sk->sk_write_space = rds_tcp_write_space; 196 sock->sk->sk_state_change = rds_tcp_state_change; 197 198 write_unlock_bh(&sock->sk->sk_callback_lock); 199 release_sock(sock->sk); 200} 201 202/* Add tc to rds_tcp_tc_list and set tc->t_sock. See comments 203 * above rds_tcp_reset_callbacks for notes about synchronization 204 * with data path 205 */ | 195 sock->sk->sk_data_ready = rds_tcp_data_ready; 196 sock->sk->sk_write_space = rds_tcp_write_space; 197 sock->sk->sk_state_change = rds_tcp_state_change; 198 199 write_unlock_bh(&sock->sk->sk_callback_lock); 200 release_sock(sock->sk); 201} 202 203/* Add tc to rds_tcp_tc_list and set tc->t_sock. See comments 204 * above rds_tcp_reset_callbacks for notes about synchronization 205 * with data path 206 */ |
206void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn) | 207void rds_tcp_set_callbacks(struct socket *sock, struct rds_conn_path *cp) |
207{ | 208{ |
208 struct rds_tcp_connection *tc = conn->c_transport_data; | 209 struct rds_tcp_connection *tc = cp->cp_transport_data; |
209 210 rdsdebug("setting sock %p callbacks to tc %p\n", sock, tc); 211 write_lock_bh(&sock->sk->sk_callback_lock); 212 213 /* done under the callback_lock to serialize with write_space */ 214 spin_lock(&rds_tcp_tc_list_lock); 215 list_add_tail(&tc->t_list_item, &rds_tcp_tc_list); 216 rds_tcp_tc_count++; 217 spin_unlock(&rds_tcp_tc_list_lock); 218 219 /* accepted sockets need our listen data ready undone */ 220 if (sock->sk->sk_data_ready == rds_tcp_listen_data_ready) 221 sock->sk->sk_data_ready = sock->sk->sk_user_data; 222 223 tc->t_sock = sock; | 210 211 rdsdebug("setting sock %p callbacks to tc %p\n", sock, tc); 212 write_lock_bh(&sock->sk->sk_callback_lock); 213 214 /* done under the callback_lock to serialize with write_space */ 215 spin_lock(&rds_tcp_tc_list_lock); 216 list_add_tail(&tc->t_list_item, &rds_tcp_tc_list); 217 rds_tcp_tc_count++; 218 spin_unlock(&rds_tcp_tc_list_lock); 219 220 /* accepted sockets need our listen data ready undone */ 221 if (sock->sk->sk_data_ready == rds_tcp_listen_data_ready) 222 sock->sk->sk_data_ready = sock->sk->sk_user_data; 223 224 tc->t_sock = sock; |
224 tc->t_cpath = &conn->c_path[0]; | 225 tc->t_cpath = cp; |
225 tc->t_orig_data_ready = sock->sk->sk_data_ready; 226 tc->t_orig_write_space = sock->sk->sk_write_space; 227 tc->t_orig_state_change = sock->sk->sk_state_change; 228 | 226 tc->t_orig_data_ready = sock->sk->sk_data_ready; 227 tc->t_orig_write_space = sock->sk->sk_write_space; 228 tc->t_orig_state_change = sock->sk->sk_state_change; 229 |
229 sock->sk->sk_user_data = conn; | 230 sock->sk->sk_user_data = cp; |
230 sock->sk->sk_data_ready = rds_tcp_data_ready; 231 sock->sk->sk_write_space = rds_tcp_write_space; 232 sock->sk->sk_state_change = rds_tcp_state_change; 233 234 write_unlock_bh(&sock->sk->sk_callback_lock); 235} 236 237static void rds_tcp_tc_info(struct socket *sock, unsigned int len, --- 439 unchanged lines hidden --- | 231 sock->sk->sk_data_ready = rds_tcp_data_ready; 232 sock->sk->sk_write_space = rds_tcp_write_space; 233 sock->sk->sk_state_change = rds_tcp_state_change; 234 235 write_unlock_bh(&sock->sk->sk_callback_lock); 236} 237 238static void rds_tcp_tc_info(struct socket *sock, unsigned int len, --- 439 unchanged lines hidden --- |