Skip to content

Commit 999b69f

Browse files
committed
rxrpc: Kill the client connection bundle concept
Kill off the concept of maintaining a bundle of connections to a particular target service to increase the number of call slots available for any beyond four for that service (there are four call slots per connection). This will make cleaning up the connection handling code easier and facilitate removal of the rxrpc_transport struct. Bundling can be reintroduced later if necessary. Signed-off-by: David Howells <[email protected]>
1 parent 5627cc8 commit 999b69f

File tree

8 files changed

+288
-480
lines changed

8 files changed

+288
-480
lines changed

net/rxrpc/af_rxrpc.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,6 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
276276
gfp_t gfp)
277277
{
278278
struct rxrpc_conn_parameters cp;
279-
struct rxrpc_conn_bundle *bundle;
280279
struct rxrpc_transport *trans;
281280
struct rxrpc_call *call;
282281
struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
@@ -311,15 +310,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
311310
}
312311
cp.peer = trans->peer;
313312

314-
bundle = rxrpc_get_bundle(rx, trans, key, srx->srx_service, gfp);
315-
if (IS_ERR(bundle)) {
316-
call = ERR_CAST(bundle);
317-
goto out;
318-
}
319-
320-
call = rxrpc_new_client_call(rx, &cp, trans, bundle, user_call_ID, gfp);
321-
rxrpc_put_bundle(trans, bundle);
322-
out:
313+
call = rxrpc_new_client_call(rx, &cp, trans, srx, user_call_ID, gfp);
323314
rxrpc_put_transport(trans);
324315
out_notrans:
325316
release_sock(&rx->sk);

