Skip to content

Commit 1bab27a

Browse files
committed
rxrpc: Set up a connection bundle from a call, not rxrpc_conn_parameters
Use the information now stored in struct rxrpc_call to configure the connection bundle and thence the connection, rather than using the rxrpc_conn_parameters struct. Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected]
1 parent 2953d3b commit 1bab27a

File tree

7 files changed

+76
-75
lines changed

7 files changed

+76
-75
lines changed

include/trace/events/rxrpc.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@
178178
#define rxrpc_peer_traces \
179179
EM(rxrpc_peer_free, "FREE ") \
180180
EM(rxrpc_peer_get_accept, "GET accept ") \
181-
EM(rxrpc_peer_get_activate_call, "GET act-call") \
182181
EM(rxrpc_peer_get_bundle, "GET bundle ") \
183182
EM(rxrpc_peer_get_client_conn, "GET cln-conn") \
184183
EM(rxrpc_peer_get_input, "GET input ") \
@@ -191,7 +190,6 @@
191190
EM(rxrpc_peer_put_bundle, "PUT bundle ") \
192191
EM(rxrpc_peer_put_call, "PUT call ") \
193192
EM(rxrpc_peer_put_conn, "PUT conn ") \
194-
EM(rxrpc_peer_put_discard_tmp, "PUT disc-tmp") \
195193
EM(rxrpc_peer_put_input, "PUT input ") \
196194
EM(rxrpc_peer_put_input_error, "PUT inpt-err") \
197195
E_(rxrpc_peer_put_keepalive, "PUT keepaliv")
@@ -201,6 +199,7 @@
201199
EM(rxrpc_bundle_get_client_call, "GET clt-call") \
202200
EM(rxrpc_bundle_get_client_conn, "GET clt-conn") \
203201
EM(rxrpc_bundle_get_service_conn, "GET svc-conn") \
202+
EM(rxrpc_bundle_put_call, "PUT call ") \
204203
EM(rxrpc_bundle_put_conn, "PUT conn ") \
205204
EM(rxrpc_bundle_put_discard, "PUT discard ") \
206205
E_(rxrpc_bundle_new, "NEW ")

net/rxrpc/af_rxrpc.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,6 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
328328
mutex_unlock(&call->user_mutex);
329329
}
330330

331-
rxrpc_put_peer(cp.peer, rxrpc_peer_put_discard_tmp);
332331
_leave(" = %p", call);
333332
return call;
334333
}

