[PATCH 03/10] net: emac: use DMA-specific and SMP memory barriers
From: Rosen Penev
Date: Tue Jun 30 2026 - 00:18:02 EST
Replace generic wmb()/mb() barriers with more specific variants:
- dma_wmb() for ordering descriptor field writes before hardware
ownership bit (ctrl) hand-off in TX/RX paths
- dma_rmb() for ordering descriptor ctrl read after ownership
observation in the RX poll path
- smp_wmb() for CPU-to-CPU ordering (link_polling flag,
platform_set_drvdata visibility)
- dma_rmb() for the RX descriptor ownership transfer read
Assisted-by: opencode:big-pickle
Signed-off-by: Rosen Penev <rosenp@xxxxxxxxx>
---
drivers/net/ethernet/ibm/emac/core.c | 16 ++++++++--------
drivers/net/ethernet/ibm/emac/mal.c | 2 +-
drivers/net/ethernet/ibm/emac/rgmii.c | 2 +-
drivers/net/ethernet/ibm/emac/tah.c | 2 +-
drivers/net/ethernet/ibm/emac/zmii.c | 4 ++--
5 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index 1d46cf6c2c12..5e7b85d28bde 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -1185,7 +1185,7 @@ __emac_prepare_rx_skb(struct sk_buff *skb, struct emac_instance *dev, int slot)
dev->rx_desc[slot].data_ptr =
dma_map_single(&dev->ofdev->dev, skb->data - NET_IP_ALIGN,
dev->rx_sync_size, DMA_FROM_DEVICE) + NET_IP_ALIGN;
- wmb();
+ dma_wmb();
dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
(slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
@@ -1263,7 +1263,7 @@ static int emac_open(struct net_device *ndev)
link_poll_interval = PHY_POLL_LINK_OFF;
}
dev->link_polling = 1;
- wmb();
+ smp_wmb();
schedule_delayed_work(&dev->link_work, link_poll_interval);
emac_print_link_status(dev);
} else
@@ -1464,7 +1464,7 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
skb->data, len,
DMA_TO_DEVICE);
dev->tx_desc[slot].data_len = (u16) len;
- wmb();
+ dma_wmb();
dev->tx_desc[slot].ctrl = ctrl;
return emac_xmit_finish(dev, len);
@@ -1560,7 +1560,7 @@ emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev)
/* Send the packet out */
if (dev->tx_slot == NUM_TX_BUFF - 1)
ctrl |= MAL_TX_CTRL_WRAP;
- wmb();
+ dma_wmb();
dev->tx_desc[dev->tx_slot].ctrl = ctrl;
dev->tx_slot = (slot + 1) % NUM_TX_BUFF;
@@ -1671,7 +1671,7 @@ static inline void emac_recycle_rx_skb(struct emac_instance *dev, int slot,
DMA_FROM_DEVICE);
dev->rx_desc[slot].data_len = 0;
- wmb();
+ dma_wmb();
dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
(slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
}
@@ -1754,7 +1754,7 @@ static int emac_poll_rx(void *param, int budget)
break;
skb = dev->rx_skb[slot];
- mb();
+ dma_rmb();
len = dev->rx_desc[slot].data_len;
if (unlikely(!MAL_IS_SINGLE_RX(ctrl)))
@@ -1845,7 +1845,7 @@ static int emac_poll_rx(void *param, int budget)
}
if (unlikely(budget && test_bit(MAL_COMMAC_RX_STOPPED, &dev->commac.flags))) {
- mb();
+ dma_rmb();
if (!(dev->rx_desc[slot].ctrl & MAL_RX_CTRL_EMPTY)) {
DBG2(dev, "rx restart" NL);
received = 0;
@@ -3167,7 +3167,7 @@ static int emac_probe(struct platform_device *ofdev)
/* Set our drvdata last as we don't want them visible until we are
* fully initialized
*/
- wmb();
+ smp_wmb();
platform_set_drvdata(ofdev, dev);
printk(KERN_INFO "%s: EMAC-%d %pOF, MAC %pM\n",
diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c
index 4025bc36ae16..99615c8a6c3e 100644
--- a/drivers/net/ethernet/ibm/emac/mal.c
+++ b/drivers/net/ethernet/ibm/emac/mal.c
@@ -691,7 +691,7 @@ static int mal_probe(struct platform_device *ofdev)
mal->num_tx_chans, mal->num_rx_chans);
/* Advertise this instance to the rest of the world */
- wmb();
+ smp_wmb();
platform_set_drvdata(ofdev, mal);
return 0;
diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c b/drivers/net/ethernet/ibm/emac/rgmii.c
index b544dd8633b7..093aa4f129e3 100644
--- a/drivers/net/ethernet/ibm/emac/rgmii.c
+++ b/drivers/net/ethernet/ibm/emac/rgmii.c
@@ -255,7 +255,7 @@ static int rgmii_probe(struct platform_device *ofdev)
ofdev->dev.of_node,
(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out");
- wmb();
+ smp_wmb();
platform_set_drvdata(ofdev, dev);
return 0;
diff --git a/drivers/net/ethernet/ibm/emac/tah.c b/drivers/net/ethernet/ibm/emac/tah.c
index ed07532aaf85..077da56fa449 100644
--- a/drivers/net/ethernet/ibm/emac/tah.c
+++ b/drivers/net/ethernet/ibm/emac/tah.c
@@ -112,7 +112,7 @@ static int tah_probe(struct platform_device *ofdev)
tah_reset(ofdev);
printk(KERN_INFO "TAH %pOF initialized\n", ofdev->dev.of_node);
- wmb();
+ smp_wmb();
return 0;
}
diff --git a/drivers/net/ethernet/ibm/emac/zmii.c b/drivers/net/ethernet/ibm/emac/zmii.c
index a3839cf02ec4..5144ee94a7d2 100644
--- a/drivers/net/ethernet/ibm/emac/zmii.c
+++ b/drivers/net/ethernet/ibm/emac/zmii.c
@@ -258,8 +258,8 @@ static int zmii_probe(struct platform_device *ofdev)
/* Disable all inputs by default */
out_be32(&dev->base->fer, 0);
- printk(KERN_INFO "ZMII %pOF initialized\n", ofdev->dev.of_node);
- wmb();
+ dev_info(&ofdev->dev, "ZMII initialized\n");
+ smp_wmb();
platform_set_drvdata(ofdev, dev);
return 0;
--
2.54.0