Skip to content

Commit 15f661d

Browse files
committed
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 <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected]
1 parent 81f2e8a commit 15f661d

File tree

6 files changed

+100
-5
lines changed

6 files changed

+100
-5
lines changed

include/trace/events/rxrpc.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
/*
1717
* Declare tracing information enums and their string mappings for display.
1818
*/
19+
#define rxrpc_call_poke_traces \
20+
EM(rxrpc_call_poke_error, "Error") \
21+
EM(rxrpc_call_poke_idle, "Idle") \
22+
EM(rxrpc_call_poke_start, "Start") \
23+
EM(rxrpc_call_poke_timer, "Timer") \
24+
E_(rxrpc_call_poke_timer_now, "Timer-now")
25+
1926
#define rxrpc_skb_traces \
2027
EM(rxrpc_skb_eaten_by_unshare, "ETN unshare ") \
2128
EM(rxrpc_skb_eaten_by_unshare_nomem, "ETN unshar-nm") \
@@ -150,6 +157,7 @@
150157
EM(rxrpc_call_get_input, "GET input ") \
151158
EM(rxrpc_call_get_kernel_service, "GET krnl-srv") \
152159
EM(rxrpc_call_get_notify_socket, "GET notify ") \
160+
EM(rxrpc_call_get_poke, "GET poke ") \
153161
EM(rxrpc_call_get_recvmsg, "GET recvmsg ") \
154162
EM(rxrpc_call_get_release_sock, "GET rel-sock") \
155163
EM(rxrpc_call_get_sendmsg, "GET sendmsg ") \
@@ -160,6 +168,7 @@
160168
EM(rxrpc_call_put_discard_prealloc, "PUT disc-pre") \
161169
EM(rxrpc_call_put_input, "PUT input ") \
162170
EM(rxrpc_call_put_kernel, "PUT kernel ") \
171+
EM(rxrpc_call_put_poke, "PUT poke ") \
163172
EM(rxrpc_call_put_recvmsg, "PUT recvmsg ") \
164173
EM(rxrpc_call_put_release_sock, "PUT rls-sock") \
165174
EM(rxrpc_call_put_release_sock_tba, "PUT rls-sk-a") \
@@ -378,6 +387,7 @@
378387
#define E_(a, b) a
379388

380389
enum rxrpc_bundle_trace { rxrpc_bundle_traces } __mode(byte);
390+
enum rxrpc_call_poke_trace { rxrpc_call_poke_traces } __mode(byte);
381391
enum rxrpc_call_trace { rxrpc_call_traces } __mode(byte);
382392
enum rxrpc_client_trace { rxrpc_client_traces } __mode(byte);
383393
enum rxrpc_congest_change { rxrpc_congest_changes } __mode(byte);
@@ -408,6 +418,7 @@ enum rxrpc_txqueue_trace { rxrpc_txqueue_traces } __mode(byte);
408418
#define E_(a, b) TRACE_DEFINE_ENUM(a);
409419

410420
rxrpc_bundle_traces;
421+
rxrpc_call_poke_traces;
411422
rxrpc_call_traces;
412423
rxrpc_client_traces;
413424
rxrpc_congest_changes;
@@ -1747,6 +1758,47 @@ TRACE_EVENT(rxrpc_txbuf,
17471758
__entry->ref)
17481759
);
17491760