net/rxrpc/ar-internal.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,6 @@ struct rxrpc_conn_proto {
360360

361361
struct rxrpc_conn_parameters {
362362
struct rxrpc_local *local; /* Representation of local endpoint */
363-
struct rxrpc_peer *peer; /* Remote endpoint */
364363
struct key *key; /* Security details */
365364
bool exclusive; /* T if conn is exclusive */
366365
bool upgrade; /* T if service ID can be upgraded */
@@ -428,6 +427,7 @@ struct rxrpc_bundle {
428427
struct rxrpc_local *local; /* Representation of local endpoint */
429428
struct rxrpc_peer *peer; /* Remote endpoint */
430429
struct key *key; /* Security details */
430+
const struct rxrpc_security *security; /* applied security module */
431431
refcount_t ref;
432432
atomic_t active; /* Number of active users */
433433
unsigned int debug_id;
@@ -593,6 +593,7 @@ enum rxrpc_congest_mode {
593593
struct rxrpc_call {
594594
struct rcu_head rcu;
595595
struct rxrpc_connection *conn; /* connection carrying call */
596+
struct rxrpc_bundle *bundle; /* Connection bundle to use */
596597
struct rxrpc_peer *peer; /* Peer record for remote address */
597598
struct rxrpc_local *local; /* Representation of local endpoint */
598599
struct rxrpc_sock __rcu *socket; /* socket responsible */
@@ -894,11 +895,10 @@ extern unsigned long rxrpc_conn_idle_client_fast_expiry;
894895
void rxrpc_destroy_client_conn_ids(struct rxrpc_local *local);
895896
struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace);
896897
void rxrpc_put_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace);
897-
int rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_call *,
898-
struct rxrpc_conn_parameters *, struct sockaddr_rxrpc *,
899-
gfp_t);
898+
int rxrpc_connect_call(struct rxrpc_call *call, gfp_t gfp);
900899
void rxrpc_expose_client_call(struct rxrpc_call *);
901900
void rxrpc_disconnect_client_call(struct rxrpc_bundle *, struct rxrpc_call *);
901+
void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle);
902902
void rxrpc_put_client_conn(struct rxrpc_connection *, enum rxrpc_conn_trace);
903903
void rxrpc_discard_expired_client_conns(struct work_struct *);
904904
void rxrpc_destroy_all_client_connections(struct rxrpc_net *);

net/rxrpc/call_object.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
365365
/* Set up or get a connection record and set the protocol parameters,
366366
* including channel number and call ID.
367367
*/
368-
ret = rxrpc_connect_call(rx, call, cp, srx, gfp);
368+
ret = rxrpc_connect_call(call, gfp);
369369
if (ret < 0)
370370
goto error_attached_to_socket;
371371

@@ -663,6 +663,8 @@ static void rxrpc_destroy_call(struct work_struct *work)
663663

664664
rxrpc_put_txbuf(call->tx_pending, rxrpc_txbuf_put_cleaned);
665665
rxrpc_put_connection(call->conn, rxrpc_conn_put_call);
666+
rxrpc_deactivate_bundle(call->bundle);
667+
rxrpc_put_bundle(call->bundle, rxrpc_bundle_put_call);
666668
rxrpc_put_peer(call->peer, rxrpc_peer_put_call);
667669
rxrpc_put_local(call->local, rxrpc_local_put_call);
668670
call_rcu(&call->rcu, rxrpc_rcu_free_call);

net/rxrpc/conn_client.c

Lines changed: 67 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ __read_mostly unsigned int rxrpc_reap_client_connections = 900;
3434
__read_mostly unsigned long rxrpc_conn_idle_client_expiry = 2 * 60 * HZ;
3535
__read_mostly unsigned long rxrpc_conn_idle_client_fast_expiry = 2 * HZ;
3636

37-
static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle);
37+
static void rxrpc_activate_bundle(struct rxrpc_bundle *bundle)
38+
{
39+
atomic_inc(&bundle->active);
40+
}
3841

