Skip to content

Commit f3441d4

Browse files
committed
rxrpc: Copy client call parameters into rxrpc_call earlier
Copy client call parameters into rxrpc_call earlier so that that can be used to convey them to the connection code - which can then be offloaded to the I/O thread. Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected]
1 parent 15f661d commit f3441d4

File tree

11 files changed

+87
-48
lines changed

11 files changed

+87
-48
lines changed

include/trace/events/rxrpc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252

5353
#define rxrpc_local_traces \
5454
EM(rxrpc_local_free, "FREE ") \
55+
EM(rxrpc_local_get_call, "GET call ") \
5556
EM(rxrpc_local_get_client_conn, "GET conn-cln") \
5657
EM(rxrpc_local_get_for_use, "GET for-use ") \
5758
EM(rxrpc_local_get_peer, "GET peer ") \
@@ -61,6 +62,7 @@
6162
EM(rxrpc_local_processing, "PROCESSING ") \
6263
EM(rxrpc_local_put_already_queued, "PUT alreadyq") \
6364
EM(rxrpc_local_put_bind, "PUT bind ") \
65+
EM(rxrpc_local_put_call, "PUT call ") \
6466
EM(rxrpc_local_put_for_use, "PUT for-use ") \
6567
EM(rxrpc_local_put_kill_conn, "PUT conn-kil") \
6668
EM(rxrpc_local_put_peer, "PUT peer ") \
@@ -166,6 +168,7 @@
166168
EM(rxrpc_call_new_client, "NEW client ") \
167169
EM(rxrpc_call_new_prealloc_service, "NEW prealloc") \
168170
EM(rxrpc_call_put_discard_prealloc, "PUT disc-pre") \
171+
EM(rxrpc_call_put_discard_error, "PUT disc-err") \
169172
EM(rxrpc_call_put_input, "PUT input ") \
170173
EM(rxrpc_call_put_kernel, "PUT kernel ") \
171174
EM(rxrpc_call_put_poke, "PUT poke ") \

net/rxrpc/ar-internal.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ enum rxrpc_call_flag {
530530
RXRPC_CALL_UPGRADE, /* Service upgrade was requested for the call */
531531
RXRPC_CALL_DELAY_ACK_PENDING, /* DELAY ACK generation is pending */
532532
RXRPC_CALL_IDLE_ACK_PENDING, /* IDLE ACK generation is pending */
533+
RXRPC_CALL_EXCLUSIVE, /* The call uses a once-only connection */
533534
};
534535

535536
/*
@@ -592,10 +593,13 @@ struct rxrpc_call {
592593
struct rcu_head rcu;
593594
struct rxrpc_connection *conn; /* connection carrying call */
594595
struct rxrpc_peer *peer; /* Peer record for remote address */
596+
struct rxrpc_local *local; /* Representation of local endpoint */
595597
struct rxrpc_sock __rcu *socket; /* socket responsible */
596598
struct rxrpc_net *rxnet; /* Network namespace to which call belongs */
599+
struct key *key; /* Security details */
597600
const struct rxrpc_security *security; /* applied security module */
598601
struct mutex user_mutex; /* User access mutex */
602+
struct sockaddr_rxrpc dest_srx; /* Destination address */
599603
unsigned long delay_ack_at; /* When DELAY ACK needs to happen */
600604
unsigned long ack_lost_at; /* When ACK is figured as lost */
601605
unsigned long resend_at; /* When next resend needs to happen */
@@ -631,11 +635,11 @@ struct rxrpc_call {
631635
enum rxrpc_call_state state; /* current state of call */
632636
enum rxrpc_call_completion completion; /* Call completion condition */
633637
refcount_t ref;
634-
u16 service_id; /* service ID */
635638
u8 security_ix; /* Security type */
636639
enum rxrpc_interruptibility interruptibility; /* At what point call may be interrupted */
637640
u32 call_id; /* call ID on connection */
638641
u32 cid; /* connection ID plus channel index */
642+
u32 security_level; /* Security level selected */
639643
int debug_id; /* debug ID for printks */
640644
unsigned short rx_pkt_offset; /* Current recvmsg packet offset */
641645
unsigned short rx_pkt_len; /* Current recvmsg packet len */
@@ -1147,6 +1151,7 @@ extern const struct rxrpc_security rxkad;
11471151
int __init rxrpc_init_security(void);
11481152
const struct rxrpc_security *rxrpc_security_lookup(u8);
11491153
void rxrpc_exit_security(void);
1154+
int rxrpc_init_client_call_security(struct rxrpc_call *);
11501155
int rxrpc_init_client_conn_security(struct rxrpc_connection *);
11511156
const struct rxrpc_security *rxrpc_get_incoming_security(struct rxrpc_sock *,
11521157
struct sk_buff *);

net/rxrpc/call_accept.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,12 @@ static struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx,
318318
(call_tail + 1) & (RXRPC_BACKLOG_MAX - 1));
319319

