Skip to content

Commit ff73482

Browse files
committed
rxrpc: Move error processing into the local endpoint I/O thread
Move the processing of error packets into the local endpoint I/O thread, leaving the handover from UDP to merely transfer them into the local endpoint queue. Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected]
1 parent 446b3e1 commit ff73482

File tree

3 files changed

+38
-36
lines changed

3 files changed

+38
-36
lines changed

net/rxrpc/ar-internal.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct rxrpc_txbuf;
3737
*/
3838
enum rxrpc_skb_mark {
3939
RXRPC_SKB_MARK_PACKET, /* Received packet */
40+
RXRPC_SKB_MARK_ERROR, /* Error notification */
4041
RXRPC_SKB_MARK_REJECT_BUSY, /* Reject with BUSY */
4142
RXRPC_SKB_MARK_REJECT_ABORT, /* Reject with ABORT (code in skb->priority) */
4243
};
@@ -959,6 +960,7 @@ void rxrpc_input_implicit_end_call(struct rxrpc_sock *, struct rxrpc_connection
959960
* io_thread.c
960961
*/
961962
int rxrpc_encap_rcv(struct sock *, struct sk_buff *);
963+
void rxrpc_error_report(struct sock *);
962964
int rxrpc_io_thread(void *data);
963965
static inline void rxrpc_wake_up_io_thread(struct rxrpc_local *local)
964966
{
@@ -1063,7 +1065,7 @@ void rxrpc_send_keepalive(struct rxrpc_peer *);
10631065
/*
10641066
* peer_event.c
10651067
*/
1066-
void rxrpc_error_report(struct sock *);
1068+
void rxrpc_input_error(struct rxrpc_local *, struct sk_buff *);
10671069
void rxrpc_peer_keepalive_worker(struct work_struct *);
10681070

10691071
/*

net/rxrpc/io_thread.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,31 @@ int rxrpc_encap_rcv(struct sock *udp_sk, struct sk_buff *skb)
3737
return 0;
3838
}
3939

40+
/*
41+
* Handle an error received on the local endpoint.
42+
*/
43+
void rxrpc_error_report(struct sock *sk)
44+
{
45+
struct rxrpc_local *local;
46+
struct sk_buff *skb;
47+
48+
rcu_read_lock();
49+
local = rcu_dereference_sk_user_data(sk);
50+
if (unlikely(!local)) {
51+
rcu_read_unlock();
52+
return;
53+
}
54+
55+
while ((skb = skb_dequeue(&sk->sk_error_queue))) {
56+
skb->mark = RXRPC_SKB_MARK_ERROR;
57+
rxrpc_new_skb(skb, rxrpc_skb_new_error_report);
58+
skb_queue_tail(&local->rx_queue, skb);
59+
}
60+
61+
rxrpc_wake_up_io_thread(local);
62+
rcu_read_unlock();
63+
}
64+
4065
/*
4166
* post connection-level events to the connection
4267
* - this includes challenges, responses, some aborts and call terminal packet
@@ -405,6 +430,10 @@ int rxrpc_io_thread(void *data)
405430
rxrpc_input_packet(local, skb);
406431
rcu_read_unlock();
407432
break;
433+
case RXRPC_SKB_MARK_ERROR:
434+
rxrpc_input_error(local, skb);
435+
rxrpc_free_skb(skb, rxrpc_skb_put_error_report);
436+
break;
408437
default:
409438
WARN_ON_ONCE(1);
410439
rxrpc_free_skb(skb, rxrpc_skb_put_unknown);

net/rxrpc/peer_event.c

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -131,51 +131,26 @@ static void rxrpc_adjust_mtu(struct rxrpc_peer *peer, unsigned int mtu)
131131
/*
132132
* Handle an error received on the local endpoint.
133133
*/
134-
void rxrpc_error_report(struct sock *sk)
134+
void rxrpc_input_error(struct rxrpc_local *local, struct sk_buff *skb)
135135
{
136-
struct sock_exterr_skb *serr;
136+
struct sock_exterr_skb *serr = SKB_EXT_ERR(skb);
137137
struct sockaddr_rxrpc srx;
138-
struct rxrpc_local *local;
139138
struct rxrpc_peer *peer = NULL;
140-
struct sk_buff *skb;
141139

142-
rcu_read_lock();
143-
local = rcu_dereference_sk_user_data(sk);
144-
if (unlikely(!local)) {
145-
rcu_read_unlock();
146-
return;
147-
}
148-
_enter("%p{%d}", sk, local->debug_id);
140+
_enter("L=%x", local->debug_id);
149141

150-
/* Clear the outstanding error value on the socket so that it doesn't
151-
* cause kernel_sendmsg() to return it later.
152-
*/
153-
sock_error(sk);
154-
155-
skb = sock_dequeue_err_skb(sk);
156-
if (!skb) {
157-
rcu_read_unlock();
158-
_leave("UDP socket errqueue empty");
159-
return;
160-
}
161-
rxrpc_new_skb(skb, rxrpc_skb_new_error_report);
162-
serr = SKB_EXT_ERR(skb);
163142
if (!skb->len && serr->ee.ee_origin == SO_EE_ORIGIN_TIMESTAMPING) {
164143
_leave("UDP empty message");
165-
rcu_read_unlock();
166-
rxrpc_free_skb(skb, rxrpc_skb_put_error_report);
167144
return;
168145
}
169146

147+
rcu_read_lock();
170148
peer = rxrpc_lookup_peer_local_rcu(local, skb, &srx);
171149
if (peer && !rxrpc_get_peer_maybe(peer, rxrpc_peer_get_input_error))
172150
peer = NULL;
173-
if (!peer) {
174-
rcu_read_unlock();
175-
rxrpc_free_skb(skb, rxrpc_skb_put_error_report);
176-
_leave(" [no peer]");
151+
rcu_read_unlock();
152+
if (!peer)
177153
return;
178-
}
179154

180155
trace_rxrpc_rx_icmp(peer, &serr->ee, &srx);
181156

@@ -188,11 +163,7 @@ void rxrpc_error_report(struct sock *sk)
188163

189164
rxrpc_store_error(peer, serr);
190165
out:
191-
rcu_read_unlock();
192-
rxrpc_free_skb(skb, rxrpc_skb_put_error_report);
193166
rxrpc_put_peer(peer, rxrpc_peer_put_input_error);
194-
195-
_leave("");
196167
}
197168

198169
/*

0 commit comments

Comments
 (0)