Skip to content

Commit ba67555

Browse files
committed
rxrpc: Wrap accesses to get call state to put the barrier in one place
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 d41b3f5 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/d41b3f5b.failed Wrap accesses to get the state of a call from outside of the I/O thread in a single place so that the barrier needed to order wrt the error code and abort code is in just that place. Also use a barrier when setting the call state and again when reading the call state such that the auxiliary completion info (error code, abort code) can be read without taking a read lock on the call state lock. 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 d41b3f5) Signed-off-by: Jonathan Maple <jmaple@ciq.com> # Conflicts: # net/rxrpc/ar-internal.h # net/rxrpc/call_state.c # net/rxrpc/sendmsg.c
1 parent 686c1a0 commit ba67555

File tree

1 file changed

+221
-0
lines changed

1 file changed

+221
-0
lines changed
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
rxrpc: Wrap accesses to get call state to put the barrier in one place
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 d41b3f5b96881809c73f86e3ca436c9426610b7a
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/d41b3f5b.failed
10+
11+
Wrap accesses to get the state of a call from outside of the I/O thread in
12+
a single place so that the barrier needed to order wrt the error code and
13+
abort code is in just that place.
14+
15+
Also use a barrier when setting the call state and again when reading the
16+
call state such that the auxiliary completion info (error code, abort code)
17+
can be read without taking a read lock on the call state lock.
18+
19+
Signed-off-by: David Howells <dhowells@redhat.com>
20+
cc: Marc Dionne <marc.dionne@auristor.com>
21+
cc: linux-afs@lists.infradead.org
22+
(cherry picked from commit d41b3f5b96881809c73f86e3ca436c9426610b7a)
23+
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
24+
25+
# Conflicts:
26+
# net/rxrpc/ar-internal.h
27+
# net/rxrpc/call_state.c
28+
# net/rxrpc/sendmsg.c
29+
diff --cc net/rxrpc/ar-internal.h
30+
index 46ce41afb431,9e992487649c..000000000000
31+
--- a/net/rxrpc/ar-internal.h
32+
+++ b/net/rxrpc/ar-internal.h
33+
@@@ -855,6 -886,40 +855,43 @@@ static inline bool rxrpc_is_client_call
34+
}
35+
36+
/*
37+
++<<<<<<< HEAD
38+
++=======
39+
+ * call_state.c
40+
+ */
41+
+ bool __rxrpc_set_call_completion(struct rxrpc_call *call,
42+
+ enum rxrpc_call_completion compl,
43+
+ u32 abort_code,
44+
+ int error);
45+
+ bool rxrpc_set_call_completion(struct rxrpc_call *call,
46+
+ enum rxrpc_call_completion compl,
47+
+ u32 abort_code,
48+
+ int error);
49+
+ bool __rxrpc_call_completed(struct rxrpc_call *call);
50+
+ bool rxrpc_call_completed(struct rxrpc_call *call);
51+
+ bool __rxrpc_abort_call(struct rxrpc_call *call, rxrpc_seq_t seq,
52+
+ u32 abort_code, int error, enum rxrpc_abort_reason why);
53+
+ bool rxrpc_abort_call(struct rxrpc_call *call, rxrpc_seq_t seq,
54+
+ u32 abort_code, int error, enum rxrpc_abort_reason why);
55+
+
56+
+ static inline enum rxrpc_call_state rxrpc_call_state(const struct rxrpc_call *call)
57+
+ {
58+
+ /* Order read ->state before read ->error. */
59+
+ return smp_load_acquire(&call->state);
60+
+ }
61+
+
62+
+ static inline bool rxrpc_call_is_complete(const struct rxrpc_call *call)
63+
+ {
64+
+ return rxrpc_call_state(call) == RXRPC_CALL_COMPLETE;
65+
+ }
66+
+
67+
+ static inline bool rxrpc_call_has_failed(const struct rxrpc_call *call)
68+
+ {
69+
+ return rxrpc_call_is_complete(call) && call->completion != RXRPC_CALL_SUCCEEDED;
70+
+ }
71+
+
72+
+ /*
73+
++>>>>>>> d41b3f5b9688 (rxrpc: Wrap accesses to get call state to put the barrier in one place)
74+
* conn_client.c
75+
*/
76+
extern unsigned int rxrpc_reap_client_connections;
77+
diff --cc net/rxrpc/sendmsg.c
78+
index 45c09f0de6fe,f0b5822f3e04..000000000000
79+
--- a/net/rxrpc/sendmsg.c
80+
+++ b/net/rxrpc/sendmsg.c
81+
@@@ -18,6 -18,27 +18,30 @@@
82+
#include "ar-internal.h"
83+
84+
/*
85+
++<<<<<<< HEAD
86+
++=======
87+
+ * Propose an abort to be made in the I/O thread.
88+
+ */
89+
+ bool rxrpc_propose_abort(struct rxrpc_call *call, s32 abort_code, int error,
90+
+ enum rxrpc_abort_reason why)
91+
+ {
92+
+ _enter("{%d},%d,%d,%u", call->debug_id, abort_code, error, why);
93+
+
94+
+ if (!call->send_abort && !rxrpc_call_is_complete(call)) {
95+
+ call->send_abort_why = why;
96+
+ call->send_abort_err = error;
97+
+ call->send_abort_seq = 0;
98+
+ /* Request abort locklessly vs rxrpc_input_call_event(). */
99+
+ smp_store_release(&call->send_abort, abort_code);
100+
+ rxrpc_poke_call(call, rxrpc_call_poke_abort);
101+
+ return true;
102+
+ }
103+
+
104+
+ return false;
105+
+ }
106+
+
107+
+ /*
108+
++>>>>>>> d41b3f5b9688 (rxrpc: Wrap accesses to get call state to put the barrier in one place)
109+
* Return true if there's sufficient Tx queue space.
110+
*/
111+
static bool rxrpc_check_tx_space(struct rxrpc_call *call, rxrpc_seq_t *_tx_win)
112+
@@@ -134,14 -124,9 +158,14 @@@ static int rxrpc_wait_for_tx_window_non
113+
if (rxrpc_check_tx_space(call, NULL))
114+
return 0;
115+
116+
- if (call->state >= RXRPC_CALL_COMPLETE)
117+
+ if (rxrpc_call_is_complete(call))
118+
return call->error;
119+
120+
+ if (READ_ONCE(call->acks_hard_ack) != call->tx_bottom) {
121+
+ rxrpc_shrink_call_tx_buffer(call);
122+
+ continue;
123+
+ }
124+
+
125+
trace_rxrpc_txqueue(call, rxrpc_txqueue_wait);
126+
*timeo = schedule_timeout(*timeo);
127+
}
128+
@@@ -415,12 -375,9 +439,18 @@@ reload
129+
130+
success:
131+
ret = copied;
132+
++<<<<<<< HEAD
133+
+ if (READ_ONCE(call->state) == RXRPC_CALL_COMPLETE) {
134+
+ read_lock_bh(&call->state_lock);
135+
+ if (call->error < 0)
136+
+ ret = call->error;
137+
+ read_unlock_bh(&call->state_lock);
138+
+ }
139+
++=======
140+
+ if (rxrpc_call_is_complete(call) &&
141+
+ call->error < 0)
142+
+ ret = call->error;
143+
++>>>>>>> d41b3f5b9688 (rxrpc: Wrap accesses to get call state to put the barrier in one place)
144+
out:
145+
call->tx_pending = txb;
146+
_leave(" = %d", ret);
147+
* Unmerged path net/rxrpc/call_state.c
148+
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
149+
index 0f4d34f420f0..82fa2f7b90b4 100644
150+
--- a/net/rxrpc/af_rxrpc.c
151+
+++ b/net/rxrpc/af_rxrpc.c
152+
@@ -380,7 +380,7 @@ EXPORT_SYMBOL(rxrpc_kernel_end_call);
153+
bool rxrpc_kernel_check_life(const struct socket *sock,
154+
const struct rxrpc_call *call)
155+
{
156+
- return call->state != RXRPC_CALL_COMPLETE;
157+
+ return !rxrpc_call_is_complete(call);
158+
}
159+
EXPORT_SYMBOL(rxrpc_kernel_check_life);
160+
161+
* Unmerged path net/rxrpc/ar-internal.h
162+
* Unmerged path net/rxrpc/call_state.c
163+
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c
164+
index c84d2b620396..4a2a76b2aba4 100644
165+
--- a/net/rxrpc/recvmsg.c
166+
+++ b/net/rxrpc/recvmsg.c
167+
@@ -168,7 +168,7 @@ static int rxrpc_recvmsg_term(struct rxrpc_call *call, struct msghdr *msg)
168+
ret = put_cmsg(msg, SOL_RXRPC, RXRPC_LOCAL_ERROR, 4, &tmp);
169+
break;
170+
default:
171+
- pr_err("Invalid terminal call state %u\n", call->state);
172+
+ pr_err("Invalid terminal call state %u\n", call->completion);
173+
BUG();
174+
break;
175+
}
176+
@@ -190,7 +190,7 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call, rxrpc_serial_t serial)
177+
178+
trace_rxrpc_receive(call, rxrpc_receive_end, 0, whigh);
179+
180+
- if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY)
181+
+ if (rxrpc_call_state(call) == RXRPC_CALL_CLIENT_RECV_REPLY)
182+
rxrpc_propose_delay_ACK(call, serial, rxrpc_propose_ack_terminal_ack);
183+
184+
write_lock_bh(&call->state_lock);
185+
@@ -291,7 +291,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
186+
rx_pkt_offset = call->rx_pkt_offset;
187+
rx_pkt_len = call->rx_pkt_len;
188+
189+
- if (call->state >= RXRPC_CALL_SERVER_ACK_REQUEST) {
190+
+ if (rxrpc_call_state(call) >= RXRPC_CALL_SERVER_ACK_REQUEST) {
191+
seq = lower_32_bits(atomic64_read(&call->ackr_window)) - 1;
192+
ret = 1;
193+
goto done;
194+
@@ -498,7 +498,7 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
195+
msg->msg_namelen = len;
196+
}
197+
198+
- switch (READ_ONCE(call->state)) {
199+
+ switch (rxrpc_call_state(call)) {
200+
case RXRPC_CALL_CLIENT_RECV_REPLY:
201+
case RXRPC_CALL_SERVER_RECV_REQUEST:
202+
case RXRPC_CALL_SERVER_ACK_REQUEST:
203+
@@ -519,7 +519,7 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
204+
if (ret < 0)
205+
goto error_unlock_call;
206+
207+
- if (call->state == RXRPC_CALL_COMPLETE) {
208+
+ if (rxrpc_call_is_complete(call)) {
209+
ret = rxrpc_recvmsg_term(call, msg);
210+
if (ret < 0)
211+
goto error_unlock_call;
212+
@@ -599,7 +599,7 @@ int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call,
213+
214+
mutex_lock(&call->user_mutex);
215+
216+
- switch (READ_ONCE(call->state)) {
217+
+ switch (rxrpc_call_state(call)) {
218+
case RXRPC_CALL_CLIENT_RECV_REPLY:
219+
case RXRPC_CALL_SERVER_RECV_REQUEST:
220+
case RXRPC_CALL_SERVER_ACK_REQUEST:
221+
* Unmerged path net/rxrpc/sendmsg.c

0 commit comments

Comments
 (0)