320320
rxrpc_see_call(call, rxrpc_call_see_accept);
321+
call->local = rxrpc_get_local(conn->local, rxrpc_local_get_call);
321322
call->conn = conn;
322323
call->security = conn->security;
323324
call->security_ix = conn->security_ix;
324325
call->peer = rxrpc_get_peer(conn->peer, rxrpc_peer_get_accept);
326+
call->dest_srx = peer->srx;
325327
call->cong_ssthresh = call->peer->cong_ssthresh;
326328
call->tx_last_sent = ktime_get_real();
327329
return call;

net/rxrpc/call_object.c

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,9 @@ static struct semaphore rxrpc_kernel_call_limiter =
4747

4848
void rxrpc_poke_call(struct rxrpc_call *call, enum rxrpc_call_poke_trace what)
4949
{
50-
struct rxrpc_local *local;
51-
struct rxrpc_peer *peer = call->peer;
50+
struct rxrpc_local *local = call->local;
5251
bool busy;
5352

54-
if (WARN_ON_ONCE(!peer))
55-
return;
56-
local = peer->local;
57-
5853
if (call->state < RXRPC_CALL_COMPLETE) {
5954
spin_lock_bh(&local->lock);
6055
busy = !list_empty(&call->attend_link);
@@ -200,22 +195,45 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp,
200195
*/
201196
static struct rxrpc_call *rxrpc_alloc_client_call(struct rxrpc_sock *rx,
202197
struct sockaddr_rxrpc *srx,
198+
struct rxrpc_conn_parameters *cp,
199+
struct rxrpc_call_params *p,
203200
gfp_t gfp,
204201
unsigned int debug_id)
205202
{
206203
struct rxrpc_call *call;
207204
ktime_t now;
205+
int ret;
208206

209207
_enter("");
210208

211209
call = rxrpc_alloc_call(rx, gfp, debug_id);
212210
if (!call)
213211
return ERR_PTR(-ENOMEM);
214-
call->state = RXRPC_CALL_CLIENT_AWAIT_CONN;
215-
call->service_id = srx->srx_service;
216212
now = ktime_get_real();
217-
call->acks_latest_ts = now;
218-
call->cong_tstamp = now;
213+
call->acks_latest_ts = now;
214+
call->cong_tstamp = now;
215+
call->state = RXRPC_CALL_CLIENT_AWAIT_CONN;
216+
call->dest_srx = *srx;
217+
call->interruptibility = p->interruptibility;
218+
call->tx_total_len = p->tx_total_len;
219+
call->key = key_get(cp->key);
220+
call->local = rxrpc_get_local(cp->local, rxrpc_local_get_call);
221+
if (p->kernel)
222+
__set_bit(RXRPC_CALL_KERNEL, &call->flags);
223+
if (cp->upgrade)
224+
__set_bit(RXRPC_CALL_UPGRADE, &call->flags);
225+
if (cp->exclusive)
226+
__set_bit(RXRPC_CALL_EXCLUSIVE, &call->flags);
227+
228+
ret = rxrpc_init_client_call_security(call);
229+
if (ret < 0) {
230+
__rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, 0, ret);
231+
rxrpc_put_call(call, rxrpc_call_put_discard_error);
232+
return ERR_PTR(ret);
233+
}
234+
235+
trace_rxrpc_call(call->debug_id, refcount_read(&call->ref),
236+
p->user_call_ID, rxrpc_call_new_client);
219237

220238
_leave(" = %p", call);
221239
return call;
@@ -295,21 +313,14 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
295313
return ERR_PTR(-ERESTARTSYS);
296314
}
297315

298-
call = rxrpc_alloc_client_call(rx, srx, gfp, debug_id);
316+
call = rxrpc_alloc_client_call(rx, srx, cp, p, gfp, debug_id);
299317
if (IS_ERR(call)) {
300318
release_sock(&rx->sk);
301319
up(limiter);
302320
_leave(" = %ld", PTR_ERR(call));
303321
return call;
304322
}
305323

306-
call->interruptibility = p->interruptibility;
307-
call->tx_total_len = p->tx_total_len;
308-
trace_rxrpc_call(call->debug_id, refcount_read(&call->ref),
309-
p->user_call_ID, rxrpc_call_new_client);
310-
if (p->kernel)
311-
__set_bit(RXRPC_CALL_KERNEL, &call->flags);
312-
313324
/* We need to protect a partially set up call against the user as we
314325
* will be acting outside the socket lock.
315326
*/
@@ -413,7 +424,7 @@ void rxrpc_incoming_call(struct rxrpc_sock *rx,
413424

414425
rcu_assign_pointer(call->socket, rx);
415426
call->call_id = sp->hdr.callNumber;
416-
call->service_id = sp->hdr.serviceId;
427+
call->dest_srx.srx_service = sp->hdr.serviceId;
417428
call->cid = sp->hdr.cid;
418429
call->state = RXRPC_CALL_SERVER_SECURING;
419430
call->cong_tstamp = skb->tstamp;
@@ -639,6 +650,7 @@ static void rxrpc_destroy_call(struct work_struct *work)
639650
rxrpc_free_skb(call->acks_soft_tbl, rxrpc_skb_put_ack);
640651
rxrpc_put_connection(call->conn, rxrpc_conn_put_call);
641652
rxrpc_put_peer(call->peer, rxrpc_peer_put_call);
653+
rxrpc_put_local(call->local, rxrpc_local_put_call);
642654
call_rcu(&call->rcu, rxrpc_rcu_free_call);
643655
}
644656

net/rxrpc/conn_client.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ static void rxrpc_activate_one_channel(struct rxrpc_connection *conn,
553553
call->call_id = call_id;
554554
call->security = conn->security;
555555
call->security_ix = conn->security_ix;
556-
call->service_id = conn->service_id;
556+
call->dest_srx.srx_service = conn->service_id;
557557

558558
trace_rxrpc_connect_call(call);
559559

net/rxrpc/io_thread.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,8 @@ static int rxrpc_input_packet(struct rxrpc_local *local, struct sk_buff *skb)
343343
}
344344

345345
if (call) {
346-
if (sp->hdr.serviceId != call->service_id)
347-
call->service_id = sp->hdr.serviceId;
346+
if (sp->hdr.serviceId != call->dest_srx.srx_service)
347+
call->dest_srx.srx_service = sp->hdr.serviceId;
348348
if ((int)sp->hdr.serial - (int)call->rx_serial > 0)
349349
call->rx_serial = sp->hdr.serial;
350350
if (!test_bit(RXRPC_CALL_RX_HEARD, &call->flags))

net/rxrpc/output.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call)
357357
pkt.whdr.userStatus = 0;
358358
pkt.whdr.securityIndex = call->security_ix;
359359
pkt.whdr._rsvd = 0;
360-
pkt.whdr.serviceId = htons(call->service_id);
360+
pkt.whdr.serviceId = htons(call->dest_srx.srx_service);
361361
pkt.abort_code = htonl(call->abort_code);
362362

363363
iov[0].iov_base = &pkt;

net/rxrpc/proc.c

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ static void rxrpc_call_seq_stop(struct seq_file *seq, void *v)
4949
static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
5050
{
5151
struct rxrpc_local *local;
52-
struct rxrpc_sock *rx;
53-
struct rxrpc_peer *peer;
5452
struct rxrpc_call *call;
5553
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
5654
unsigned long timeout = 0;
@@ -69,22 +67,13 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
6967

7068
call = list_entry(v, struct rxrpc_call, link);
7169

72-
rx = rcu_dereference(call->socket);
73-
if (rx) {
74-
local = READ_ONCE(rx->local);
75-
if (local)
76-
sprintf(lbuff, "%pISpc", &local->srx.transport);
77-
else
78-
strcpy(lbuff, "no_local");
79-
} else {
80-
strcpy(lbuff, "no_socket");
81-
}
82-
83-
peer = call->peer;
84-
if (peer)
85-
sprintf(rbuff, "%pISpc", &peer->srx.transport);
70+
local = call->local;
71+
if (local)
72+
sprintf(lbuff, "%pISpc", &local->srx.transport);
8673
else
87-
strcpy(rbuff, "no_connection");
74+
strcpy(lbuff, "no_local");
75+
76+
sprintf(rbuff, "%pISpc", &call->dest_srx.transport);
8877

8978
if (call->state != RXRPC_CALL_SERVER_PREALLOC) {
9079
timeout = READ_ONCE(call->expect_rx_by);
@@ -98,7 +87,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
9887
" %-8.8s %08x %08x %08x %02x %08x %02x %08x %06lx\n",
9988
lbuff,
10089
rbuff,
101-
call->service_id,
90+
call->dest_srx.srx_service,
10291
call->cid,
10392
call->call_id,
10493
rxrpc_is_service_call(call) ? "Svc" : "Clt",

net/rxrpc/recvmsg.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -490,11 +490,9 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
490490
}
491491

492492
if (msg->msg_name && call->peer) {
493-
struct sockaddr_rxrpc *srx = msg->msg_name;
494-
size_t len = sizeof(call->peer->srx);
493+
size_t len = sizeof(call->dest_srx);
495494

496-
memcpy(msg->msg_name, &call->peer->srx, len);
497-
srx->srx_service = call->service_id;
495+
memcpy(msg->msg_name, &call->dest_srx, len);
498496
msg->msg_namelen = len;
499497
}
500498

@@ -639,7 +637,7 @@ int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call,
639637
out:
640638
rxrpc_transmit_ack_packets(call->peer->local);
641639
if (_service)
642-
*_service = call->service_id;
640+
*_service = call->dest_srx.srx_service;
643641
mutex_unlock(&call->user_mutex);
644642
_leave(" = %d [%zu,%d]", ret, iov_iter_count(iter), *_abort);
645643
return ret;

net/rxrpc/security.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,36 @@ const struct rxrpc_security *rxrpc_security_lookup(u8 security_index)
6262
return rxrpc_security_types[security_index];
6363
}
6464

65+
/*
66+
* Initialise the security on a client call.
67+
*/
68+
int rxrpc_init_client_call_security(struct rxrpc_call *call)
69+
{
70+
const struct rxrpc_security *sec;
71+
struct rxrpc_key_token *token;
72+
struct key *key = call->key;
73+
int ret;
74+
75+
if (!key)
76+
return 0;
77+
78+
ret = key_validate(key);
79+
if (ret < 0)
80+
return ret;
81+
82+
for (token = key->payload.data[0]; token; token = token->next) {
83+
sec = rxrpc_security_lookup(token->security_index);
84+
if (sec)
85+
goto found;
86+
}
87+
return -EKEYREJECTED;
88+
89+
found:
90+
call->security = sec;
91+
_leave(" = 0");
92+
return 0;
93+
}
94+
6595
/*
6696
* initialise the security on a client connection
6797
*/

net/rxrpc/txbuf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct rxrpc_txbuf *rxrpc_alloc_txbuf(struct rxrpc_call *call, u8 packet_type,
4444
txb->wire.userStatus = 0;
4545
txb->wire.securityIndex = call->security_ix;
4646
txb->wire._rsvd = 0;
47-
txb->wire.serviceId = htons(call->service_id);
47+
txb->wire.serviceId = htons(call->dest_srx.srx_service);
4848

4949
trace_rxrpc_txbuf(txb->debug_id,
5050
txb->call_debug_id, txb->seq, 1,

0 commit comments

Comments
 (0)