Skip to content

Commit 28d9fab

Browse files
esbendavem330
authored andcommitted
net: ll_temac: Add memory-barriers for TX BD access
Add a couple of memory-barriers to ensure correct ordering of read/write access to TX BDs. In xmit_done, we should ensure that reading the additional BD fields are only done after STS_CTRL_APP0_CMPLT bit is set. When xmit_done marks the BD as free by setting APP0=0, we need to ensure that the other BD fields are reset first, so we avoid racing with the xmit path, which writes to the same fields. Finally, making sure to read APP0 of next BD after the current BD, ensures that we see all available buffers. Signed-off-by: Esben Haabendal <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6aa3221 commit 28d9fab

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

drivers/net/ethernet/xilinx/ll_temac_main.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,12 +774,15 @@ static void temac_start_xmit_done(struct net_device *ndev)
774774
stat = be32_to_cpu(cur_p->app0);
775775

776776
while (stat & STS_CTRL_APP0_CMPLT) {
777+
/* Make sure that the other fields are read after bd is
778+
* released by dma
779+
*/
780+
rmb();
777781
dma_unmap_single(ndev->dev.parent, be32_to_cpu(cur_p->phys),
778782
be32_to_cpu(cur_p->len), DMA_TO_DEVICE);
779783
skb = (struct sk_buff *)ptr_from_txbd(cur_p);
780784
if (skb)
781785
dev_consume_skb_irq(skb);
782-
cur_p->app0 = 0;
783786
cur_p->app1 = 0;
784787
cur_p->app2 = 0;
785788
cur_p->app3 = 0;
@@ -788,6 +791,12 @@ static void temac_start_xmit_done(struct net_device *ndev)
788791
ndev->stats.tx_packets++;
789792
ndev->stats.tx_bytes += be32_to_cpu(cur_p->len);
790793

794+
/* app0 must be visible last, as it is used to flag
795+
* availability of the bd
796+
*/
797+
smp_mb();
798+
cur_p->app0 = 0;
799+
791800
lp->tx_bd_ci++;
792801
if (lp->tx_bd_ci >= lp->tx_bd_num)
793802
lp->tx_bd_ci = 0;
@@ -814,6 +823,9 @@ static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag)
814823
if (cur_p->app0)
815824
return NETDEV_TX_BUSY;
816825

826+
/* Make sure to read next bd app0 after this one */
827+
rmb();
828+
817829
tail++;
818830
if (tail >= lp->tx_bd_num)
819831
tail = 0;

0 commit comments

Comments
 (0)