summaryrefslogtreecommitdiffstats
path: root/net/rxrpc/io_thread.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2022-10-10 15:51:39 +0100
committerDavid Howells <dhowells@redhat.com>2022-12-01 13:36:41 +0000
commit15f661dc95daec9b38e8e4cc931c95afe0ae0cef (patch)
treeaa5687f899ffe2c55438704c386ac5cdaed4370a /net/rxrpc/io_thread.c
parent81f2e8adc0fd10847637873dafe8610f3fb4cdff (diff)
downloadlinux-15f661dc95daec9b38e8e4cc931c95afe0ae0cef.tar.gz
linux-15f661dc95daec9b38e8e4cc931c95afe0ae0cef.tar.bz2
linux-15f661dc95daec9b38e8e4cc931c95afe0ae0cef.zip
rxrpc: Implement a mechanism to send an event notification to a call
Provide a means by which an event notification can be sent to a call such that the I/O thread can process it rather than it being done in a separate workqueue. This will allow a lot of locking to be removed. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org
Diffstat (limited to 'net/rxrpc/io_thread.c')
-rw-r--r--net/rxrpc/io_thread.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/net/rxrpc/io_thread.c b/net/rxrpc/io_thread.c
index 416c6101cf78..cc249bc6b8cd 100644
--- a/net/rxrpc/io_thread.c
+++ b/net/rxrpc/io_thread.c
@@ -366,7 +366,7 @@ static int rxrpc_input_packet(struct rxrpc_local *local, struct sk_buff *skb)
/* Process a call packet; this either discards or passes on the ref
* elsewhere.
*/
- rxrpc_input_call_packet(call, skb);
+ rxrpc_input_call_event(call, skb);
goto out;
discard:
@@ -413,6 +413,7 @@ int rxrpc_io_thread(void *data)
{
struct sk_buff_head rx_queue;
struct rxrpc_local *local = data;
+ struct rxrpc_call *call;
struct sk_buff *skb;
skb_queue_head_init(&rx_queue);
@@ -422,6 +423,20 @@ int rxrpc_io_thread(void *data)
for (;;) {
rxrpc_inc_stat(local->rxnet, stat_io_loop);
+ /* Deal with calls that want immediate attention. */
+ if ((call = list_first_entry_or_null(&local->call_attend_q,
+ struct rxrpc_call,
+ attend_link))) {
+ spin_lock_bh(&local->lock);
+ list_del_init(&call->attend_link);
+ spin_unlock_bh(&local->lock);
+
+ trace_rxrpc_call_poked(call);
+ rxrpc_input_call_event(call, NULL);
+ rxrpc_put_call(call, rxrpc_call_put_poke);
+ continue;
+ }
+
/* Process received packets and errors. */
if ((skb = __skb_dequeue(&rx_queue))) {
switch (skb->mark) {
@@ -450,7 +465,8 @@ int rxrpc_io_thread(void *data)
}
set_current_state(TASK_INTERRUPTIBLE);
- if (!skb_queue_empty(&local->rx_queue)) {
+ if (!skb_queue_empty(&local->rx_queue) ||
+ !list_empty(&local->call_attend_q)) {
__set_current_state(TASK_RUNNING);
continue;
}