Skip to content

Commit f2cce89

Browse files
committed
rxrpc: Implement a mechanism to send an event notification to a connection
Provide a means by which an event notification can be sent to a connection through such that the I/O thread can pick it up and handle it rather than doing it in a separate workqueue. This is then used to move the deferred final ACK of a call into the I/O thread rather than a separate work queue as part of the drive to do all transmission from the I/O thread. Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected]
1 parent 03fc55a commit f2cce89

File tree

6 files changed

+55
-9
lines changed

6 files changed

+55
-9
lines changed

include/trace/events/rxrpc.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
EM(rxrpc_conn_get_call_input, "GET inp-call") \
112112
EM(rxrpc_conn_get_conn_input, "GET inp-conn") \
113113
EM(rxrpc_conn_get_idle, "GET idle ") \
114-
EM(rxrpc_conn_get_poke, "GET poke ") \
114+
EM(rxrpc_conn_get_poke_timer, "GET poke ") \
115115
EM(rxrpc_conn_get_service_conn, "GET svc-conn") \
116116
EM(rxrpc_conn_new_client, "NEW client ") \
117117
EM(rxrpc_conn_new_service, "NEW service ") \
@@ -126,10 +126,9 @@
126126
EM(rxrpc_conn_put_service_reaped, "PUT svc-reap") \
127127
EM(rxrpc_conn_put_unbundle, "PUT unbundle") \
128128
EM(rxrpc_conn_put_unidle, "PUT unidle ") \
129+
EM(rxrpc_conn_put_work, "PUT work ") \
129130
EM(rxrpc_conn_queue_challenge, "QUE chall ") \
130-
EM(rxrpc_conn_queue_retry_work, "QUE retry-wk") \
131131
EM(rxrpc_conn_queue_rx_work, "QUE rx-work ") \
132-
EM(rxrpc_conn_queue_timer, "QUE timer ") \
133132
EM(rxrpc_conn_see_new_service_conn, "SEE new-svc ") \
134133
EM(rxrpc_conn_see_reap_service, "SEE reap-svc") \
135134
E_(rxrpc_conn_see_work, "SEE work ")

net/rxrpc/ar-internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ struct rxrpc_host_header {
202202
* - max 48 bytes (struct sk_buff::cb)
203203
*/
204204
struct rxrpc_skb_priv {
205+
struct rxrpc_connection *conn; /* Connection referred to (poke packet) */
205206
u16 offset; /* Offset of data */
206207
u16 len; /* Length of data */
207208
u8 flags;
@@ -292,6 +293,7 @@ struct rxrpc_local {
292293
struct rxrpc_sock __rcu *service; /* Service(s) listening on this endpoint */
293294
struct rw_semaphore defrag_sem; /* control re-enablement of IP DF bit */
294295
struct sk_buff_head rx_queue; /* Received packets */
296+
struct list_head conn_attend_q; /* Conns requiring immediate attention */
295297
struct list_head call_attend_q; /* Calls requiring immediate attention */
296298
struct rb_root client_bundles; /* Client connection bundles by socket params */
297299
spinlock_t client_bundles_lock; /* Lock for client_bundles */
@@ -441,6 +443,7 @@ struct rxrpc_connection {
441443
struct rxrpc_peer *peer; /* Remote endpoint */
442444
struct rxrpc_net *rxnet; /* Network namespace to which call belongs */
443445
struct key *key; /* Security details */
446+
struct list_head attend_link; /* Link in local->conn_attend_q */
444447

445448
refcount_t ref;
446449
atomic_t active; /* Active count for service conns */
@@ -905,13 +908,15 @@ void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, struct sk_buff *s
905908
void rxrpc_process_connection(struct work_struct *);
906909
void rxrpc_process_delayed_final_acks(struct rxrpc_connection *, bool);
907910
int rxrpc_input_conn_packet(struct rxrpc_connection *conn, struct sk_buff *skb);
911+
void rxrpc_input_conn_event(struct rxrpc_connection *conn, struct sk_buff *skb);
908912

909913
/*
910914
* conn_object.c
911915
*/
912916
extern unsigned int rxrpc_connection_expiry;
913917
extern unsigned int rxrpc_closed_conn_expiry;
914918

919+
void rxrpc_poke_conn(struct rxrpc_connection *conn, enum rxrpc_conn_trace why);
915920
struct rxrpc_connection *rxrpc_alloc_connection(struct rxrpc_net *, gfp_t);
916921
struct rxrpc_connection *rxrpc_find_client_connection_rcu(struct rxrpc_local *,
917922
struct sockaddr_rxrpc *,

net/rxrpc/conn_event.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,6 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn)
412412
if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events))
413413
rxrpc_secure_connection(conn);
414414

415-
/* Process delayed ACKs whose time has come. */
416-
if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK)
417-
rxrpc_process_delayed_final_acks(conn, false);
418-
419415
/* go through the conn-level event packets, releasing the ref on this
420416
* connection that each one has when we've finished with it */
421417
while ((skb = skb_dequeue(&conn->rx_queue))) {
@@ -515,3 +511,13 @@ int rxrpc_input_conn_packet(struct rxrpc_connection *conn, struct sk_buff *skb)
515511
return -EPROTO;
516512
}
517513
}
514+
515+
/*
516+
* Input a connection event.
517+
*/
518+
void rxrpc_input_conn_event(struct rxrpc_connection *conn, struct sk_buff *skb)
519+
{
520+
/* Process delayed ACKs whose time has come. */
521+
if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK)
522+
rxrpc_process_delayed_final_acks(conn, false);
523+
}

