History

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.

Esben Haabendal committed 5 years ago

Commit 28d9fab1 parent 6aa32211 file · +13 −1Browse files

Unified · Split

drivers/net/ethernet/xilinx/ll_temac_main.c+13−1
@@ -774,12 +774,15 @@ static void temac_start_xmit_done(struct net_device *ndev) · 773 unmodified lines
774 stat = be32_to_cpu(cur_p->app0);774 stat = be32_to_cpu(cur_p->app0);
775 775
776 while (stat & STS_CTRL_APP0_CMPLT) {776 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();
777 dma_unmap_single(ndev->dev.parent, be32_to_cpu(cur_p->phys),781 dma_unmap_single(ndev->dev.parent, be32_to_cpu(cur_p->phys),
778 be32_to_cpu(cur_p->len), DMA_TO_DEVICE);782 be32_to_cpu(cur_p->len), DMA_TO_DEVICE);
779 skb = (struct sk_buff *)ptr_from_txbd(cur_p);783 skb = (struct sk_buff *)ptr_from_txbd(cur_p);
780 if (skb)784 if (skb)
781 dev_consume_skb_irq(skb);785 dev_consume_skb_irq(skb);
782 cur_p->app0 = 0;
783 cur_p->app1 = 0;786 cur_p->app1 = 0;
784 cur_p->app2 = 0;787 cur_p->app2 = 0;
785 cur_p->app3 = 0;788 cur_p->app3 = 0;
@@ -788,6 +791,12 @@ static void temac_start_xmit_done(struct net_device *ndev) · 2 unmodified lines
788 ndev->stats.tx_packets++;791 ndev->stats.tx_packets++;
789 ndev->stats.tx_bytes += be32_to_cpu(cur_p->len);792 ndev->stats.tx_bytes += be32_to_cpu(cur_p->len);
790 793
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
791 lp->tx_bd_ci++;800 lp->tx_bd_ci++;
792 if (lp->tx_bd_ci >= lp->tx_bd_num)801 if (lp->tx_bd_ci >= lp->tx_bd_num)
793 lp->tx_bd_ci = 0;802 lp->tx_bd_ci = 0;
@@ -814,6 +823,9 @@ static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag) · 20 unmodified lines
814 if (cur_p->app0)823 if (cur_p->app0)
815 return NETDEV_TX_BUSY;824 return NETDEV_TX_BUSY;
816 825
826 /* Make sure to read next bd app0 after this one */
827 rmb();
828
817 tail++;829 tail++;
818 if (tail >= lp->tx_bd_num)830 if (tail >= lp->tx_bd_num)
819 tail = 0;831 tail = 0;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t