loop.c (7731b8bc94e599c9a79e428f3359ff2c34b7576a) | loop.c (c809195f5523dd4d09403bbb1c9732d548aa0d1e) |
---|---|
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: --- 19 unchanged lines hidden (view full) --- 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 * 32 */ 33#include <linux/kernel.h> 34#include <linux/slab.h> 35#include <linux/in.h> | 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: --- 19 unchanged lines hidden (view full) --- 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 * 32 */ 33#include <linux/kernel.h> 34#include <linux/slab.h> 35#include <linux/in.h> |
36#include <net/net_namespace.h> 37#include <net/netns/generic.h> |
|
36 37#include "rds_single_path.h" 38#include "rds.h" 39#include "loop.h" 40 41static DEFINE_SPINLOCK(loop_conns_lock); 42static LIST_HEAD(loop_conns); | 38 39#include "rds_single_path.h" 40#include "rds.h" 41#include "loop.h" 42 43static DEFINE_SPINLOCK(loop_conns_lock); 44static LIST_HEAD(loop_conns); |
45static atomic_t rds_loop_unloading = ATOMIC_INIT(0); |
|
43 | 46 |
47static void rds_loop_set_unloading(void) 48{ 49 atomic_set(&rds_loop_unloading, 1); 50} 51 52static bool rds_loop_is_unloading(struct rds_connection *conn) 53{ 54 return atomic_read(&rds_loop_unloading) != 0; 55} 56 |
|
44/* 45 * This 'loopback' transport is a special case for flows that originate 46 * and terminate on the same machine. 47 * 48 * Connection build-up notices if the destination address is thought of 49 * as a local address by a transport. At that time it decides to use the 50 * loopback transport instead of the bound transport of the sending socket. 51 * --- 108 unchanged lines hidden (view full) --- 160{ 161} 162 163void rds_loop_exit(void) 164{ 165 struct rds_loop_connection *lc, *_lc; 166 LIST_HEAD(tmp_list); 167 | 57/* 58 * This 'loopback' transport is a special case for flows that originate 59 * and terminate on the same machine. 60 * 61 * Connection build-up notices if the destination address is thought of 62 * as a local address by a transport. At that time it decides to use the 63 * loopback transport instead of the bound transport of the sending socket. 64 * --- 108 unchanged lines hidden (view full) --- 173{ 174} 175 176void rds_loop_exit(void) 177{ 178 struct rds_loop_connection *lc, *_lc; 179 LIST_HEAD(tmp_list); 180 |
181 rds_loop_set_unloading(); 182 synchronize_rcu(); |
|
168 /* avoid calling conn_destroy with irqs off */ 169 spin_lock_irq(&loop_conns_lock); 170 list_splice(&loop_conns, &tmp_list); 171 INIT_LIST_HEAD(&loop_conns); 172 spin_unlock_irq(&loop_conns_lock); 173 174 list_for_each_entry_safe(lc, _lc, &tmp_list, loop_node) { 175 WARN_ON(lc->conn->c_passive); 176 rds_conn_destroy(lc->conn); 177 } 178} 179 | 183 /* avoid calling conn_destroy with irqs off */ 184 spin_lock_irq(&loop_conns_lock); 185 list_splice(&loop_conns, &tmp_list); 186 INIT_LIST_HEAD(&loop_conns); 187 spin_unlock_irq(&loop_conns_lock); 188 189 list_for_each_entry_safe(lc, _lc, &tmp_list, loop_node) { 190 WARN_ON(lc->conn->c_passive); 191 rds_conn_destroy(lc->conn); 192 } 193} 194 |
195static void rds_loop_kill_conns(struct net *net) 196{ 197 struct rds_loop_connection *lc, *_lc; 198 LIST_HEAD(tmp_list); 199 200 spin_lock_irq(&loop_conns_lock); 201 list_for_each_entry_safe(lc, _lc, &loop_conns, loop_node) { 202 struct net *c_net = read_pnet(&lc->conn->c_net); 203 204 if (net != c_net) 205 continue; 206 list_move_tail(&lc->loop_node, &tmp_list); 207 } 208 spin_unlock_irq(&loop_conns_lock); 209 210 list_for_each_entry_safe(lc, _lc, &tmp_list, loop_node) { 211 WARN_ON(lc->conn->c_passive); 212 rds_conn_destroy(lc->conn); 213 } 214} 215 216static void __net_exit rds_loop_exit_net(struct net *net) 217{ 218 rds_loop_kill_conns(net); 219} 220 221static struct pernet_operations rds_loop_net_ops = { 222 .exit = rds_loop_exit_net, 223}; 224 225int rds_loop_net_init(void) 226{ 227 return register_pernet_device(&rds_loop_net_ops); 228} 229 230void rds_loop_net_exit(void) 231{ 232 unregister_pernet_device(&rds_loop_net_ops); 233} 234 |
|
180/* 181 * This is missing .xmit_* because loop doesn't go through generic 182 * rds_send_xmit() and doesn't call rds_recv_incoming(). .listen_stop and 183 * .laddr_check are missing because transport.c doesn't iterate over 184 * rds_loop_transport. 185 */ 186struct rds_transport rds_loop_transport = { 187 .xmit = rds_loop_xmit, 188 .recv_path = rds_loop_recv_path, 189 .conn_alloc = rds_loop_conn_alloc, 190 .conn_free = rds_loop_conn_free, 191 .conn_path_connect = rds_loop_conn_path_connect, 192 .conn_path_shutdown = rds_loop_conn_path_shutdown, 193 .inc_copy_to_user = rds_message_inc_copy_to_user, 194 .inc_free = rds_loop_inc_free, 195 .t_name = "loopback", 196 .t_type = RDS_TRANS_LOOP, | 235/* 236 * This is missing .xmit_* because loop doesn't go through generic 237 * rds_send_xmit() and doesn't call rds_recv_incoming(). .listen_stop and 238 * .laddr_check are missing because transport.c doesn't iterate over 239 * rds_loop_transport. 240 */ 241struct rds_transport rds_loop_transport = { 242 .xmit = rds_loop_xmit, 243 .recv_path = rds_loop_recv_path, 244 .conn_alloc = rds_loop_conn_alloc, 245 .conn_free = rds_loop_conn_free, 246 .conn_path_connect = rds_loop_conn_path_connect, 247 .conn_path_shutdown = rds_loop_conn_path_shutdown, 248 .inc_copy_to_user = rds_message_inc_copy_to_user, 249 .inc_free = rds_loop_inc_free, 250 .t_name = "loopback", 251 .t_type = RDS_TRANS_LOOP, |
252 .t_unloading = rds_loop_is_unloading, |
|
197}; | 253}; |