Skip to content

Commit b3fc03b

Browse files
committed
rxrpc: Make the local endpoint hold a ref on a connected call
jira LE-1907 Rebuild_History Non-Buildable kernel-rt-5.14.0-284.30.1.rt14.315.el9_2 commit-author David Howells <dhowells@redhat.com> commit 5040011 Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-rt-5.14.0-284.30.1.rt14.315.el9_2/5040011d.failed Make the local endpoint and it's I/O thread hold a reference on a connected call until that call is disconnected. Without this, we're reliant on either the AF_RXRPC socket to hold a ref (which is dropped when the call is released) or a queued work item to hold a ref (the work item is being replaced with the I/O thread). Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org (cherry picked from commit 5040011) Signed-off-by: Jonathan Maple <jmaple@ciq.com> # Conflicts: # include/trace/events/rxrpc.h # net/rxrpc/call_object.c # net/rxrpc/conn_object.c
1 parent 9c01ca3 commit b3fc03b

File tree

1 file changed

+195
-0
lines changed

1 file changed

+195
-0
lines changed
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
rxrpc: Make the local endpoint hold a ref on a connected call
2+
3+
jira LE-1907
4+
Rebuild_History Non-Buildable kernel-rt-5.14.0-284.30.1.rt14.315.el9_2
5+
commit-author David Howells <dhowells@redhat.com>
6+
commit 5040011d073d3acdeb58af2b64f84e33bb03abd2
7+
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
8+
Will be included in final tarball splat. Ref for failed cherry-pick at:
9+
ciq/ciq_backports/kernel-rt-5.14.0-284.30.1.rt14.315.el9_2/5040011d.failed
10+
11+
Make the local endpoint and it's I/O thread hold a reference on a connected
12+
call until that call is disconnected. Without this, we're reliant on
13+
either the AF_RXRPC socket to hold a ref (which is dropped when the call is
14+
released) or a queued work item to hold a ref (the work item is being
15+
replaced with the I/O thread).
16+
17+
Signed-off-by: David Howells <dhowells@redhat.com>
18+
cc: Marc Dionne <marc.dionne@auristor.com>
19+
cc: linux-afs@lists.infradead.org
20+
(cherry picked from commit 5040011d073d3acdeb58af2b64f84e33bb03abd2)
21+
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
22+
23+
# Conflicts:
24+
# include/trace/events/rxrpc.h
25+
# net/rxrpc/call_object.c
26+
# net/rxrpc/conn_object.c
27+
diff --cc include/trace/events/rxrpc.h
28+
index 2a52121d73a0,b526d982da7e..000000000000
29+
--- a/include/trace/events/rxrpc.h
30+
+++ b/include/trace/events/rxrpc.h
31+
@@@ -82,10 -159,12 +83,15 @@@
32+
EM(rxrpc_call_get_userid, "GET user-id ") \
33+
EM(rxrpc_call_new_client, "NEW client ") \
34+
EM(rxrpc_call_new_prealloc_service, "NEW prealloc") \
35+
+ EM(rxrpc_call_put_already_queued, "PUT alreadyq") \
36+
EM(rxrpc_call_put_discard_prealloc, "PUT disc-pre") \
37+
++<<<<<<< HEAD
38+
++=======
39+
+ EM(rxrpc_call_put_discard_error, "PUT disc-err") \
40+
+ EM(rxrpc_call_put_io_thread, "PUT iothread") \
41+
++>>>>>>> 5040011d073d (rxrpc: Make the local endpoint hold a ref on a connected call)
42+
EM(rxrpc_call_put_input, "PUT input ") \
43+
EM(rxrpc_call_put_kernel, "PUT kernel ") \
44+
- EM(rxrpc_call_put_poke, "PUT poke ") \
45+
EM(rxrpc_call_put_recvmsg, "PUT recvmsg ") \
46+
EM(rxrpc_call_put_release_sock, "PUT rls-sock") \
47+
EM(rxrpc_call_put_release_sock_tba, "PUT rls-sk-a") \
48+
diff --cc net/rxrpc/call_object.c
49+
index ad495d0d21a8,239fc3c75079..000000000000
50+
--- a/net/rxrpc/call_object.c
51+
+++ b/net/rxrpc/call_object.c
52+
@@@ -405,6 -430,31 +405,34 @@@ void rxrpc_incoming_call(struct rxrpc_s
53+
call->state = RXRPC_CALL_SERVER_SECURING;
54+
call->cong_tstamp = skb->tstamp;
55+
56+
++<<<<<<< HEAD
57+
++=======
58+
+ spin_lock(&conn->state_lock);
59+
+
60+
+ switch (conn->state) {
61+
+ case RXRPC_CONN_SERVICE_UNSECURED:
62+
+ case RXRPC_CONN_SERVICE_CHALLENGING:
63+
+ call->state = RXRPC_CALL_SERVER_SECURING;
64+
+ break;
65+
+ case RXRPC_CONN_SERVICE:
66+
+ call->state = RXRPC_CALL_SERVER_RECV_REQUEST;
67+
+ break;
68+
+
69+
+ case RXRPC_CONN_REMOTELY_ABORTED:
70+
+ __rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED,
71+
+ conn->abort_code, conn->error);
72+
+ break;
73+
+ case RXRPC_CONN_LOCALLY_ABORTED:
74+
+ __rxrpc_abort_call("CON", call, 1,
75+
+ conn->abort_code, conn->error);
76+
+ break;
77+
+ default:
78+
+ BUG();
79+
+ }
80+
+
81+
+ rxrpc_get_call(call, rxrpc_call_get_io_thread);
82+
+
83+
++>>>>>>> 5040011d073d (rxrpc: Make the local endpoint hold a ref on a connected call)
84+
/* Set the channel for this call. We don't get channel_lock as we're
85+
* only defending against the data_ready handler (which we're called
86+
* from) and the RESPONSE packet parser (which is only really
87+
diff --cc net/rxrpc/conn_object.c
88+
index 156bd26daf74,2bd3f6288895..000000000000
89+
--- a/net/rxrpc/conn_object.c
90+
+++ b/net/rxrpc/conn_object.c
91+
@@@ -210,50 -184,25 +213,60 @@@ void rxrpc_disconnect_call(struct rxrpc
92+
call->peer->cong_ssthresh = call->cong_ssthresh;
93+
94+
if (!hlist_unhashed(&call->error_link)) {
95+
- spin_lock(&call->peer->lock);
96+
- hlist_del_init(&call->error_link);
97+
- spin_unlock(&call->peer->lock);
98+
+ spin_lock_bh(&call->peer->lock);
99+
+ hlist_del_rcu(&call->error_link);
100+
+ spin_unlock_bh(&call->peer->lock);
101+
}
102+
103+
- if (rxrpc_is_client_call(call))
104+
- return rxrpc_disconnect_client_call(conn->bundle, call);
105+
+ if (rxrpc_is_client_call(call)) {
106+
+ rxrpc_disconnect_client_call(conn->bundle, call);
107+
+ } else {
108+
+ spin_lock(&conn->bundle->channel_lock);
109+
+ __rxrpc_disconnect_call(conn, call);
110+
+ spin_unlock(&conn->bundle->channel_lock);
111+
112+
- spin_lock(&conn->bundle->channel_lock);
113+
- __rxrpc_disconnect_call(conn, call);
114+
- spin_unlock(&conn->bundle->channel_lock);
115+
+ conn->idle_timestamp = jiffies;
116+
+ if (atomic_dec_and_test(&conn->active))
117+
+ rxrpc_set_service_reap_timer(conn->rxnet,
118+
+ jiffies + rxrpc_connection_expiry);
119+
+ }
120+
121+
++<<<<<<< HEAD
122+
+ set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
123+
+ conn->idle_timestamp = jiffies;
124+
+}
125+
+
126+
+/*
127+
+ * Kill off a connection.
128+
+ */
129+
+void rxrpc_kill_connection(struct rxrpc_connection *conn)
130+
+{
131+
+ struct rxrpc_net *rxnet = conn->params.local->rxnet;
132+
+
133+
+ ASSERT(!rcu_access_pointer(conn->channels[0].call) &&
134+
+ !rcu_access_pointer(conn->channels[1].call) &&
135+
+ !rcu_access_pointer(conn->channels[2].call) &&
136+
+ !rcu_access_pointer(conn->channels[3].call));
137+
+ ASSERT(list_empty(&conn->cache_link));
138+
+
139+
+ write_lock(&rxnet->conn_lock);
140+
+ list_del_init(&conn->proc_link);
141+
+ write_unlock(&rxnet->conn_lock);
142+
+
143+
+ /* Drain the Rx queue. Note that even though we've unpublished, an
144+
+ * incoming packet could still be being added to our Rx queue, so we
145+
+ * will need to drain it again in the RCU cleanup handler.
146+
+ */
147+
+ rxrpc_purge_queue(&conn->rx_queue);
148+
+
149+
+ /* Leave final destruction to RCU. The connection processor work item
150+
+ * must carry a ref on the connection to prevent us getting here whilst
151+
+ * it is queued or running.
152+
+ */
153+
+ call_rcu(&conn->rcu, rxrpc_destroy_connection);
154+
++=======
155+
+ rxrpc_put_call(call, rxrpc_call_put_io_thread);
156+
++>>>>>>> 5040011d073d (rxrpc: Make the local endpoint hold a ref on a connected call)
157+
}
158+
159+
/*
160+
* Unmerged path include/trace/events/rxrpc.h
161+
* Unmerged path net/rxrpc/call_object.c
162+
diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
163+
index 827c1308297c..0576723401c8 100644
164+
--- a/net/rxrpc/conn_client.c
165+
+++ b/net/rxrpc/conn_client.c
166+
@@ -714,8 +714,11 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
167+
168+
rxrpc_discard_expired_client_conns(&rxnet->client_conn_reaper);
169+
170+
+ rxrpc_get_call(call, rxrpc_call_get_io_thread);
171+
+
172+
bundle = rxrpc_prep_call(rx, call, cp, srx, gfp);
173+
if (IS_ERR(bundle)) {
174+
+ rxrpc_put_call(call, rxrpc_call_get_io_thread);
175+
ret = PTR_ERR(bundle);
176+
goto out;
177+
}
178+
@@ -805,7 +808,6 @@ void rxrpc_disconnect_client_call(struct rxrpc_bundle *bundle, struct rxrpc_call
179+
_enter("c=%x", call->debug_id);
180+
181+
spin_lock(&bundle->channel_lock);
182+
- set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
183+
184+
/* Calls that have never actually been assigned a channel can simply be
185+
* discarded.
186+
@@ -897,8 +899,6 @@ void rxrpc_disconnect_client_call(struct rxrpc_bundle *bundle, struct rxrpc_call
187+
188+
out:
189+
spin_unlock(&bundle->channel_lock);
190+
- _leave("");
191+
- return;
192+
}
193+
194+
/*
195+
* Unmerged path net/rxrpc/conn_object.c

0 commit comments

Comments
 (0)