net: nps_enet: Tx handler synchronization
Below is a description of a possible problematic
sequence. CPU-A is sending a frame and CPU-B handles
the interrupt that indicates the frame was sent. CPU-B
reads an invalid value of tx_packet_sent.
	CPU-A				CPU-B
	-----				-----
	nps_enet_send_frame
	.
	.
	tx_skb = skb
	tx_packet_sent = true
	order HW to start tx
	.
	.
	HW complete tx
			    ------> 	get tx complete interrupt
					.
					.
					if(tx_packet_sent == true)
						handle tx_skb
	end memory transaction
	(tx_packet_sent actually
	 written)
Furthermore there is a dependency between tx_skb and tx_packet_sent.
There is no assurance that tx_skb contains a valid pointer at CPU B
when it sees tx_packet_sent == true.
Solution:
Initialize tx_skb to NULL and use it to indicate that packet was sent,
in this way tx_packet_sent can be removed.
Add a write memory barrier after setting tx_skb in order to make sure
that it is valid before HW is informed and IRQ is fired.
Fixed sequence will be:
       CPU-A                           CPU-B
       -----                           -----
	tx_skb = skb
	wmb()
	.
	.
	order HW to start tx
	.
	.
	HW complete tx
			------>		get tx complete interrupt
					.
					.
					if(tx_skb != NULL)
						handle tx_skb
					tx_skb = NULL
Signed-off-by: 
Elad Kanfi <eladkan@mellanox.com>
Acked-by: 
Noam Camus <noamca@mellanox.com>
Acked-by: 
Gilad Ben-Yossef <giladby@mellanox.com>
Signed-off-by: 
David S. Miller <davem@davemloft.net>
Loading
Please register or sign in to comment