net/rxrpc/ar-internal.h

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ struct rxrpc_local {
186186
struct sk_buff_head accept_queue; /* incoming calls awaiting acceptance */
187187
struct sk_buff_head reject_queue; /* packets awaiting rejection */
188188
struct sk_buff_head event_queue; /* endpoint event packets awaiting processing */
189-
struct mutex conn_lock; /* Client connection creation lock */
189+
struct rb_root client_conns; /* Client connections by socket params */
190+
spinlock_t client_conns_lock; /* Lock for client_conns */
190191
spinlock_t lock; /* access lock */
191192
rwlock_t services_lock; /* lock for services list */
192193
int debug_id; /* debug ID for printks */
@@ -232,34 +233,14 @@ struct rxrpc_peer {
232233
struct rxrpc_transport {
233234
struct rxrpc_local *local; /* local transport endpoint */
234235
struct rxrpc_peer *peer; /* remote transport endpoint */
235-
struct rb_root bundles; /* client connection bundles on this transport */
236236
struct rb_root server_conns; /* server connections on this transport */
237237
struct list_head link; /* link in master session list */
238238
unsigned long put_time; /* time at which to reap */
239-
spinlock_t client_lock; /* client connection allocation lock */
240239
rwlock_t conn_lock; /* lock for active/dead connections */
241240
atomic_t usage;
242241
int debug_id; /* debug ID for printks */
243242
};
244243

245-
/*
246-
* RxRPC client connection bundle
247-
* - matched by { transport, service_id, key }
248-
*/
249-
struct rxrpc_conn_bundle {
250-
struct rb_node node; /* node in transport's lookup tree */
251-
struct list_head unused_conns; /* unused connections in this bundle */
252-
struct list_head avail_conns; /* available connections in this bundle */
253-
struct list_head busy_conns; /* busy connections in this bundle */
254-
struct key *key; /* security for this bundle */
255-
wait_queue_head_t chanwait; /* wait for channel to become available */
256-
atomic_t usage;
257-
int debug_id; /* debug ID for printks */
258-
unsigned short num_conns; /* number of connections in this bundle */
259-
u16 service_id; /* Service ID for this bundle */
260-
u8 security_ix; /* security type */
261-
};
262-
263244
/*
264245
* Keys for matching a connection.
265246
*/
@@ -295,17 +276,21 @@ struct rxrpc_conn_parameters {
295276
*/
296277
struct rxrpc_connection {
297278
struct rxrpc_transport *trans; /* transport session */
298-
struct rxrpc_conn_bundle *bundle; /* connection bundle (client) */
299279
struct rxrpc_conn_proto proto;
300280
struct rxrpc_conn_parameters params;
301281

282+
spinlock_t channel_lock;
283+
struct rxrpc_call *channels[RXRPC_MAXCALLS]; /* active calls */
284+
wait_queue_head_t channel_wq; /* queue to wait for channel to become available */
285+
302286
struct work_struct processor; /* connection event processor */
303-
struct rb_node node; /* node in transport's lookup tree */
287+
union {
288+
struct rb_node client_node; /* Node in local->client_conns */
289+
struct rb_node service_node; /* Node in trans->server_conns */
290+
};
304291
struct list_head link; /* link in master connection list */
305-
struct list_head bundle_link; /* link in bundle */
306292
struct rb_root calls; /* calls on this connection */
307293
struct sk_buff_head rx_queue; /* received conn-level packets */
308-
struct rxrpc_call *channels[RXRPC_MAXCALLS]; /* channels (active calls) */
309294
const struct rxrpc_security *security; /* applied security module */
310295
struct key *server_key; /* security for this service */
311296
struct crypto_skcipher *cipher; /* encryption handle */
@@ -314,7 +299,7 @@ struct rxrpc_connection {
314299
#define RXRPC_CONN_HAS_IDR 0 /* - Has a client conn ID assigned */
315300
unsigned long events;
316301
#define RXRPC_CONN_CHALLENGE 0 /* send challenge packet */
317-
unsigned long put_time; /* time at which to reap */
302+
unsigned long put_time; /* Time at which last put */
318303
rwlock_t lock; /* access lock */
319304
spinlock_t state_lock; /* state-change lock */
320305
atomic_t usage;
@@ -335,7 +320,7 @@ struct rxrpc_connection {
335320
unsigned int call_counter; /* call ID counter */
336321
atomic_t serial; /* packet serial number counter */
337322
atomic_t hi_serial; /* highest serial number received */
338-
u8 avail_calls; /* number of calls available */
323+
atomic_t avail_chans; /* number of channels available */
339324
u8 size_align; /* data size alignment (for security) */
340325
u8 header_size; /* rxrpc + security header size */
341326
u8 security_size; /* security header size */
@@ -386,6 +371,8 @@ enum rxrpc_call_event {
386371
* The states that a call can be in.
387372
*/
388373
enum rxrpc_call_state {
374+
RXRPC_CALL_UNINITIALISED,
375+
RXRPC_CALL_CLIENT_AWAIT_CONN, /* - client waiting for connection to become available */
389376
RXRPC_CALL_CLIENT_SEND_REQUEST, /* - client sending request phase */
390377
RXRPC_CALL_CLIENT_AWAIT_REPLY, /* - client awaiting reply */
391378
RXRPC_CALL_CLIENT_RECV_REPLY, /* - client receiving reply phase */
@@ -540,7 +527,7 @@ struct rxrpc_call *rxrpc_find_call_by_user_ID(struct rxrpc_sock *, unsigned long
540527
struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *,
541528
struct rxrpc_conn_parameters *,
542529
struct rxrpc_transport *,
543-
struct rxrpc_conn_bundle *,
530+
struct sockaddr_rxrpc *,
544531
unsigned long, gfp_t);
545532
struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *,
546533
struct rxrpc_connection *,
@@ -555,8 +542,7 @@ void __exit rxrpc_destroy_all_calls(void);
555542
*/
556543
extern struct idr rxrpc_client_conn_ids;
557544

558-
int rxrpc_get_client_connection_id(struct rxrpc_connection *,
559-
struct rxrpc_transport *, gfp_t);
545+
int rxrpc_get_client_connection_id(struct rxrpc_connection *, gfp_t);
560546
void rxrpc_put_client_connection_id(struct rxrpc_connection *);
561547

562548
/*
@@ -573,13 +559,10 @@ extern unsigned int rxrpc_connection_expiry;
573559
extern struct list_head rxrpc_connections;
574560
extern rwlock_t rxrpc_connection_lock;
575561

576-
struct rxrpc_conn_bundle *rxrpc_get_bundle(struct rxrpc_sock *,
577-
struct rxrpc_transport *,
578-
struct key *, u16, gfp_t);
579-
void rxrpc_put_bundle(struct rxrpc_transport *, struct rxrpc_conn_bundle *);
580-
int rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_conn_parameters *,
581-
struct rxrpc_transport *, struct rxrpc_conn_bundle *,
582-
struct rxrpc_call *, gfp_t);
562+
int rxrpc_connect_call(struct rxrpc_call *, struct rxrpc_conn_parameters *,
563+
struct rxrpc_transport *,
564+
struct sockaddr_rxrpc *, gfp_t);
565+
void rxrpc_disconnect_call(struct rxrpc_call *);
583566
void rxrpc_put_connection(struct rxrpc_connection *);
584567
void __exit rxrpc_destroy_all_connections(void);
585568
struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *,

net/rxrpc/call_object.c

Lines changed: 65 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ unsigned int rxrpc_max_call_lifetime = 60 * HZ;
3131
unsigned int rxrpc_dead_call_expiry = 2 * HZ;
3232

3333
const char *const rxrpc_call_states[NR__RXRPC_CALL_STATES] = {
34+
[RXRPC_CALL_UNINITIALISED] = "Uninit",
35+
[RXRPC_CALL_CLIENT_AWAIT_CONN] = "ClWtConn",
3436
[RXRPC_CALL_CLIENT_SEND_REQUEST] = "ClSndReq",
3537
[RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl",
3638
[RXRPC_CALL_CLIENT_RECV_REPLY] = "ClRcvRpl",
@@ -261,6 +263,7 @@ static struct rxrpc_call *rxrpc_alloc_call(gfp_t gfp)
261263
(unsigned long) call);
262264
INIT_WORK(&call->destroyer, &rxrpc_destroy_call);
263265
INIT_WORK(&call->processor, &rxrpc_process_call);
266+
INIT_LIST_HEAD(&call->link);
264267
INIT_LIST_HEAD(&call->accept_link);
265268
skb_queue_head_init(&call->rx_queue);
266269
skb_queue_head_init(&call->rx_oos_queue);
@@ -269,7 +272,6 @@ static struct rxrpc_call *rxrpc_alloc_call(gfp_t gfp)
269272
rwlock_init(&call->state_lock);
270273
atomic_set(&call->usage, 1);
271274
call->debug_id = atomic_inc_return(&rxrpc_debug_id);
272-
call->state = RXRPC_CALL_CLIENT_SEND_REQUEST;
273275

274276
memset(&call->sock_node, 0xed, sizeof(call->sock_node));
275277

@@ -282,55 +284,70 @@ static struct rxrpc_call *rxrpc_alloc_call(gfp_t gfp)
282284
}
283285

284286
/*
285-
* allocate a new client call and attempt to get a connection slot for it
287+
* Allocate a new client call.
286288
*/
287289
static struct rxrpc_call *rxrpc_alloc_client_call(
288290
struct rxrpc_sock *rx,
289291
struct rxrpc_conn_parameters *cp,
290-
struct rxrpc_transport *trans,
291-
struct rxrpc_conn_bundle *bundle,
292+
struct sockaddr_rxrpc *srx,
292293
gfp_t gfp)
293294
{
294295
struct rxrpc_call *call;
295-
int ret;
296296

297297
_enter("");
298298

299-
ASSERT(rx != NULL);
300-
ASSERT(trans != NULL);
301-
ASSERT(bundle != NULL);
299+
ASSERT(rx->local != NULL);
302300

303301
call = rxrpc_alloc_call(gfp);
304302
if (!call)
305303
return ERR_PTR(-ENOMEM);
304+
call->state = RXRPC_CALL_CLIENT_AWAIT_CONN;
306305

307306
sock_hold(&rx->sk);
308307
call->socket = rx;
309308
call->rx_data_post = 1;
310309

311-
ret = rxrpc_connect_call(rx, cp, trans, bundle, call, gfp);
312-
if (ret < 0) {
313-
kmem_cache_free(rxrpc_call_jar, call);
314-
return ERR_PTR(ret);
315-
}
316-
317310
/* Record copies of information for hashtable lookup */
318311
call->family = rx->family;
319-
call->local = call->conn->params.local;
312+
call->local = rx->local;
320313
switch (call->family) {
321314
case AF_INET:
322-
call->peer_ip.ipv4_addr =
323-
call->conn->params.peer->srx.transport.sin.sin_addr.s_addr;
315+
call->peer_ip.ipv4_addr = srx->transport.sin.sin_addr.s_addr;
324316
break;
325317
case AF_INET6:
326318
memcpy(call->peer_ip.ipv6_addr,
327-
call->conn->params.peer->srx.transport.sin6.sin6_addr.in6_u.u6_addr8,
319+
srx->transport.sin6.sin6_addr.in6_u.u6_addr8,
328320
sizeof(call->peer_ip.ipv6_addr));
329321
break;
330322
}
331-
call->epoch = call->conn->proto.epoch;
332-
call->service_id = call->conn->params.service_id;
333-
call->in_clientflag = call->conn->proto.in_clientflag;
323+
324+
call->service_id = srx->srx_service;
325+
call->in_clientflag = 0;
326+
327+
_leave(" = %p", call);
328+
return call;
329+
}
330+
331+
/*
332+
* Begin client call.
333+
*/
334+
static int rxrpc_begin_client_call(struct rxrpc_call *call,
335+
struct rxrpc_conn_parameters *cp,
336+
struct rxrpc_transport *trans,
337+
struct sockaddr_rxrpc *srx,
338+
gfp_t gfp)
339+
{
340+
int ret;
341+
342+
/* Set up or get a connection record and set the protocol parameters,
343+
* including channel number and call ID.
344+
*/
345+
ret = rxrpc_connect_call(call, cp, trans, srx, gfp);
346+
if (ret < 0)
347+
return ret;
348+
349+
call->state = RXRPC_CALL_CLIENT_SEND_REQUEST;
350+
334351
/* Add the new call to the hashtable */
335352
rxrpc_call_hash_add(call);
336353

@@ -340,9 +357,7 @@ static struct rxrpc_call *rxrpc_alloc_client_call(
340357

341358
call->lifetimer.expires = jiffies + rxrpc_max_call_lifetime;
342359
add_timer(&call->lifetimer);
343-
344-
_leave(" = %p", call);
345-
return call;
360+
return 0;
346361
}
347362

348363
/*
@@ -352,23 +367,23 @@ static struct rxrpc_call *rxrpc_alloc_client_call(
352367
struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
353368
struct rxrpc_conn_parameters *cp,
354369
struct rxrpc_transport *trans,
355-
struct rxrpc_conn_bundle *bundle,
370+
struct sockaddr_rxrpc *srx,
356371
unsigned long user_call_ID,
357372
gfp_t gfp)
358373
{
359374
struct rxrpc_call *call, *xcall;
360375
struct rb_node *parent, **pp;
376+
int ret;
361377

362-
_enter("%p,%d,%d,%lx",
363-
rx, trans->debug_id, bundle ? bundle->debug_id : -1,
364-
user_call_ID);
378+
_enter("%p,%lx", rx, user_call_ID);
365379

366-
call = rxrpc_alloc_client_call(rx, cp, trans, bundle, gfp);
380+
call = rxrpc_alloc_client_call(rx, cp, srx, gfp);
367381
if (IS_ERR(call)) {
368382
_leave(" = %ld", PTR_ERR(call));
369383
return call;
370384
}
371385

386+
/* Publish the call, even though it is incompletely set up as yet */
372387
call->user_call_ID = user_call_ID;
373388
__set_bit(RXRPC_CALL_HAS_USERID, &call->flags);
374389

@@ -398,11 +413,29 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
398413
list_add_tail(&call->link, &rxrpc_calls);
399414
write_unlock_bh(&rxrpc_call_lock);
400415

416+
ret = rxrpc_begin_client_call(call, cp, trans, srx, gfp);
417+
if (ret < 0)
418+
goto error;
419+
401420
_net("CALL new %d on CONN %d", call->debug_id, call->conn->debug_id);
402421

403422
_leave(" = %p [new]", call);
404423
return call;
405424

425+
error:
426+
write_lock(&rx->call_lock);
427+
rb_erase(&call->sock_node, &rx->calls);
428+
write_unlock(&rx->call_lock);
429+
rxrpc_put_call(call);
430+
431+
write_lock_bh(&rxrpc_call_lock);
432+
list_del(&call->link);
433+
write_unlock_bh(&rxrpc_call_lock);
434+
435+
rxrpc_put_call(call);
436+
_leave(" = %d", ret);
437+
return ERR_PTR(ret);
438+
406439
/* We unexpectedly found the user ID in the list after taking
407440
* the call_lock. This shouldn't happen unless the user races
408441
* with itself and tries to add the same user ID twice at the
@@ -612,40 +645,13 @@ void rxrpc_release_call(struct rxrpc_call *call)
612645
write_unlock_bh(&rx->call_lock);
613646

614647
/* free up the channel for reuse */
615-
spin_lock(&conn->trans->client_lock);
648+
spin_lock(&conn->channel_lock);
616649
write_lock_bh(&conn->lock);
617650
write_lock(&call->state_lock);
618651

619-
if (conn->channels[call->channel] == call)
620-
conn->channels[call->channel] = NULL;
621-
622-
if (conn->out_clientflag && conn->bundle) {
623-
conn->avail_calls++;
624-
switch (conn->avail_calls) {
625-
case 1:
626-
list_move_tail(&conn->bundle_link,
627-
&conn->bundle->avail_conns);
628-
case 2 ... RXRPC_MAXCALLS - 1:
629-
ASSERT(conn->channels[0] == NULL ||
630-
conn->channels[1] == NULL ||
631-
conn->channels[2] == NULL ||
632-
conn->channels[3] == NULL);
633-
break;
634-
case RXRPC_MAXCALLS:
635-
list_move_tail(&conn->bundle_link,
636-
&conn->bundle->unused_conns);
637-
ASSERT(conn->channels[0] == NULL &&
638-
conn->channels[1] == NULL &&
639-
conn->channels[2] == NULL &&
640-
conn->channels[3] == NULL);
641-
break;
642-
default:
643-
pr_err("conn->avail_calls=%d\n", conn->avail_calls);
644-
BUG();
645-
}
646-
}
652+
rxrpc_disconnect_call(call);
647653

648-
spin_unlock(&conn->trans->client_lock);
654+
spin_unlock(&conn->channel_lock);
649655

650656
if (call->state < RXRPC_CALL_COMPLETE &&
651657
call->state != RXRPC_CALL_CLIENT_FINAL_ACK) {

0 commit comments

Comments
 (0)