Skip to content

Commit 2953d3b

Browse files
committed
rxrpc: Offload the completion of service conn security to the I/O thread
Offload the completion of the challenge/response cycle on a service connection to the I/O thread. After the RESPONSE packet has been successfully decrypted and verified by the work queue, offloading the changing of the call states to the I/O thread makes iteration over the conn's channel list simpler. Do this by marking the RESPONSE skbuff and putting it onto the receive queue for the I/O thread to collect. We put it on the front of the queue as we've already received the packet for it. Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected]
1 parent f06cb29 commit 2953d3b

File tree

4 files changed

+40
-14
lines changed

4 files changed

+40
-14
lines changed

include/trace/events/rxrpc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
#define rxrpc_skb_traces \
127127
EM(rxrpc_skb_eaten_by_unshare, "ETN unshare ") \
128128
EM(rxrpc_skb_eaten_by_unshare_nomem, "ETN unshar-nm") \
129+
EM(rxrpc_skb_get_conn_secured, "GET conn-secd") \
129130
EM(rxrpc_skb_get_conn_work, "GET conn-work") \
130131
EM(rxrpc_skb_get_local_work, "GET locl-work") \
131132
EM(rxrpc_skb_get_reject_work, "GET rej-work ") \
@@ -135,6 +136,7 @@
135136
EM(rxrpc_skb_new_error_report, "NEW error-rpt") \
136137
EM(rxrpc_skb_new_jumbo_subpacket, "NEW jumbo-sub") \
137138
EM(rxrpc_skb_new_unshared, "NEW unshared ") \
139+
EM(rxrpc_skb_put_conn_secured, "PUT conn-secd") \
138140
EM(rxrpc_skb_put_conn_work, "PUT conn-work") \
139141
EM(rxrpc_skb_put_error_report, "PUT error-rep") \
140142
EM(rxrpc_skb_put_input, "PUT input ") \

net/rxrpc/ar-internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct rxrpc_txbuf;
3838
enum rxrpc_skb_mark {
3939
RXRPC_SKB_MARK_PACKET, /* Received packet */
4040
RXRPC_SKB_MARK_ERROR, /* Error notification */
41+
RXRPC_SKB_MARK_SERVICE_CONN_SECURED, /* Service connection response has been verified */
4142
RXRPC_SKB_MARK_REJECT_BUSY, /* Reject with BUSY */
4243
RXRPC_SKB_MARK_REJECT_ABORT, /* Reject with ABORT (code in skb->priority) */
4344
};

net/rxrpc/conn_event.c

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
248248
struct sk_buff *skb)
249249
{
250250
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
251-
int loop, ret;
251+
int ret;
252252

253253
if (conn->state == RXRPC_CONN_ABORTED)
254254
return -ECONNABORTED;
@@ -269,22 +269,21 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
269269
if (ret < 0)
270270
return ret;
271271

272-
spin_lock(&conn->bundle->channel_lock);
273272
spin_lock(&conn->state_lock);
274-
275-
if (conn->state == RXRPC_CONN_SERVICE_CHALLENGING) {
273+
if (conn->state == RXRPC_CONN_SERVICE_CHALLENGING)
276274
conn->state = RXRPC_CONN_SERVICE;
277-
spin_unlock(&conn->state_lock);
278-
for (loop = 0; loop < RXRPC_MAXCALLS; loop++)
279-
rxrpc_call_is_secure(
280-
rcu_dereference_protected(
281-
conn->channels[loop].call,
282-
lockdep_is_held(&conn->bundle->channel_lock)));
283-
} else {
284-
spin_unlock(&conn->state_lock);
285-
}
275+
spin_unlock(&conn->state_lock);
286276

287-
spin_unlock(&conn->bundle->channel_lock);
277+
if (conn->state == RXRPC_CONN_SERVICE) {
278+
/* Offload call state flipping to the I/O thread. As
279+
* we've already received the packet, put it on the
280+
* front of the queue.
281+
*/
282+
skb->mark = RXRPC_SKB_MARK_SERVICE_CONN_SECURED;
283+
rxrpc_get_skb(skb, rxrpc_skb_get_conn_secured);
284+
skb_queue_head(&conn->local->rx_queue, skb);
285+
rxrpc_wake_up_io_thread(conn->local);
286+
}
288287
return 0;
289288

290289
default:
@@ -442,9 +441,28 @@ bool rxrpc_input_conn_packet(struct rxrpc_connection *conn, struct sk_buff *skb)
442441
*/
443442
void rxrpc_input_conn_event(struct rxrpc_connection *conn, struct sk_buff *skb)
444443
{
444+
unsigned int loop;
445+
445446
if (test_and_clear_bit(RXRPC_CONN_EV_ABORT_CALLS, &conn->events))
446447
rxrpc_abort_calls(conn);
447448

449+
switch (skb->mark) {
450+
case RXRPC_SKB_MARK_SERVICE_CONN_SECURED:
451+
if (conn->state != RXRPC_CONN_SERVICE)
452+
break;
453+
454+
spin_lock(&conn->bundle->channel_lock);
455+
456+
for (loop = 0; loop < RXRPC_MAXCALLS; loop++)
457+
rxrpc_call_is_secure(
458+
rcu_dereference_protected(
459+
conn->channels[loop].call,
460+
lockdep_is_held(&conn->bundle->channel_lock)));
461+
462+
spin_unlock(&conn->bundle->channel_lock);
463+
break;
464+
}
465+
448466
/* Process delayed ACKs whose time has come. */
449467
if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK)
450468
rxrpc_process_delayed_final_acks(conn, false);

net/rxrpc/io_thread.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ int rxrpc_io_thread(void *data)
451451

452452
/* Process received packets and errors. */
453453
if ((skb = __skb_dequeue(&rx_queue))) {
454+
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
454455
switch (skb->mark) {
455456
case RXRPC_SKB_MARK_PACKET:
456457
skb->priority = 0;
@@ -463,6 +464,10 @@ int rxrpc_io_thread(void *data)
463464
rxrpc_input_error(local, skb);
464465
rxrpc_free_skb(skb, rxrpc_skb_put_error_report);
465466
break;
467+
case RXRPC_SKB_MARK_SERVICE_CONN_SECURED:
468+
rxrpc_input_conn_event(sp->conn, skb);
469+
rxrpc_put_connection(sp->conn, rxrpc_conn_put_poke);
470+
rxrpc_free_skb(skb, rxrpc_skb_put_conn_secured);
466471
break;
467472
default:
468473
WARN_ON_ONCE(1);

0 commit comments

Comments
 (0)