1761+
TRACE_EVENT(rxrpc_poke_call,
1762+
TP_PROTO(struct rxrpc_call *call, bool busy,
1763+
enum rxrpc_call_poke_trace what),
1764+
1765+
TP_ARGS(call, busy, what),
1766+
1767+
TP_STRUCT__entry(
1768+
__field(unsigned int, call_debug_id )
1769+
__field(bool, busy )
1770+
__field(enum rxrpc_call_poke_trace, what )
1771+
),
1772+
1773+
TP_fast_assign(
1774+
__entry->call_debug_id = call->debug_id;
1775+
__entry->busy = busy;
1776+
__entry->what = what;
1777+
),
1778+
1779+
TP_printk("c=%08x %s%s",
1780+
__entry->call_debug_id,
1781+
__print_symbolic(__entry->what, rxrpc_call_poke_traces),
1782+
__entry->busy ? "!" : "")
1783+
);
1784+
1785+
TRACE_EVENT(rxrpc_call_poked,
1786+
TP_PROTO(struct rxrpc_call *call),
1787+
1788+
TP_ARGS(call),
1789+
1790+
TP_STRUCT__entry(
1791+
__field(unsigned int, call_debug_id )
1792+
),
1793+
1794+
TP_fast_assign(
1795+
__entry->call_debug_id = call->debug_id;
1796+
),
1797+
1798+
TP_printk("c=%08x",
1799+
__entry->call_debug_id)
1800+
);
1801+
17501802
#undef EM
17511803
#undef E_
17521804
#endif /* _TRACE_RXRPC_H */