net/rxrpc/conn_object.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,30 @@ static void rxrpc_clean_up_connection(struct work_struct *work);
2323
static void rxrpc_set_service_reap_timer(struct rxrpc_net *rxnet,
2424
unsigned long reap_at);
2525

26+
void rxrpc_poke_conn(struct rxrpc_connection *conn, enum rxrpc_conn_trace why)
27+
{
28+
struct rxrpc_local *local = conn->local;
29+
bool busy;
30+
31+
if (WARN_ON_ONCE(!local))
32+
return;
33+
34+
spin_lock_bh(&local->lock);
35+
busy = !list_empty(&conn->attend_link);
36+
if (!busy) {
37+
rxrpc_get_connection(conn, why);
38+
list_add_tail(&conn->attend_link, &local->conn_attend_q);
39+
}
40+
spin_unlock_bh(&local->lock);
41+
rxrpc_wake_up_io_thread(local);
42+
}
43+
2644
static void rxrpc_connection_timer(struct timer_list *timer)
2745
{
2846
struct rxrpc_connection *conn =
2947
container_of(timer, struct rxrpc_connection, timer);
3048

31-
rxrpc_queue_conn(conn, rxrpc_conn_queue_timer);
49+
rxrpc_poke_conn(conn, rxrpc_conn_get_poke_timer);
3250
}
3351

3452
/*

net/rxrpc/io_thread.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ static int rxrpc_input_packet_on_conn(struct rxrpc_connection *conn,
421421
*/
422422
int rxrpc_io_thread(void *data)
423423
{
424+
struct rxrpc_connection *conn;
424425
struct sk_buff_head rx_queue;
425426
struct rxrpc_local *local = data;
426427
struct rxrpc_call *call;
@@ -436,6 +437,20 @@ int rxrpc_io_thread(void *data)
436437
for (;;) {
437438
rxrpc_inc_stat(local->rxnet, stat_io_loop);
438439

440+
/* Deal with connections that want immediate attention. */
441+
conn = list_first_entry_or_null(&local->conn_attend_q,
442+
struct rxrpc_connection,
443+
attend_link);
444+
if (conn) {
445+
spin_lock_bh(&local->lock);
446+
list_del_init(&conn->attend_link);
447+
spin_unlock_bh(&local->lock);
448+
449+
rxrpc_input_conn_event(conn, NULL);
450+
rxrpc_put_connection(conn, rxrpc_conn_put_poke);
451+
continue;
452+
}
453+
439454
/* Deal with calls that want immediate attention. */
440455
if ((call = list_first_entry_or_null(&local->call_attend_q,
441456
struct rxrpc_call,
@@ -463,6 +478,7 @@ int rxrpc_io_thread(void *data)
463478
rxrpc_input_error(local, skb);
464479
rxrpc_free_skb(skb, rxrpc_skb_put_error_report);
465480
break;
481+
break;
466482
default:
467483
WARN_ON_ONCE(1);
468484
rxrpc_free_skb(skb, rxrpc_skb_put_unknown);
@@ -481,7 +497,8 @@ int rxrpc_io_thread(void *data)
481497
set_current_state(TASK_INTERRUPTIBLE);
482498
should_stop = kthread_should_stop();
483499
if (!skb_queue_empty(&local->rx_queue) ||
484-
!list_empty(&local->call_attend_q)) {
500+
!list_empty(&local->call_attend_q) ||
501+
!list_empty(&local->conn_attend_q)) {
485502
__set_current_state(TASK_RUNNING);
486503
continue;
487504
}

net/rxrpc/local_object.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static struct rxrpc_local *rxrpc_alloc_local(struct net *net,
100100
init_rwsem(&local->defrag_sem);
101101
init_completion(&local->io_thread_ready);
102102
skb_queue_head_init(&local->rx_queue);
103+
INIT_LIST_HEAD(&local->conn_attend_q);
103104
INIT_LIST_HEAD(&local->call_attend_q);
104105
local->client_bundles = RB_ROOT;
105106
spin_lock_init(&local->client_bundles_lock);

0 commit comments

Comments
 (0)