aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-06-17 05:06:56 -0400
committerDavid Howells <dhowells@redhat.com>2016-06-22 09:00:23 -0400
commitaa390bbe2113dd0de99cf35c39d7701d4412b744 (patch)
treefd836f0bacb921ec94909a03ae801e5db855549b
parent999b69f89241c9384c104b84329c13350fd696ef (diff)
rxrpc: Kill off the rxrpc_transport struct
The rxrpc_transport struct is now redundant, given that the rxrpc_peer struct is now per peer port rather than per peer host, so get rid of it. Service connection lists are transferred to the rxrpc_peer struct, as is the conn_lock. Previous patches moved the client connection handling out of the rxrpc_transport struct and discarded the connection bundling code. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--net/rxrpc/Makefile1
-rw-r--r--net/rxrpc/af_rxrpc.c46
-rw-r--r--net/rxrpc/ar-internal.h57
-rw-r--r--net/rxrpc/call_accept.c11
-rw-r--r--net/rxrpc/call_object.c16
-rw-r--r--net/rxrpc/conn_object.c78
-rw-r--r--net/rxrpc/input.c8
-rw-r--r--net/rxrpc/output.c24
-rw-r--r--net/rxrpc/peer_object.c2
-rw-r--r--net/rxrpc/sysctl.c8
-rw-r--r--net/rxrpc/transport.c265
11 files changed, 65 insertions, 451 deletions
diff --git a/net/rxrpc/Makefile b/net/rxrpc/Makefile
index cfa221536f33..6522e50fb750 100644
--- a/net/rxrpc/Makefile
+++ b/net/rxrpc/Makefile
@@ -22,7 +22,6 @@ af-rxrpc-y := \
22 recvmsg.o \ 22 recvmsg.o \
23 security.o \ 23 security.o \
24 skbuff.o \ 24 skbuff.o \
25 transport.o \
26 utils.o 25 utils.o
27 26
28af-rxrpc-$(CONFIG_PROC_FS) += proc.o 27af-rxrpc-$(CONFIG_PROC_FS) += proc.o
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index f3b6ed8196c3..5d3e795a7c48 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -224,37 +224,6 @@ static int rxrpc_listen(struct socket *sock, int backlog)
224 return ret; 224 return ret;
225} 225}
226 226
227/*
228 * find a transport by address
229 */
230struct rxrpc_transport *
231rxrpc_name_to_transport(struct rxrpc_conn_parameters *cp,
232 struct sockaddr *addr,
233 int addr_len,
234 gfp_t gfp)
235{
236 struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *) addr;
237 struct rxrpc_transport *trans;
238
239 _enter("%p,%d", addr, addr_len);
240
241 if (cp->local->srx.transport_type != srx->transport_type)
242 return ERR_PTR(-ESOCKTNOSUPPORT);
243 if (cp->local->srx.transport.family != srx->transport.family)
244 return ERR_PTR(-EAFNOSUPPORT);
245
246 /* find a remote transport endpoint from the local one */
247 cp->peer = rxrpc_lookup_peer(cp->local, srx, gfp);
248 if (!cp->peer)
249 return ERR_PTR(-ENOMEM);
250
251 /* find a transport */
252 trans = rxrpc_get_transport(cp->local, cp->peer, gfp);
253 rxrpc_put_peer(cp->peer);
254 _leave(" = %p", trans);
255 return trans;
256}
257
258/** 227/**
259 * rxrpc_kernel_begin_call - Allow a kernel service to begin a call 228 * rxrpc_kernel_begin_call - Allow a kernel service to begin a call
260 * @sock: The socket on which to make the call 229 * @sock: The socket on which to make the call
@@ -276,7 +245,6 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
276 gfp_t gfp) 245 gfp_t gfp)
277{ 246{
278 struct rxrpc_conn_parameters cp; 247 struct rxrpc_conn_parameters cp;
279 struct rxrpc_transport *trans;
280 struct rxrpc_call *call; 248 struct rxrpc_call *call;
281 struct rxrpc_sock *rx = rxrpc_sk(sock->sk); 249 struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
282 int ret; 250 int ret;
@@ -300,19 +268,8 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
300 cp.security_level = 0; 268 cp.security_level = 0;
301 cp.exclusive = false; 269 cp.exclusive = false;
302 cp.service_id = srx->srx_service; 270 cp.service_id = srx->srx_service;
271 call = rxrpc_new_client_call(rx, &cp, srx, user_call_ID, gfp);
303 272
304 trans = rxrpc_name_to_transport(&cp, (struct sockaddr *)srx,
305 sizeof(*srx), gfp);
306 if (IS_ERR(trans)) {
307 call = ERR_CAST(trans);
308 trans = NULL;
309 goto out_notrans;
310 }
311 cp.peer = trans->peer;
312
313 call = rxrpc_new_client_call(rx, &cp, trans, srx, user_call_ID, gfp);
314 rxrpc_put_transport(trans);
315out_notrans:
316 release_sock(&rx->sk); 273 release_sock(&rx->sk);
317 _leave(" = %p", call); 274 _leave(" = %p", call);
318 return call; 275 return call;
@@ -831,7 +788,6 @@ static void __exit af_rxrpc_exit(void)
831 proto_unregister(&rxrpc_proto); 788 proto_unregister(&rxrpc_proto);
832 rxrpc_destroy_all_calls(); 789 rxrpc_destroy_all_calls();
833 rxrpc_destroy_all_connections(); 790 rxrpc_destroy_all_connections();
834 rxrpc_destroy_all_transports();
835 791
836 ASSERTCMP(atomic_read(&rxrpc_n_skbs), ==, 0); 792 ASSERTCMP(atomic_read(&rxrpc_n_skbs), ==, 0);
837 793
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 26fe137d62bb..702db72196fb 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -207,6 +207,8 @@ struct rxrpc_peer {
207 struct rxrpc_local *local; 207 struct rxrpc_local *local;
208 struct hlist_head error_targets; /* targets for net error distribution */ 208 struct hlist_head error_targets; /* targets for net error distribution */
209 struct work_struct error_distributor; 209 struct work_struct error_distributor;
210 struct rb_root service_conns; /* Service connections */
211 rwlock_t conn_lock;
210 spinlock_t lock; /* access lock */ 212 spinlock_t lock; /* access lock */
211 unsigned int if_mtu; /* interface MTU for this peer */ 213 unsigned int if_mtu; /* interface MTU for this peer */
212 unsigned int mtu; /* network MTU for this peer */ 214 unsigned int mtu; /* network MTU for this peer */
@@ -226,22 +228,6 @@ struct rxrpc_peer {
226}; 228};
227 229
228/* 230/*
229 * RxRPC point-to-point transport / connection manager definition
230 * - handles a bundle of connections between two endpoints
231 * - matched by { local, peer }
232 */
233struct rxrpc_transport {
234 struct rxrpc_local *local; /* local transport endpoint */
235 struct rxrpc_peer *peer; /* remote transport endpoint */
236 struct rb_root server_conns; /* server connections on this transport */
237 struct list_head link; /* link in master session list */
238 unsigned long put_time; /* time at which to reap */
239 rwlock_t conn_lock; /* lock for active/dead connections */
240 atomic_t usage;
241 int debug_id; /* debug ID for printks */
242};
243
244/*
245 * Keys for matching a connection. 231 * Keys for matching a connection.
246 */ 232 */
247struct rxrpc_conn_proto { 233struct rxrpc_conn_proto {
@@ -271,11 +257,10 @@ struct rxrpc_conn_parameters {
271 257
272/* 258/*
273 * RxRPC connection definition 259 * RxRPC connection definition
274 * - matched by { transport, service_id, conn_id, direction, key } 260 * - matched by { local, peer, epoch, conn_id, direction }
275 * - each connection can only handle four simultaneous calls 261 * - each connection can only handle four simultaneous calls
276 */ 262 */
277struct rxrpc_connection { 263struct rxrpc_connection {
278 struct rxrpc_transport *trans; /* transport session */
279 struct rxrpc_conn_proto proto; 264 struct rxrpc_conn_proto proto;
280 struct rxrpc_conn_parameters params; 265 struct rxrpc_conn_parameters params;
281 266
@@ -286,7 +271,7 @@ struct rxrpc_connection {
286 struct work_struct processor; /* connection event processor */ 271 struct work_struct processor; /* connection event processor */
287 union { 272 union {
288 struct rb_node client_node; /* Node in local->client_conns */ 273 struct rb_node client_node; /* Node in local->client_conns */
289 struct rb_node service_node; /* Node in trans->server_conns */ 274 struct rb_node service_node; /* Node in peer->service_conns */
290 }; 275 };
291 struct list_head link; /* link in master connection list */ 276 struct list_head link; /* link in master connection list */
292 struct rb_root calls; /* calls on this connection */ 277 struct rb_root calls; /* calls on this connection */
@@ -494,10 +479,6 @@ extern u32 rxrpc_epoch;
494extern atomic_t rxrpc_debug_id; 479extern atomic_t rxrpc_debug_id;
495extern struct workqueue_struct *rxrpc_workqueue; 480extern struct workqueue_struct *rxrpc_workqueue;
496 481
497extern struct rxrpc_transport *rxrpc_name_to_transport(struct rxrpc_conn_parameters *,
498 struct sockaddr *,
499 int, gfp_t);
500
501/* 482/*
502 * call_accept.c 483 * call_accept.c
503 */ 484 */
@@ -526,7 +507,6 @@ struct rxrpc_call *rxrpc_find_call_hash(struct rxrpc_host_header *,
526struct rxrpc_call *rxrpc_find_call_by_user_ID(struct rxrpc_sock *, unsigned long); 507struct rxrpc_call *rxrpc_find_call_by_user_ID(struct rxrpc_sock *, unsigned long);
527struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *, 508struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *,
528 struct rxrpc_conn_parameters *, 509 struct rxrpc_conn_parameters *,
529 struct rxrpc_transport *,
530 struct sockaddr_rxrpc *, 510 struct sockaddr_rxrpc *,
531 unsigned long, gfp_t); 511 unsigned long, gfp_t);
532struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *, 512struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *,
@@ -560,15 +540,16 @@ extern struct list_head rxrpc_connections;
560extern rwlock_t rxrpc_connection_lock; 540extern rwlock_t rxrpc_connection_lock;
561 541
562int rxrpc_connect_call(struct rxrpc_call *, struct rxrpc_conn_parameters *, 542int rxrpc_connect_call(struct rxrpc_call *, struct rxrpc_conn_parameters *,
563 struct rxrpc_transport *,
564 struct sockaddr_rxrpc *, gfp_t); 543 struct sockaddr_rxrpc *, gfp_t);
544struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *,
545 struct rxrpc_peer *,
546 struct sk_buff *);
565void rxrpc_disconnect_call(struct rxrpc_call *); 547void rxrpc_disconnect_call(struct rxrpc_call *);
566void rxrpc_put_connection(struct rxrpc_connection *); 548void rxrpc_put_connection(struct rxrpc_connection *);
567void __exit rxrpc_destroy_all_connections(void); 549void __exit rxrpc_destroy_all_connections(void);
568struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *, 550struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_local *,
569 struct sk_buff *); 551 struct rxrpc_peer *,
570extern struct rxrpc_connection * 552 struct sk_buff *);
571rxrpc_incoming_connection(struct rxrpc_transport *, struct sk_buff *);
572 553
573static inline bool rxrpc_conn_is_client(const struct rxrpc_connection *conn) 554static inline bool rxrpc_conn_is_client(const struct rxrpc_connection *conn)
574{ 555{
@@ -585,12 +566,6 @@ static inline void rxrpc_get_connection(struct rxrpc_connection *conn)
585 atomic_inc(&conn->usage); 566 atomic_inc(&conn->usage);
586} 567}
587 568
588static inline
589struct rxrpc_connection *rxrpc_get_connection_maybe(struct rxrpc_connection *conn)
590{
591 return atomic_inc_not_zero(&conn->usage) ? conn : NULL;
592}
593
594/* 569/*
595 * input.c 570 * input.c
596 */ 571 */
@@ -745,18 +720,6 @@ static inline void rxrpc_sysctl_exit(void) {}
745#endif 720#endif
746 721
747/* 722/*
748 * transport.c
749 */
750extern unsigned int rxrpc_transport_expiry;
751
752struct rxrpc_transport *rxrpc_get_transport(struct rxrpc_local *,
753 struct rxrpc_peer *, gfp_t);
754void rxrpc_put_transport(struct rxrpc_transport *);
755void __exit rxrpc_destroy_all_transports(void);
756struct rxrpc_transport *rxrpc_find_transport(struct rxrpc_local *,
757 struct rxrpc_peer *);
758
759/*
760 * utils.c 723 * utils.c
761 */ 724 */
762void rxrpc_get_addr_from_skb(struct rxrpc_local *, const struct sk_buff *, 725void rxrpc_get_addr_from_skb(struct rxrpc_local *, const struct sk_buff *,
diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c
index 833ad0622b61..202e053a3c6d 100644
--- a/net/rxrpc/call_accept.c
+++ b/net/rxrpc/call_accept.c
@@ -74,7 +74,6 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
74 struct sockaddr_rxrpc *srx) 74 struct sockaddr_rxrpc *srx)
75{ 75{
76 struct rxrpc_connection *conn; 76 struct rxrpc_connection *conn;
77 struct rxrpc_transport *trans;
78 struct rxrpc_skb_priv *sp, *nsp; 77 struct rxrpc_skb_priv *sp, *nsp;
79 struct rxrpc_peer *peer; 78 struct rxrpc_peer *peer;
80 struct rxrpc_call *call; 79 struct rxrpc_call *call;
@@ -102,16 +101,8 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
102 goto error; 101 goto error;
103 } 102 }
104 103
105 trans = rxrpc_get_transport(local, peer, GFP_NOIO); 104 conn = rxrpc_incoming_connection(local, peer, skb);
106 rxrpc_put_peer(peer); 105 rxrpc_put_peer(peer);
107 if (IS_ERR(trans)) {
108 _debug("no trans");
109 ret = -EBUSY;
110 goto error;
111 }
112
113 conn = rxrpc_incoming_connection(trans, skb);
114 rxrpc_put_transport(trans);
115 if (IS_ERR(conn)) { 106 if (IS_ERR(conn)) {
116 _debug("no conn"); 107 _debug("no conn");
117 ret = PTR_ERR(conn); 108 ret = PTR_ERR(conn);
diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
index 9b3b48abe12f..ad933daae13b 100644
--- a/net/rxrpc/call_object.c
+++ b/net/rxrpc/call_object.c
@@ -286,11 +286,9 @@ static struct rxrpc_call *rxrpc_alloc_call(gfp_t gfp)
286/* 286/*
287 * Allocate a new client call. 287 * Allocate a new client call.
288 */ 288 */
289static struct rxrpc_call *rxrpc_alloc_client_call( 289static struct rxrpc_call *rxrpc_alloc_client_call(struct rxrpc_sock *rx,
290 struct rxrpc_sock *rx, 290 struct sockaddr_rxrpc *srx,
291 struct rxrpc_conn_parameters *cp, 291 gfp_t gfp)
292 struct sockaddr_rxrpc *srx,
293 gfp_t gfp)
294{ 292{
295 struct rxrpc_call *call; 293 struct rxrpc_call *call;
296 294
@@ -333,7 +331,6 @@ static struct rxrpc_call *rxrpc_alloc_client_call(
333 */ 331 */
334static int rxrpc_begin_client_call(struct rxrpc_call *call, 332static int rxrpc_begin_client_call(struct rxrpc_call *call,
335 struct rxrpc_conn_parameters *cp, 333 struct rxrpc_conn_parameters *cp,
336 struct rxrpc_transport *trans,
337 struct sockaddr_rxrpc *srx, 334 struct sockaddr_rxrpc *srx,
338 gfp_t gfp) 335 gfp_t gfp)
339{ 336{
@@ -342,7 +339,7 @@ static int rxrpc_begin_client_call(struct rxrpc_call *call,
342 /* Set up or get a connection record and set the protocol parameters, 339 /* Set up or get a connection record and set the protocol parameters,
343 * including channel number and call ID. 340 * including channel number and call ID.
344 */ 341 */
345 ret = rxrpc_connect_call(call, cp, trans, srx, gfp); 342 ret = rxrpc_connect_call(call, cp, srx, gfp);
346 if (ret < 0) 343 if (ret < 0)
347 return ret; 344 return ret;
348 345
@@ -366,7 +363,6 @@ static int rxrpc_begin_client_call(struct rxrpc_call *call,
366 */ 363 */
367struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, 364struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
368 struct rxrpc_conn_parameters *cp, 365 struct rxrpc_conn_parameters *cp,
369 struct rxrpc_transport *trans,
370 struct sockaddr_rxrpc *srx, 366 struct sockaddr_rxrpc *srx,
371 unsigned long user_call_ID, 367 unsigned long user_call_ID,
372 gfp_t gfp) 368 gfp_t gfp)
@@ -377,7 +373,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
377 373
378 _enter("%p,%lx", rx, user_call_ID); 374 _enter("%p,%lx", rx, user_call_ID);
379 375
380 call = rxrpc_alloc_client_call(rx, cp, srx, gfp); 376 call = rxrpc_alloc_client_call(rx, srx, gfp);
381 if (IS_ERR(call)) { 377 if (IS_ERR(call)) {
382 _leave(" = %ld", PTR_ERR(call)); 378 _leave(" = %ld", PTR_ERR(call));
383 return call; 379 return call;
@@ -413,7 +409,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
413 list_add_tail(&call->link, &rxrpc_calls); 409 list_add_tail(&call->link, &rxrpc_calls);
414 write_unlock_bh(&rxrpc_call_lock); 410 write_unlock_bh(&rxrpc_call_lock);
415 411
416 ret = rxrpc_begin_client_call(call, cp, trans, srx, gfp); 412 ret = rxrpc_begin_client_call(call, cp, srx, gfp);
417 if (ret < 0) 413 if (ret < 0)
418 goto error; 414 goto error;
419 415
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
index 276ff505394f..4bfad7cf96cb 100644
--- a/net/rxrpc/conn_object.c
+++ b/net/rxrpc/conn_object.c
@@ -100,9 +100,7 @@ static void rxrpc_add_call_ID_to_conn(struct rxrpc_connection *conn,
100 * padding bytes in *cp. 100 * padding bytes in *cp.
101 */ 101 */
102static struct rxrpc_connection * 102static struct rxrpc_connection *
103rxrpc_alloc_client_connection(struct rxrpc_conn_parameters *cp, 103rxrpc_alloc_client_connection(struct rxrpc_conn_parameters *cp, gfp_t gfp)
104 struct rxrpc_transport *trans,
105 gfp_t gfp)
106{ 104{
107 struct rxrpc_connection *conn; 105 struct rxrpc_connection *conn;
108 int ret; 106 int ret;
@@ -146,9 +144,10 @@ rxrpc_alloc_client_connection(struct rxrpc_conn_parameters *cp,
146 list_add_tail(&conn->link, &rxrpc_connections); 144 list_add_tail(&conn->link, &rxrpc_connections);
147 write_unlock(&rxrpc_connection_lock); 145 write_unlock(&rxrpc_connection_lock);
148 146
147 /* We steal the caller's peer ref. */
148 cp->peer = NULL;
149 rxrpc_get_local(conn->params.local);
149 key_get(conn->params.key); 150 key_get(conn->params.key);
150 conn->trans = trans;
151 atomic_inc(&trans->usage);
152 151
153 _leave(" = %p", conn); 152 _leave(" = %p", conn);
154 return conn; 153 return conn;
@@ -167,7 +166,6 @@ error_0:
167 */ 166 */
168int rxrpc_connect_call(struct rxrpc_call *call, 167int rxrpc_connect_call(struct rxrpc_call *call,
169 struct rxrpc_conn_parameters *cp, 168 struct rxrpc_conn_parameters *cp,
170 struct rxrpc_transport *trans,
171 struct sockaddr_rxrpc *srx, 169 struct sockaddr_rxrpc *srx,
172 gfp_t gfp) 170 gfp_t gfp)
173{ 171{
@@ -181,8 +179,9 @@ int rxrpc_connect_call(struct rxrpc_call *call,
181 179
182 _enter("{%d,%lx},", call->debug_id, call->user_call_ID); 180 _enter("{%d,%lx},", call->debug_id, call->user_call_ID);
183 181
184 cp->peer = trans->peer; 182 cp->peer = rxrpc_lookup_peer(cp->local, srx, gfp);
185 rxrpc_get_peer(cp->peer); 183 if (!cp->peer)
184 return -ENOMEM;
186 185
187 if (!cp->exclusive) { 186 if (!cp->exclusive) {
188 /* Search for a existing client connection unless this is going 187 /* Search for a existing client connection unless this is going
@@ -210,7 +209,7 @@ int rxrpc_connect_call(struct rxrpc_call *call,
210 209
211 /* We didn't find a connection or we want an exclusive one. */ 210 /* We didn't find a connection or we want an exclusive one. */
212 _debug("get new conn"); 211 _debug("get new conn");
213 candidate = rxrpc_alloc_client_connection(cp, trans, gfp); 212 candidate = rxrpc_alloc_client_connection(cp, gfp);
214 if (!candidate) { 213 if (!candidate) {
215 _leave(" = -ENOMEM"); 214 _leave(" = -ENOMEM");
216 return -ENOMEM; 215 return -ENOMEM;
@@ -281,6 +280,8 @@ found_channel:
281 280
282 rxrpc_add_call_ID_to_conn(conn, call); 281 rxrpc_add_call_ID_to_conn(conn, call);
283 spin_unlock(&conn->channel_lock); 282 spin_unlock(&conn->channel_lock);
283 rxrpc_put_peer(cp->peer);
284 cp->peer = NULL;
284 _leave(" = %p {u=%d}", conn, atomic_read(&conn->usage)); 285 _leave(" = %p {u=%d}", conn, atomic_read(&conn->usage));
285 return 0; 286 return 0;
286 287
@@ -329,6 +330,8 @@ interrupted:
329 remove_wait_queue(&conn->channel_wq, &myself); 330 remove_wait_queue(&conn->channel_wq, &myself);
330 __set_current_state(TASK_RUNNING); 331 __set_current_state(TASK_RUNNING);
331 rxrpc_put_connection(conn); 332 rxrpc_put_connection(conn);
333 rxrpc_put_peer(cp->peer);
334 cp->peer = NULL;
332 _leave(" = -ERESTARTSYS"); 335 _leave(" = -ERESTARTSYS");
333 return -ERESTARTSYS; 336 return -ERESTARTSYS;
334} 337}
@@ -336,7 +339,8 @@ interrupted:
336/* 339/*
337 * get a record of an incoming connection 340 * get a record of an incoming connection
338 */ 341 */
339struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_transport *trans, 342struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_local *local,
343 struct rxrpc_peer *peer,
340 struct sk_buff *skb) 344 struct sk_buff *skb)
341{ 345{
342 struct rxrpc_connection *conn, *candidate = NULL; 346 struct rxrpc_connection *conn, *candidate = NULL;
@@ -354,9 +358,9 @@ struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_transport *trans
354 cid = sp->hdr.cid & RXRPC_CIDMASK; 358 cid = sp->hdr.cid & RXRPC_CIDMASK;
355 359
356 /* search the connection list first */ 360 /* search the connection list first */
357 read_lock_bh(&trans->conn_lock); 361 read_lock_bh(&peer->conn_lock);
358 362
359 p = trans->server_conns.rb_node; 363 p = peer->service_conns.rb_node;
360 while (p) { 364 while (p) {
361 conn = rb_entry(p, struct rxrpc_connection, service_node); 365 conn = rb_entry(p, struct rxrpc_connection, service_node);
362 366
@@ -373,7 +377,7 @@ struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_transport *trans
373 else 377 else
374 goto found_extant_connection; 378 goto found_extant_connection;
375 } 379 }
376 read_unlock_bh(&trans->conn_lock); 380 read_unlock_bh(&peer->conn_lock);
377 381
378 /* not yet present - create a candidate for a new record and then 382 /* not yet present - create a candidate for a new record and then
379 * redo the search */ 383 * redo the search */
@@ -383,13 +387,12 @@ struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_transport *trans
383 return ERR_PTR(-ENOMEM); 387 return ERR_PTR(-ENOMEM);
384 } 388 }
385 389
386 candidate->trans = trans; 390 candidate->proto.local = local;
387 candidate->proto.local = trans->local;
388 candidate->proto.epoch = sp->hdr.epoch; 391 candidate->proto.epoch = sp->hdr.epoch;
389 candidate->proto.cid = sp->hdr.cid & RXRPC_CIDMASK; 392 candidate->proto.cid = sp->hdr.cid & RXRPC_CIDMASK;
390 candidate->proto.in_clientflag = RXRPC_CLIENT_INITIATED; 393 candidate->proto.in_clientflag = RXRPC_CLIENT_INITIATED;
391 candidate->params.local = trans->local; 394 candidate->params.local = local;
392 candidate->params.peer = trans->peer; 395 candidate->params.peer = peer;
393 candidate->params.service_id = sp->hdr.serviceId; 396 candidate->params.service_id = sp->hdr.serviceId;
394 candidate->security_ix = sp->hdr.securityIndex; 397 candidate->security_ix = sp->hdr.securityIndex;
395 candidate->out_clientflag = 0; 398 candidate->out_clientflag = 0;
@@ -397,9 +400,9 @@ struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_transport *trans
397 if (candidate->params.service_id) 400 if (candidate->params.service_id)
398 candidate->state = RXRPC_CONN_SERVER_UNSECURED; 401 candidate->state = RXRPC_CONN_SERVER_UNSECURED;
399 402
400 write_lock_bh(&trans->conn_lock); 403 write_lock_bh(&peer->conn_lock);
401 404
402 pp = &trans->server_conns.rb_node; 405 pp = &peer->service_conns.rb_node;
403 p = NULL; 406 p = NULL;
404 while (*pp) { 407 while (*pp) {
405 p = *pp; 408 p = *pp;
@@ -421,10 +424,11 @@ struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_transport *trans
421 conn = candidate; 424 conn = candidate;
422 candidate = NULL; 425 candidate = NULL;
423 rb_link_node(&conn->service_node, p, pp); 426 rb_link_node(&conn->service_node, p, pp);
424 rb_insert_color(&conn->service_node, &trans->server_conns); 427 rb_insert_color(&conn->service_node, &peer->service_conns);
425 atomic_inc(&conn->trans->usage); 428 rxrpc_get_peer(peer);
429 rxrpc_get_local(local);
426 430
427 write_unlock_bh(&trans->conn_lock); 431 write_unlock_bh(&peer->conn_lock);
428 432
429 write_lock(&rxrpc_connection_lock); 433 write_lock(&rxrpc_connection_lock);
430 list_add_tail(&conn->link, &rxrpc_connections); 434 list_add_tail(&conn->link, &rxrpc_connections);
@@ -441,21 +445,21 @@ success:
441 /* we found the connection in the list immediately */ 445 /* we found the connection in the list immediately */
442found_extant_connection: 446found_extant_connection:
443 if (sp->hdr.securityIndex != conn->security_ix) { 447 if (sp->hdr.securityIndex != conn->security_ix) {
444 read_unlock_bh(&trans->conn_lock); 448 read_unlock_bh(&peer->conn_lock);
445 goto security_mismatch; 449 goto security_mismatch;
446 } 450 }
447 rxrpc_get_connection(conn); 451 rxrpc_get_connection(conn);
448 read_unlock_bh(&trans->conn_lock); 452 read_unlock_bh(&peer->conn_lock);
449 goto success; 453 goto success;
450 454
451 /* we found the connection on the second time through the list */ 455 /* we found the connection on the second time through the list */
452found_extant_second: 456found_extant_second:
453 if (sp->hdr.securityIndex != conn->security_ix) { 457 if (sp->hdr.securityIndex != conn->security_ix) {
454 write_unlock_bh(&trans->conn_lock); 458 write_unlock_bh(&peer->conn_lock);
455 goto security_mismatch; 459 goto security_mismatch;
456 } 460 }
457 rxrpc_get_connection(conn); 461 rxrpc_get_connection(conn);
458 write_unlock_bh(&trans->conn_lock); 462 write_unlock_bh(&peer->conn_lock);
459 kfree(candidate); 463 kfree(candidate);
460 goto success; 464 goto success;
461 465
@@ -469,7 +473,8 @@ security_mismatch:
469 * find a connection based on transport and RxRPC connection ID for an incoming 473 * find a connection based on transport and RxRPC connection ID for an incoming
470 * packet 474 * packet
471 */ 475 */
472struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *trans, 476struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *local,
477 struct rxrpc_peer *peer,
473 struct sk_buff *skb) 478 struct sk_buff *skb)
474{ 479{
475 struct rxrpc_connection *conn; 480 struct rxrpc_connection *conn;
@@ -479,13 +484,13 @@ struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *trans,
479 484
480 _enter(",{%x,%x}", sp->hdr.cid, sp->hdr.flags); 485 _enter(",{%x,%x}", sp->hdr.cid, sp->hdr.flags);
481 486
482 read_lock_bh(&trans->conn_lock); 487 read_lock_bh(&peer->conn_lock);
483 488
484 cid = sp->hdr.cid & RXRPC_CIDMASK; 489 cid = sp->hdr.cid & RXRPC_CIDMASK;
485 epoch = sp->hdr.epoch; 490 epoch = sp->hdr.epoch;
486 491
487 if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) { 492 if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) {
488 p = trans->server_conns.rb_node; 493 p = peer->service_conns.rb_node;
489 while (p) { 494 while (p) {
490 conn = rb_entry(p, struct rxrpc_connection, service_node); 495 conn = rb_entry(p, struct rxrpc_connection, service_node);
491 496
@@ -508,13 +513,13 @@ struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *trans,
508 goto found; 513 goto found;
509 } 514 }
510 515
511 read_unlock_bh(&trans->conn_lock); 516 read_unlock_bh(&peer->conn_lock);
512 _leave(" = NULL"); 517 _leave(" = NULL");
513 return NULL; 518 return NULL;
514 519
515found: 520found:
516 rxrpc_get_connection(conn); 521 rxrpc_get_connection(conn);
517 read_unlock_bh(&trans->conn_lock); 522 read_unlock_bh(&peer->conn_lock);
518 _leave(" = %p", conn); 523 _leave(" = %p", conn);
519 return conn; 524 return conn;
520} 525}
@@ -576,8 +581,9 @@ static void rxrpc_destroy_connection(struct rxrpc_connection *conn)
576 conn->security->clear(conn); 581 conn->security->clear(conn);
577 key_put(conn->params.key); 582 key_put(conn->params.key);
578 key_put(conn->server_key); 583 key_put(conn->server_key);
584 rxrpc_put_peer(conn->params.peer);
585 rxrpc_put_local(conn->params.local);
579 586
580 rxrpc_put_transport(conn->trans);
581 kfree(conn); 587 kfree(conn);
582 _leave(""); 588 _leave("");
583} 589}
@@ -588,6 +594,7 @@ static void rxrpc_destroy_connection(struct rxrpc_connection *conn)
588static void rxrpc_connection_reaper(struct work_struct *work) 594static void rxrpc_connection_reaper(struct work_struct *work)
589{ 595{
590 struct rxrpc_connection *conn, *_p; 596 struct rxrpc_connection *conn, *_p;
597 struct rxrpc_peer *peer;
591 unsigned long now, earliest, reap_time; 598 unsigned long now, earliest, reap_time;
592 599
593 LIST_HEAD(graveyard); 600 LIST_HEAD(graveyard);
@@ -624,7 +631,8 @@ static void rxrpc_connection_reaper(struct work_struct *work)
624 631
625 spin_unlock(&local->client_conns_lock); 632 spin_unlock(&local->client_conns_lock);
626 } else { 633 } else {
627 write_lock_bh(&conn->trans->conn_lock); 634 peer = conn->params.peer;
635 write_lock_bh(&peer->conn_lock);
628 reap_time = conn->put_time + rxrpc_connection_expiry; 636 reap_time = conn->put_time + rxrpc_connection_expiry;
629 637
630 if (atomic_read(&conn->usage) > 0) { 638 if (atomic_read(&conn->usage) > 0) {
@@ -632,12 +640,12 @@ static void rxrpc_connection_reaper(struct work_struct *work)
632 } else if (reap_time <= now) { 640 } else if (reap_time <= now) {
633 list_move_tail(&conn->link, &graveyard); 641 list_move_tail(&conn->link, &graveyard);
634 rb_erase(&conn->service_node, 642 rb_erase(&conn->service_node,
635 &conn->trans->server_conns); 643 &peer->service_conns);
636 } else if (reap_time < earliest) { 644 } else if (reap_time < earliest) {
637 earliest = reap_time; 645 earliest = reap_time;
638 } 646 }
639 647
640 write_unlock_bh(&conn->trans->conn_lock); 648 write_unlock_bh(&peer->conn_lock);
641 } 649 }
642 } 650 }
643 write_unlock(&rxrpc_connection_lock); 651 write_unlock(&rxrpc_connection_lock);
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index 799aec18aa7b..f4bd57b77b93 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -631,7 +631,6 @@ static struct rxrpc_connection *rxrpc_conn_from_local(struct rxrpc_local *local,
631 struct sk_buff *skb) 631 struct sk_buff *skb)
632{ 632{
633 struct rxrpc_peer *peer; 633 struct rxrpc_peer *peer;
634 struct rxrpc_transport *trans;
635 struct rxrpc_connection *conn; 634 struct rxrpc_connection *conn;
636 struct sockaddr_rxrpc srx; 635 struct sockaddr_rxrpc srx;
637 636
@@ -641,13 +640,8 @@ static struct rxrpc_connection *rxrpc_conn_from_local(struct rxrpc_local *local,
641 if (!peer) 640 if (!peer)
642 goto cant_find_peer; 641 goto cant_find_peer;
643 642
644 trans = rxrpc_find_transport(local, peer); 643 conn = rxrpc_find_connection(local, peer, skb);
645 rcu_read_unlock(); 644 rcu_read_unlock();
646 if (!trans)
647 goto cant_find_conn;
648
649 conn = rxrpc_find_connection(trans, skb);
650 rxrpc_put_transport(trans);
651 if (!conn) 645 if (!conn)
652 goto cant_find_conn; 646 goto cant_find_conn;
653 647
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index 8e24939aeac8..f4bda06b7d2d 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -140,10 +140,8 @@ rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg,
140 unsigned long user_call_ID, bool exclusive) 140 unsigned long user_call_ID, bool exclusive)
141{ 141{
142 struct rxrpc_conn_parameters cp; 142 struct rxrpc_conn_parameters cp;
143 struct rxrpc_transport *trans;
144 struct rxrpc_call *call; 143 struct rxrpc_call *call;
145 struct key *key; 144 struct key *key;
146 long ret;
147 145
148 DECLARE_SOCKADDR(struct sockaddr_rxrpc *, srx, msg->msg_name); 146 DECLARE_SOCKADDR(struct sockaddr_rxrpc *, srx, msg->msg_name);
149 147
@@ -162,30 +160,10 @@ rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg,
162 cp.security_level = rx->min_sec_level; 160 cp.security_level = rx->min_sec_level;
163 cp.exclusive = rx->exclusive | exclusive; 161 cp.exclusive = rx->exclusive | exclusive;
164 cp.service_id = srx->srx_service; 162 cp.service_id = srx->srx_service;
165 trans = rxrpc_name_to_transport(&cp, msg->msg_name, msg->msg_namelen, 163 call = rxrpc_new_client_call(rx, &cp, srx, user_call_ID, GFP_KERNEL);
166 GFP_KERNEL);
167 if (IS_ERR(trans)) {
168 ret = PTR_ERR(trans);
169 goto out;
170 }
171 cp.peer = trans->peer;
172
173 call = rxrpc_new_client_call(rx, &cp, trans, srx, user_call_ID,
174 GFP_KERNEL);
175 rxrpc_put_transport(trans);
176 if (IS_ERR(call)) {
177 ret = PTR_ERR(call);
178 goto out_trans;
179 }
180 164
181 _leave(" = %p\n", call); 165 _leave(" = %p\n", call);
182 return call; 166 return call;
183
184out_trans:
185 rxrpc_put_transport(trans);
186out:
187 _leave(" = %ld", ret);
188 return ERR_PTR(ret);
189} 167}
190 168
191/* 169/*
diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c
index 6baad708f3b1..01d4930a11f7 100644
--- a/net/rxrpc/peer_object.c
+++ b/net/rxrpc/peer_object.c
@@ -188,6 +188,8 @@ struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp)
188 INIT_HLIST_HEAD(&peer->error_targets); 188 INIT_HLIST_HEAD(&peer->error_targets);
189 INIT_WORK(&peer->error_distributor, 189 INIT_WORK(&peer->error_distributor,
190 &rxrpc_peer_error_distributor); 190 &rxrpc_peer_error_distributor);
191 peer->service_conns = RB_ROOT;
192 rwlock_init(&peer->conn_lock);
191 spin_lock_init(&peer->lock); 193 spin_lock_init(&peer->lock);
192 peer->debug_id = atomic_inc_return(&rxrpc_debug_id); 194 peer->debug_id = atomic_inc_return(&rxrpc_debug_id);
193 } 195 }
diff --git a/net/rxrpc/sysctl.c b/net/rxrpc/sysctl.c
index a99690a8a3da..03ad08774d4e 100644
--- a/net/rxrpc/sysctl.c
+++ b/net/rxrpc/sysctl.c
@@ -90,14 +90,6 @@ static struct ctl_table rxrpc_sysctl_table[] = {
90 .proc_handler = proc_dointvec_minmax, 90 .proc_handler = proc_dointvec_minmax,
91 .extra1 = (void *)&one, 91 .extra1 = (void *)&one,
92 }, 92 },
93 {
94 .procname = "transport_expiry",
95 .data = &rxrpc_transport_expiry,
96 .maxlen = sizeof(unsigned int),
97 .mode = 0644,
98 .proc_handler = proc_dointvec_minmax,
99 .extra1 = (void *)&one,
100 },
101 93
102 /* Non-time values */ 94 /* Non-time values */
103 { 95 {
diff --git a/net/rxrpc/transport.c b/net/rxrpc/transport.c
deleted file mode 100644
index 71947402d071..000000000000
--- a/net/rxrpc/transport.c
+++ /dev/null
@@ -1,265 +0,0 @@
1/* RxRPC point-to-point transport session management
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14#include <linux/module.h>
15#include <linux/net.h>
16#include <linux/skbuff.h>
17#include <linux/slab.h>
18#include <net/sock.h>
19#include <net/af_rxrpc.h>
20#include "ar-internal.h"
21
22/*
23 * Time after last use at which transport record is cleaned up.
24 */
25unsigned int rxrpc_transport_expiry = 3600 * 24;
26
27static void rxrpc_transport_reaper(struct work_struct *work);
28
29static LIST_HEAD(rxrpc_transports);
30static DEFINE_RWLOCK(rxrpc_transport_lock);
31static DECLARE_DELAYED_WORK(rxrpc_transport_reap, rxrpc_transport_reaper);
32
33/*
34 * allocate a new transport session manager
35 */
36static struct rxrpc_transport *rxrpc_alloc_transport(struct rxrpc_local *local,
37 struct rxrpc_peer *peer,
38 gfp_t gfp)
39{
40 struct rxrpc_transport *trans;
41
42 _enter("");
43
44 trans = kzalloc(sizeof(struct rxrpc_transport), gfp);
45 if (trans) {
46 trans->local = local;
47 trans->peer = peer;
48 INIT_LIST_HEAD(&trans->link);
49 trans->server_conns = RB_ROOT;
50 rwlock_init(&trans->conn_lock);
51 atomic_set(&trans->usage, 1);
52 trans->debug_id = atomic_inc_return(&rxrpc_debug_id);
53 }
54
55 _leave(" = %p", trans);
56 return trans;
57}
58
59/*
60 * obtain a transport session for the nominated endpoints
61 */
62struct rxrpc_transport *rxrpc_get_transport(struct rxrpc_local *local,
63 struct rxrpc_peer *peer,
64 gfp_t gfp)
65{
66 struct rxrpc_transport *trans, *candidate;
67 const char *new = "old";
68 int usage;
69
70 _enter("{%pI4+%hu},{%pI4+%hu},",
71 &local->srx.transport.sin.sin_addr,
72 ntohs(local->srx.transport.sin.sin_port),
73 &peer->srx.transport.sin.sin_addr,
74 ntohs(peer->srx.transport.sin.sin_port));
75
76 /* search the transport list first */
77 read_lock_bh(&rxrpc_transport_lock);
78 list_for_each_entry(trans, &rxrpc_transports, link) {
79 if (trans->local == local && trans->peer == peer)
80 goto found_extant_transport;
81 }
82 read_unlock_bh(&rxrpc_transport_lock);
83
84 /* not yet present - create a candidate for a new record and then
85 * redo the search */
86 candidate = rxrpc_alloc_transport(local, peer, gfp);
87 if (!candidate) {
88 _leave(" = -ENOMEM");
89 return ERR_PTR(-ENOMEM);
90 }
91
92 write_lock_bh(&rxrpc_transport_lock);
93
94 list_for_each_entry(trans, &rxrpc_transports, link) {
95 if (trans->local == local && trans->peer == peer)
96 goto found_extant_second;
97 }
98
99 /* we can now add the new candidate to the list */
100 trans = candidate;
101 candidate = NULL;
102 usage = atomic_read(&trans->usage);
103
104 rxrpc_get_local(trans->local);
105 rxrpc_get_peer(trans->peer);
106 list_add_tail(&trans->link, &rxrpc_transports);
107 write_unlock_bh(&rxrpc_transport_lock);
108 new = "new";
109
110success:
111 _net("TRANSPORT %s %d local %d -> peer %d",
112 new,
113 trans->debug_id,
114 trans->local->debug_id,
115 trans->peer->debug_id);
116
117 _leave(" = %p {u=%d}", trans, usage);
118 return trans;
119
120 /* we found the transport in the list immediately */
121found_extant_transport:
122 usage = atomic_inc_return(&trans->usage);
123 read_unlock_bh(&rxrpc_transport_lock);
124 goto success;
125
126 /* we found the transport on the second time through the list */
127found_extant_second:
128 usage = atomic_inc_return(&trans->usage);
129 write_unlock_bh(&rxrpc_transport_lock);
130 kfree(candidate);
131 goto success;
132}
133
134/*
135 * find the transport connecting two endpoints
136 */
137struct rxrpc_transport *rxrpc_find_transport(struct rxrpc_local *local,
138 struct rxrpc_peer *peer)
139{
140 struct rxrpc_transport *trans;
141
142 _enter("{%pI4+%hu},{%pI4+%hu},",
143 &local->srx.transport.sin.sin_addr,
144 ntohs(local->srx.transport.sin.sin_port),
145 &peer->srx.transport.sin.sin_addr,
146 ntohs(peer->srx.transport.sin.sin_port));
147
148 /* search the transport list */
149 read_lock_bh(&rxrpc_transport_lock);
150
151 list_for_each_entry(trans, &rxrpc_transports, link) {
152 if (trans->local == local && trans->peer == peer)
153 goto found_extant_transport;
154 }
155
156 read_unlock_bh(&rxrpc_transport_lock);
157 _leave(" = NULL");
158 return NULL;
159
160found_extant_transport:
161 atomic_inc(&trans->usage);
162 read_unlock_bh(&rxrpc_transport_lock);
163 _leave(" = %p", trans);
164 return trans;
165}
166
167/*
168 * release a transport session
169 */
170void rxrpc_put_transport(struct rxrpc_transport *trans)
171{
172 _enter("%p{u=%d}", trans, atomic_read(&trans->usage));
173
174 ASSERTCMP(atomic_read(&trans->usage), >, 0);
175
176 trans->put_time = ktime_get_seconds();
177 if (unlikely(atomic_dec_and_test(&trans->usage))) {
178 _debug("zombie");
179 /* let the reaper determine the timeout to avoid a race with
180 * overextending the timeout if the reaper is running at the
181 * same time */
182 rxrpc_queue_delayed_work(&rxrpc_transport_reap, 0);
183 }
184 _leave("");
185}
186
187/*
188 * clean up a transport session
189 */
190static void rxrpc_cleanup_transport(struct rxrpc_transport *trans)
191{
192 _net("DESTROY TRANS %d", trans->debug_id);
193
194 rxrpc_put_local(trans->local);
195 rxrpc_put_peer(trans->peer);
196 kfree(trans);
197}
198
199/*
200 * reap dead transports that have passed their expiry date
201 */
202static void rxrpc_transport_reaper(struct work_struct *work)
203{
204 struct rxrpc_transport *trans, *_p;
205 unsigned long now, earliest, reap_time;
206
207 LIST_HEAD(graveyard);
208
209 _enter("");
210
211 now = ktime_get_seconds();
212 earliest = ULONG_MAX;
213
214 /* extract all the transports that have been dead too long */
215 write_lock_bh(&rxrpc_transport_lock);
216 list_for_each_entry_safe(trans, _p, &rxrpc_transports, link) {
217 _debug("reap TRANS %d { u=%d t=%ld }",
218 trans->debug_id, atomic_read(&trans->usage),
219 (long) now - (long) trans->put_time);
220
221 if (likely(atomic_read(&trans->usage) > 0))
222 continue;
223
224 reap_time = trans->put_time + rxrpc_transport_expiry;
225 if (reap_time <= now)
226 list_move_tail(&trans->link, &graveyard);
227 else if (reap_time < earliest)
228 earliest = reap_time;
229 }
230 write_unlock_bh(&rxrpc_transport_lock);
231
232 if (earliest != ULONG_MAX) {
233 _debug("reschedule reaper %ld", (long) earliest - now);
234 ASSERTCMP(earliest, >, now);
235 rxrpc_queue_delayed_work(&rxrpc_transport_reap,
236 (earliest - now) * HZ);
237 }
238
239 /* then destroy all those pulled out */
240 while (!list_empty(&graveyard)) {
241 trans = list_entry(graveyard.next, struct rxrpc_transport,
242 link);
243 list_del_init(&trans->link);
244
245 ASSERTCMP(atomic_read(&trans->usage), ==, 0);
246 rxrpc_cleanup_transport(trans);
247 }
248
249 _leave("");
250}
251
252/*
253 * preemptively destroy all the transport session records rather than waiting
254 * for them to time out
255 */
256void __exit rxrpc_destroy_all_transports(void)
257{
258 _enter("");
259
260 rxrpc_transport_expiry = 0;
261 cancel_delayed_work(&rxrpc_transport_reap);
262 rxrpc_queue_delayed_work(&rxrpc_transport_reap, 0);
263
264 _leave("");
265}