linux/net/rxrpc
David Howells 816c9fce12 rxrpc: Fix handling of the last packet in rxrpc_recvmsg_data()
The code for determining the last packet in rxrpc_recvmsg_data() has been
using the RXRPC_CALL_RX_LAST flag to determine if the rx_top pointer points
to the last packet or not.  This isn't a good idea, however, as the input
code may be running simultaneously on another CPU and that sets the flag
*before* updating the top pointer.

Fix this by the following means:

 (1) Restrict the use of RXRPC_CALL_RX_LAST to the input routines only.
     There's otherwise a synchronisation problem between detecting the flag
     and checking tx_top.  This could probably be dealt with by appropriate
     application of memory barriers, but there's a simpler way.

 (2) Set RXRPC_CALL_RX_LAST after setting rx_top.

 (3) Make rxrpc_rotate_rx_window() consult the flags header field of the
     DATA packet it's about to discard to see if that was the last packet.
     Use this as the basis for ending the Rx phase.  This shouldn't be a
     problem because the recvmsg side of things is guaranteed to see the
     packets in order.

 (4) Make rxrpc_recvmsg_data() return 1 to indicate the end of the data if:

     (a) the packet it has just processed is marked as RXRPC_LAST_PACKET

     (b) the call's Rx phase has been ended.

Signed-off-by: David Howells <dhowells@redhat.com>
2016-09-17 10:51:54 +01:00
..
af_rxrpc.c rxrpc: Make IPv6 support conditional on CONFIG_IPV6 2016-09-17 03:58:45 -04:00
ar-internal.h rxrpc: Correctly initialise, limit and transmit call->rx_winsize 2016-09-13 22:38:45 +01:00
call_accept.c rxrpc: Fix prealloc refcounting 2016-09-13 22:38:37 +01:00
call_event.c rxrpc: Remove some whitespace. 2016-09-17 10:50:15 +01:00
call_object.c rxrpc: Correctly initialise, limit and transmit call->rx_winsize 2016-09-13 22:38:45 +01:00
conn_client.c rxrpc: Cache the security index in the rxrpc_call struct 2016-09-07 15:30:22 +01:00
conn_event.c rxrpc: Rewrite the data and ack handling code 2016-09-08 11:10:12 +01:00
conn_object.c rxrpc: Make IPv6 support conditional on CONFIG_IPV6 2016-09-17 03:58:45 -04:00
conn_service.c rxrpc: Rewrite the data and ack handling code 2016-09-08 11:10:12 +01:00
input.c rxrpc: Fix handling of the last packet in rxrpc_recvmsg_data() 2016-09-17 10:51:54 +01:00
insecure.c rxrpc: Rewrite the data and ack handling code 2016-09-08 11:10:12 +01:00
Kconfig rxrpc: Make IPv6 support conditional on CONFIG_IPV6 2016-09-17 03:58:45 -04:00
key.c rxrpc: Use structs to hold connection params and protocol info 2016-06-22 09:09:59 +01:00
local_event.c rxrpc: Use rxrpc_extract_addr_from_skb() rather than doing this manually 2016-09-13 23:09:13 +01:00
local_object.c rxrpc: Make IPv6 support conditional on CONFIG_IPV6 2016-09-17 03:58:45 -04:00
Makefile rxrpc: Split sendmsg from packet transmission code 2016-09-04 21:41:39 +01:00
misc.c rxrpc: Correctly initialise, limit and transmit call->rx_winsize 2016-09-13 22:38:45 +01:00
output.c rxrpc: Make IPv6 support conditional on CONFIG_IPV6 2016-09-17 03:58:45 -04:00
peer_event.c rxrpc: Make IPv6 support conditional on CONFIG_IPV6 2016-09-17 03:58:45 -04:00
peer_object.c rxrpc: Make IPv6 support conditional on CONFIG_IPV6 2016-09-17 03:58:45 -04:00
proc.c rxrpc: Add IPv6 support 2016-09-13 23:09:13 +01:00
recvmsg.c rxrpc: Fix handling of the last packet in rxrpc_recvmsg_data() 2016-09-17 10:51:54 +01:00
rxkad.c rxrpc: Rewrite the data and ack handling code 2016-09-08 11:10:12 +01:00
security.c rxrpc: Rewrite the data and ack handling code 2016-09-08 11:10:12 +01:00
sendmsg.c rxrpc: Rewrite the data and ack handling code 2016-09-08 11:10:12 +01:00
skbuff.c rxrpc: Rewrite the data and ack handling code 2016-09-08 11:10:12 +01:00
sysctl.c rxrpc: Correctly initialise, limit and transmit call->rx_winsize 2016-09-13 22:38:45 +01:00
utils.c rxrpc: Make IPv6 support conditional on CONFIG_IPV6 2016-09-17 03:58:45 -04:00