3942
/*
4043
* Get a connection ID and epoch for a client connection from the global pool.
@@ -109,20 +112,21 @@ void rxrpc_destroy_client_conn_ids(struct rxrpc_local *local)
109112
/*
110113
* Allocate a connection bundle.
111114
*/
112-
static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_conn_parameters *cp,
115+
static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_call *call,
113116
gfp_t gfp)
114117
{
115118
struct rxrpc_bundle *bundle;
116119

117120
bundle = kzalloc(sizeof(*bundle), gfp);
118121
if (bundle) {
119-
bundle->local = cp->local;
120-
bundle->peer = rxrpc_get_peer(cp->peer, rxrpc_peer_get_bundle);
121-
bundle->key = cp->key;
122-
bundle->exclusive = cp->exclusive;
123-
bundle->upgrade = cp->upgrade;
124-
bundle->service_id = cp->service_id;
125-
bundle->security_level = cp->security_level;
122+
bundle->local = call->local;
123+
bundle->peer = rxrpc_get_peer(call->peer, rxrpc_peer_get_bundle);
124+
bundle->key = key_get(call->key);
125+
bundle->security = call->security;
126+
bundle->exclusive = test_bit(RXRPC_CALL_EXCLUSIVE, &call->flags);
127+
bundle->upgrade = test_bit(RXRPC_CALL_UPGRADE, &call->flags);
128+
bundle->service_id = call->dest_srx.srx_service;
129+
bundle->security_level = call->security_level;
126130
refcount_set(&bundle->ref, 1);
127131
atomic_set(&bundle->active, 1);
128132
spin_lock_init(&bundle->channel_lock);
@@ -146,19 +150,23 @@ static void rxrpc_free_bundle(struct rxrpc_bundle *bundle)
146150
{
147151
trace_rxrpc_bundle(bundle->debug_id, 1, rxrpc_bundle_free);
148152
rxrpc_put_peer(bundle->peer, rxrpc_peer_put_bundle);
153+
key_put(bundle->key);
149154
kfree(bundle);
150155
}
151156

152157
void rxrpc_put_bundle(struct rxrpc_bundle *bundle, enum rxrpc_bundle_trace why)
153158
{
154-
unsigned int id = bundle->debug_id;
159+
unsigned int id;
155160
bool dead;
156161
int r;
157162

158-
dead = __refcount_dec_and_test(&bundle->ref, &r);
159-
trace_rxrpc_bundle(id, r - 1, why);
160-
if (dead)
161-
rxrpc_free_bundle(bundle);
163+
if (bundle) {
164+
id = bundle->debug_id;
165+
dead = __refcount_dec_and_test(&bundle->ref, &r);
166+
trace_rxrpc_bundle(id, r - 1, why);
167+
if (dead)
168+
rxrpc_free_bundle(bundle);
169+
}
162170
}
163171

164172
/*
@@ -272,20 +280,23 @@ static bool rxrpc_may_reuse_conn(struct rxrpc_connection *conn)
272280
* Look up the conn bundle that matches the connection parameters, adding it if
273281
* it doesn't yet exist.
274282
*/
275-
static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *cp,
276-
gfp_t gfp)
283+
static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_call *call, gfp_t gfp)
277284
{
278285
static atomic_t rxrpc_bundle_id;
279286
struct rxrpc_bundle *bundle, *candidate;
280-
struct rxrpc_local *local = cp->local;
287+
struct rxrpc_local *local = call->local;
281288
struct rb_node *p, **pp, *parent;
282289
long diff;
290+
bool upgrade = test_bit(RXRPC_CALL_UPGRADE, &call->flags);
283291

284292
_enter("{%px,%x,%u,%u}",
285-
cp->peer, key_serial(cp->key), cp->security_level, cp->upgrade);
293+
call->peer, key_serial(call->key), call->security_level,
294+
upgrade);
286295

287-
if (cp->exclusive)
288-
return rxrpc_alloc_bundle(cp, gfp);
296+
if (test_bit(RXRPC_CALL_EXCLUSIVE, &call->flags)) {
297+
call->bundle = rxrpc_alloc_bundle(call, gfp);
298+
return call->bundle;
299+
}
289300

290301
/* First, see if the bundle is already there. */
291302
_debug("search 1");
@@ -294,11 +305,11 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
294305
while (p) {
295306
bundle = rb_entry(p, struct rxrpc_bundle, local_node);
296307

297-
#define cmp(X) ((long)bundle->X - (long)cp->X)
298-
diff = (cmp(peer) ?:
299-
cmp(key) ?:
300-
cmp(security_level) ?:
301-
cmp(upgrade));
308+
#define cmp(X, Y) ((long)(X) - (long)(Y))
309+
diff = (cmp(bundle->peer, call->peer) ?:
310+
cmp(bundle->key, call->key) ?:
311+
cmp(bundle->security_level, call->security_level) ?:
312+
cmp(bundle->upgrade, upgrade));
302313
#undef cmp
303314
if (diff < 0)
304315
p = p->rb_left;
@@ -311,9 +322,9 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
311322
_debug("not found");
312323

313324
/* It wasn't. We need to add one. */
314-
candidate = rxrpc_alloc_bundle(cp, gfp);
325+
candidate = rxrpc_alloc_bundle(call, gfp);
315326
if (!candidate)
316-
return NULL;
327+
return ERR_PTR(-ENOMEM);
317328

318329
_debug("search 2");
319330
spin_lock(&local->client_bundles_lock);
@@ -323,11 +334,11 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
323334
parent = *pp;
324335
bundle = rb_entry(parent, struct rxrpc_bundle, local_node);
325336

326-
#define cmp(X) ((long)bundle->X - (long)cp->X)
327-
diff = (cmp(peer) ?:
328-
cmp(key) ?:
329-
cmp(security_level) ?:
330-
cmp(upgrade));
337+
#define cmp(X, Y) ((long)(X) - (long)(Y))
338+
diff = (cmp(bundle->peer, call->peer) ?:
339+
cmp(bundle->key, call->key) ?:
340+
cmp(bundle->security_level, call->security_level) ?:
341+
cmp(bundle->upgrade, upgrade));
331342
#undef cmp
332343
if (diff < 0)
333344
pp = &(*pp)->rb_left;
@@ -341,19 +352,19 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
341352
candidate->debug_id = atomic_inc_return(&rxrpc_bundle_id);
342353
rb_link_node(&candidate->local_node, parent, pp);
343354
rb_insert_color(&candidate->local_node, &local->client_bundles);
344-
rxrpc_get_bundle(candidate, rxrpc_bundle_get_client_call);
355+
call->bundle = rxrpc_get_bundle(candidate, rxrpc_bundle_get_client_call);
345356
spin_unlock(&local->client_bundles_lock);
346-
_leave(" = %u [new]", candidate->debug_id);
347-
return candidate;
357+
_leave(" = B=%u [new]", call->bundle->debug_id);
358+
return call->bundle;
348359

349360
found_bundle_free:
350361
rxrpc_free_bundle(candidate);
351362
found_bundle:
352-
rxrpc_get_bundle(bundle, rxrpc_bundle_get_client_call);
353-
atomic_inc(&bundle->active);
363+
call->bundle = rxrpc_get_bundle(bundle, rxrpc_bundle_get_client_call);
364+
rxrpc_activate_bundle(bundle);
354365
spin_unlock(&local->client_bundles_lock);
355-
_leave(" = %u [found]", bundle->debug_id);
356-
return bundle;
366+
_leave(" = B=%u [found]", call->bundle->debug_id);
367+
return call->bundle;
357368
}
358369

