diff options
author | Elad Kanfi <eladkan@mellanox.com> | 2016-05-09 20:13:19 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-10 22:04:49 +0300 |
commit | e5df49d564fe993c68f5cff6d96972a6358b4958 (patch) | |
tree | 899ce25dfc99e15b7454b845a894dabfd4e3d1dd /drivers/perf | |
parent | d99079e2fbd5ac38884f498ca99435d525152a88 (diff) | |
download | linux-e5df49d564fe993c68f5cff6d96972a6358b4958.tar.xz |
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>
Diffstat (limited to 'drivers/perf')
0 files changed, 0 insertions, 0 deletions