net/rxrpc/ar-internal.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ struct rxrpc_local {
292292
struct sk_buff_head reject_queue; /* packets awaiting rejection */
293293
struct sk_buff_head event_queue; /* endpoint event packets awaiting processing */
294294
struct sk_buff_head rx_queue; /* Received packets */
295+
struct list_head call_attend_q; /* Calls requiring immediate attention */
295296
struct rb_root client_bundles; /* Client connection bundles by socket params */
296297
spinlock_t client_bundles_lock; /* Lock for client_bundles */
297298
spinlock_t lock; /* access lock */
@@ -616,6 +617,7 @@ struct rxrpc_call {
616617
struct list_head recvmsg_link; /* Link in rx->recvmsg_q */
617618
struct list_head sock_link; /* Link in rx->sock_calls */
618619
struct rb_node sock_node; /* Node in rx->calls */
620+
struct list_head attend_link; /* Link in local->call_attend_q */
619621
struct rxrpc_txbuf *tx_pending; /* Tx buffer being filled */
620622
wait_queue_head_t waitq; /* Wait queue for channel or Tx */
621623
s64 tx_total_len; /* Total length left to be transmitted (or -1) */
@@ -843,6 +845,7 @@ extern const char *const rxrpc_call_states[];
843845
extern const char *const rxrpc_call_completions[];
844846
extern struct kmem_cache *rxrpc_call_jar;
845847

848+
void rxrpc_poke_call(struct rxrpc_call *call, enum rxrpc_call_poke_trace what);
846849
struct rxrpc_call *rxrpc_find_call_by_user_ID(struct rxrpc_sock *, unsigned long);
847850
struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *, gfp_t, unsigned int);
848851
struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *,
@@ -951,7 +954,7 @@ void rxrpc_unpublish_service_conn(struct rxrpc_connection *);
951954
/*
952955
* input.c
953956
*/
954-
void rxrpc_input_call_packet(struct rxrpc_call *, struct sk_buff *);
957+
void rxrpc_input_call_event(struct rxrpc_call *, struct sk_buff *);
955958
void rxrpc_input_implicit_end_call(struct rxrpc_sock *, struct rxrpc_connection *,
956959
struct rxrpc_call *);
957960

net/rxrpc/call_object.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,29 @@ static struct semaphore rxrpc_call_limiter =
4545
static struct semaphore rxrpc_kernel_call_limiter =
4646
__SEMAPHORE_INITIALIZER(rxrpc_kernel_call_limiter, 1000);
4747

48+
void rxrpc_poke_call(struct rxrpc_call *call, enum rxrpc_call_poke_trace what)
49+
{
50+
struct rxrpc_local *local;
51+
struct rxrpc_peer *peer = call->peer;
52+
bool busy;
53+
54+
if (WARN_ON_ONCE(!peer))
55+
return;
56+
local = peer->local;
57+
58+
if (call->state < RXRPC_CALL_COMPLETE) {
59+
spin_lock_bh(&local->lock);
60+
busy = !list_empty(&call->attend_link);
61+
trace_rxrpc_poke_call(call, busy, what);
62+
if (!busy) {
63+
rxrpc_get_call(call, rxrpc_call_get_poke);
64+
list_add_tail(&call->attend_link, &local->call_attend_q);
65+
}
66+
spin_unlock_bh(&local->lock);
67+
rxrpc_wake_up_io_thread(local);
68+
}
69+
}
70+
4871
static void rxrpc_call_timer_expired(struct timer_list *t)
4972
{
5073
struct rxrpc_call *call = from_timer(call, t, timer);
@@ -137,6 +160,7 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp,
137160
INIT_LIST_HEAD(&call->accept_link);
138161
INIT_LIST_HEAD(&call->recvmsg_link);
139162
INIT_LIST_HEAD(&call->sock_link);
163+
INIT_LIST_HEAD(&call->attend_link);
140164
INIT_LIST_HEAD(&call->tx_buffer);
141165
skb_queue_head_init(&call->recvmsg_queue);
142166
skb_queue_head_init(&call->rx_oos_queue);

net/rxrpc/input.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,8 +1017,7 @@ static void rxrpc_input_abort(struct rxrpc_call *call, struct sk_buff *skb)
10171017
/*
10181018
* Process an incoming call packet.
10191019
*/
1020-
void rxrpc_input_call_packet(struct rxrpc_call *call,
1021-
struct sk_buff *skb)
1020+
void rxrpc_input_call_event(struct rxrpc_call *call, struct sk_buff *skb)
10221021
{
10231022
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
10241023
unsigned long timo;

net/rxrpc/io_thread.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ static int rxrpc_input_packet(struct rxrpc_local *local, struct sk_buff *skb)
366366
/* Process a call packet; this either discards or passes on the ref
367367
* elsewhere.
368368
*/
369-
rxrpc_input_call_packet(call, skb);
369+
rxrpc_input_call_event(call, skb);
370370
goto out;
371371

372372
discard:
@@ -413,6 +413,7 @@ int rxrpc_io_thread(void *data)
413413
{
414414
struct sk_buff_head rx_queue;
415415
struct rxrpc_local *local = data;
416+
struct rxrpc_call *call;
416417
struct sk_buff *skb;
417418

418419
skb_queue_head_init(&rx_queue);
@@ -422,6 +423,20 @@ int rxrpc_io_thread(void *data)
422423
for (;;) {
423424
rxrpc_inc_stat(local->rxnet, stat_io_loop);
424425

426+
/* Deal with calls that want immediate attention. */
427+
if ((call = list_first_entry_or_null(&local->call_attend_q,
428+
struct rxrpc_call,
429+
attend_link))) {
430+
spin_lock_bh(&local->lock);
431+
list_del_init(&call->attend_link);
432+
spin_unlock_bh(&local->lock);
433+
434+
trace_rxrpc_call_poked(call);
435+
rxrpc_input_call_event(call, NULL);
436+
rxrpc_put_call(call, rxrpc_call_put_poke);
437+
continue;
438+
}
439+
425440
/* Process received packets and errors. */
426441
if ((skb = __skb_dequeue(&rx_queue))) {
427442
switch (skb->mark) {
@@ -450,7 +465,8 @@ int rxrpc_io_thread(void *data)
450465
}
451466

452467
set_current_state(TASK_INTERRUPTIBLE);
453-
if (!skb_queue_empty(&local->rx_queue)) {
468+
if (!skb_queue_empty(&local->rx_queue) ||
469+
!list_empty(&local->call_attend_q)) {
454470
__set_current_state(TASK_RUNNING);
455471
continue;
456472
}

net/rxrpc/local_object.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ static struct rxrpc_local *rxrpc_alloc_local(struct rxrpc_net *rxnet,
104104
skb_queue_head_init(&local->reject_queue);
105105
skb_queue_head_init(&local->event_queue);
106106
skb_queue_head_init(&local->rx_queue);
107+
INIT_LIST_HEAD(&local->call_attend_q);
107108
local->client_bundles = RB_ROOT;
108109
spin_lock_init(&local->client_bundles_lock);
109110
spin_lock_init(&local->lock);

0 commit comments

Comments
 (0)