359370
/*
@@ -362,31 +373,25 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
362373
* If we return with a connection, the call will be on its waiting list. It's
363374
* left to the caller to assign a channel and wake up the call.
364375
*/
365-
static struct rxrpc_bundle *rxrpc_prep_call(struct rxrpc_sock *rx,
366-
struct rxrpc_call *call,
367-
struct rxrpc_conn_parameters *cp,
368-
struct sockaddr_rxrpc *srx,
369-
gfp_t gfp)
376+
static struct rxrpc_bundle *rxrpc_prep_call(struct rxrpc_call *call, gfp_t gfp)
370377
{
371378
struct rxrpc_bundle *bundle;
372379

373380
_enter("{%d,%lx},", call->debug_id, call->user_call_ID);
374381

375-
cp->peer = rxrpc_lookup_peer(cp->local, srx, gfp);
376-
if (!cp->peer)
382+
call->peer = rxrpc_lookup_peer(call->local, &call->dest_srx, gfp);
383+
if (!call->peer)
377384
goto error;
378385

379386
call->tx_last_sent = ktime_get_real();
380-
call->cong_ssthresh = cp->peer->cong_ssthresh;
387+
call->cong_ssthresh = call->peer->cong_ssthresh;
381388
if (call->cong_cwnd >= call->cong_ssthresh)
382389
call->cong_mode = RXRPC_CALL_CONGEST_AVOIDANCE;
383390
else
384391
call->cong_mode = RXRPC_CALL_SLOW_START;
385-
if (cp->upgrade)
386-
__set_bit(RXRPC_CALL_UPGRADE, &call->flags);
387392

388393
/* Find the client connection bundle. */
389-
bundle = rxrpc_look_up_bundle(cp, gfp);
394+
bundle = rxrpc_look_up_bundle(call, gfp);
390395
if (!bundle)
391396
goto error;
392397

@@ -449,7 +454,7 @@ static void rxrpc_add_conn_to_bundle(struct rxrpc_bundle *bundle, gfp_t gfp)
449454
if (old)
450455
trace_rxrpc_client(old, -1, rxrpc_client_replace);
451456
candidate->bundle_shift = shift;
452-
atomic_inc(&bundle->active);
457+
rxrpc_activate_bundle(bundle);
453458
bundle->conns[i] = candidate;
454459
for (j = 0; j < RXRPC_MAXCALLS; j++)
455460
set_bit(shift + j, &bundle->avail_chans);
@@ -541,7 +546,6 @@ static void rxrpc_activate_one_channel(struct rxrpc_connection *conn,
541546

542547
rxrpc_see_call(call, rxrpc_call_see_activate_client);
543548
list_del_init(&call->chan_wait_link);
544-
call->peer = rxrpc_get_peer(conn->peer, rxrpc_peer_get_activate_call);
545549
call->conn = rxrpc_get_connection(conn, rxrpc_conn_get_activate_call);
546550
call->cid = conn->proto.cid | channel;
547551
call->call_id = call_id;
@@ -705,14 +709,11 @@ static int rxrpc_wait_for_channel(struct rxrpc_bundle *bundle,
705709
* find a connection for a call
706710
* - called in process context with IRQs enabled
707711
*/
708-
int rxrpc_connect_call(struct rxrpc_sock *rx,
709-
struct rxrpc_call *call,
710-
struct rxrpc_conn_parameters *cp,
711-
struct sockaddr_rxrpc *srx,
712-
gfp_t gfp)
712+
int rxrpc_connect_call(struct rxrpc_call *call, gfp_t gfp)
713713
{
714714
struct rxrpc_bundle *bundle;
715-
struct rxrpc_net *rxnet = cp->local->rxnet;
715+
struct rxrpc_local *local = call->local;
716+
struct rxrpc_net *rxnet = local->rxnet;
716717
int ret = 0;
717718

718719
_enter("{%d,%lx},", call->debug_id, call->user_call_ID);
@@ -721,7 +722,7 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
721722

722723
rxrpc_get_call(call, rxrpc_call_get_io_thread);
723724

724-
bundle = rxrpc_prep_call(rx, call, cp, srx, gfp);
725+
bundle = rxrpc_prep_call(call, gfp);
725726
if (IS_ERR(bundle)) {
726727
rxrpc_put_call(call, rxrpc_call_get_io_thread);
727728
ret = PTR_ERR(bundle);
@@ -738,9 +739,6 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
738739
/* Paired with the write barrier in rxrpc_activate_one_channel(). */
739740
smp_rmb();
740741

741-
out_put_bundle:
742-
rxrpc_deactivate_bundle(bundle);
743-
rxrpc_put_bundle(bundle, rxrpc_bundle_get_client_call);
744742
out:
745743
_leave(" = %d", ret);
746744
return ret;
@@ -758,7 +756,7 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
758756
trace_rxrpc_client(call->conn, ret, rxrpc_client_chan_wait_failed);
759757
rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, 0, ret);
760758
rxrpc_disconnect_client_call(bundle, call);
761-
goto out_put_bundle;
759+
goto out;
762760
}
763761

764762
/*
@@ -945,11 +943,15 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
945943
/*
946944
* Drop the active count on a bundle.
947945
*/
948-
static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle)
946+
void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle)
949947
{
950-
struct rxrpc_local *local = bundle->local;
948+
struct rxrpc_local *local;
951949
bool need_put = false;
952950

951+
if (!bundle)
952+
return;
953+
954+
local = bundle->local;
953955
if (atomic_dec_and_lock(&bundle->active, &local->client_bundles_lock)) {
954956
if (!bundle->exclusive) {
955957
_debug("erase bundle");

net/rxrpc/conn_object.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ void rxrpc_disconnect_call(struct rxrpc_call *call)
208208
}
209209

210210
if (rxrpc_is_client_call(call)) {
211-
rxrpc_disconnect_client_call(conn->bundle, call);
211+
rxrpc_disconnect_client_call(call->bundle, call);
212212
} else {
213213
spin_lock(&conn->bundle->channel_lock);
214214
__rxrpc_disconnect_call(conn, call);

net/rxrpc/sendmsg.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,6 @@ rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg,
564564
atomic_inc_return(&rxrpc_debug_id));
565565
/* The socket is now unlocked */
566566

567-
rxrpc_put_peer(cp.peer, rxrpc_peer_put_discard_tmp);
568567
_leave(" = %p\n", call);
569568
return call;
570569
}

0 commit comments

Comments
 (0)