rxrpc: Call state should be read with READ_ONCE() under some circumstances
The call state may be changed at any time by the data-ready routine in response to received packets, so if the call state is to be read and acted upon several times in a function, READ_ONCE() must be used unless the call state lock is held. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
02b2faaf0a
commit
146d8fef9d
@@ -420,6 +420,7 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb,
|
||||
u16 skew)
|
||||
{
|
||||
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
||||
enum rxrpc_call_state state;
|
||||
unsigned int offset = sizeof(struct rxrpc_wire_header);
|
||||
unsigned int ix;
|
||||
rxrpc_serial_t serial = sp->hdr.serial, ack_serial = 0;
|
||||
@@ -434,14 +435,15 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb,
|
||||
_proto("Rx DATA %%%u { #%u f=%02x }",
|
||||
sp->hdr.serial, seq, sp->hdr.flags);
|
||||
|
||||
if (call->state >= RXRPC_CALL_COMPLETE)
|
||||
state = READ_ONCE(call->state);
|
||||
if (state >= RXRPC_CALL_COMPLETE)
|
||||
return;
|
||||
|
||||
/* Received data implicitly ACKs all of the request packets we sent
|
||||
* when we're acting as a client.
|
||||
*/
|
||||
if ((call->state == RXRPC_CALL_CLIENT_SEND_REQUEST ||
|
||||
call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY) &&
|
||||
if ((state == RXRPC_CALL_CLIENT_SEND_REQUEST ||
|
||||
state == RXRPC_CALL_CLIENT_AWAIT_REPLY) &&
|
||||
!rxrpc_receiving_reply(call))
|
||||
return;
|
||||
|
||||
@@ -799,7 +801,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
|
||||
return rxrpc_proto_abort("AK0", call, 0);
|
||||
|
||||
/* Ignore ACKs unless we are or have just been transmitting. */
|
||||
switch (call->state) {
|
||||
switch (READ_ONCE(call->state)) {
|
||||
case RXRPC_CALL_CLIENT_SEND_REQUEST:
|
||||
case RXRPC_CALL_CLIENT_AWAIT_REPLY:
|
||||
case RXRPC_CALL_SERVER_SEND_REPLY:
|
||||
@@ -940,7 +942,7 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call,
|
||||
static void rxrpc_input_implicit_end_call(struct rxrpc_connection *conn,
|
||||
struct rxrpc_call *call)
|
||||
{
|
||||
switch (call->state) {
|
||||
switch (READ_ONCE(call->state)) {
|
||||
case RXRPC_CALL_SERVER_AWAIT_ACK:
|
||||
rxrpc_call_completed(call);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user