loop.c (c74a7469f97c0f40b46e82ee979f9fb1bb6e847c) | loop.c (eee2fa6ab3225192d6d894c54a6fb02ac9efdff6) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2006 Oracle. All rights reserved. | 2 * Copyright (c) 2006, 2017 Oracle and/or its affiliates. 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: 9 * 10 * Redistribution and use in source and binary forms, with or --- 17 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> | 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: 9 * 10 * Redistribution and use in source and binary forms, with or --- 17 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> 38#include <linux/ipv6.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); | 39 40#include "rds_single_path.h" 41#include "rds.h" 42#include "loop.h" 43 44static DEFINE_SPINLOCK(loop_conns_lock); 45static LIST_HEAD(loop_conns); |
46static atomic_t rds_loop_unloading = ATOMIC_INIT(0); |
|
43 | 47 |
48static void rds_loop_set_unloading(void) 49{ 50 atomic_set(&rds_loop_unloading, 1); 51} 52 53static bool rds_loop_is_unloading(struct rds_connection *conn) 54{ 55 return atomic_read(&rds_loop_unloading) != 0; 56} 57 |
|
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 * --- 18 unchanged lines hidden (view full) --- 70 if (rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { 71 rds_cong_map_updated(conn->c_fcong, ~(u64) 0); 72 ret = min_t(int, ret, sgp->length - conn->c_xmit_data_off); 73 goto out; 74 } 75 76 BUG_ON(hdr_off || sg || off); 77 | 58/* 59 * This 'loopback' transport is a special case for flows that originate 60 * and terminate on the same machine. 61 * 62 * Connection build-up notices if the destination address is thought of 63 * as a local address by a transport. At that time it decides to use the 64 * loopback transport instead of the bound transport of the sending socket. 65 * --- 18 unchanged lines hidden (view full) --- 84 if (rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { 85 rds_cong_map_updated(conn->c_fcong, ~(u64) 0); 86 ret = min_t(int, ret, sgp->length - conn->c_xmit_data_off); 87 goto out; 88 } 89 90 BUG_ON(hdr_off || sg || off); 91 |
78 rds_inc_init(&rm->m_inc, conn, conn->c_laddr); | 92 rds_inc_init(&rm->m_inc, conn, &conn->c_laddr); |
79 /* For the embedded inc. Matching put is in loop_inc_free() */ 80 rds_message_addref(rm); 81 | 93 /* For the embedded inc. Matching put is in loop_inc_free() */ 94 rds_message_addref(rm); 95 |
82 rds_recv_incoming(conn, conn->c_laddr, conn->c_faddr, &rm->m_inc, | 96 rds_recv_incoming(conn, &conn->c_laddr, &conn->c_faddr, &rm->m_inc, |
83 GFP_KERNEL); 84 85 rds_send_drop_acked(conn, be64_to_cpu(rm->m_inc.i_hdr.h_sequence), 86 NULL); 87 88 rds_inc_put(&rm->m_inc); 89out: 90 return ret; --- 69 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 | 97 GFP_KERNEL); 98 99 rds_send_drop_acked(conn, be64_to_cpu(rm->m_inc.i_hdr.h_sequence), 100 NULL); 101 102 rds_inc_put(&rm->m_inc); 103out: 104 return ret; --- 69 unchanged lines hidden (view full) --- 174{ 175} 176 177void rds_loop_exit(void) 178{ 179 struct rds_loop_connection *lc, *_lc; 180 LIST_HEAD(tmp_list); 181 |
182 rds_loop_set_unloading(); 183 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 | 184 /* avoid calling conn_destroy with irqs off */ 185 spin_lock_irq(&loop_conns_lock); 186 list_splice(&loop_conns, &tmp_list); 187 INIT_LIST_HEAD(&loop_conns); 188 spin_unlock_irq(&loop_conns_lock); 189 190 list_for_each_entry_safe(lc, _lc, &tmp_list, loop_node) { 191 WARN_ON(lc->conn->c_passive); 192 rds_conn_destroy(lc->conn); 193 } 194} 195 |
196static void rds_loop_kill_conns(struct net *net) 197{ 198 struct rds_loop_connection *lc, *_lc; 199 LIST_HEAD(tmp_list); 200 201 spin_lock_irq(&loop_conns_lock); 202 list_for_each_entry_safe(lc, _lc, &loop_conns, loop_node) { 203 struct net *c_net = read_pnet(&lc->conn->c_net); 204 205 if (net != c_net) 206 continue; 207 list_move_tail(&lc->loop_node, &tmp_list); 208 } 209 spin_unlock_irq(&loop_conns_lock); 210 211 list_for_each_entry_safe(lc, _lc, &tmp_list, loop_node) { 212 WARN_ON(lc->conn->c_passive); 213 rds_conn_destroy(lc->conn); 214 } 215} 216 217static void __net_exit rds_loop_exit_net(struct net *net) 218{ 219 rds_loop_kill_conns(net); 220} 221 222static struct pernet_operations rds_loop_net_ops = { 223 .exit = rds_loop_exit_net, 224}; 225 226int rds_loop_net_init(void) 227{ 228 return register_pernet_device(&rds_loop_net_ops); 229} 230 231void rds_loop_net_exit(void) 232{ 233 unregister_pernet_device(&rds_loop_net_ops); 234} 235 |
|
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, | 236/* 237 * This is missing .xmit_* because loop doesn't go through generic 238 * rds_send_xmit() and doesn't call rds_recv_incoming(). .listen_stop and 239 * .laddr_check are missing because transport.c doesn't iterate over 240 * rds_loop_transport. 241 */ 242struct rds_transport rds_loop_transport = { 243 .xmit = rds_loop_xmit, 244 .recv_path = rds_loop_recv_path, 245 .conn_alloc = rds_loop_conn_alloc, 246 .conn_free = rds_loop_conn_free, 247 .conn_path_connect = rds_loop_conn_path_connect, 248 .conn_path_shutdown = rds_loop_conn_path_shutdown, 249 .inc_copy_to_user = rds_message_inc_copy_to_user, 250 .inc_free = rds_loop_inc_free, 251 .t_name = "loopback", 252 .t_type = RDS_TRANS_LOOP, |
253 .t_unloading = rds_loop_is_unloading, |
|
197}; | 254}; |