Clear MAL descriptor rings with explicit field stores instead of
memset(). The descriptor rings are carved from MAL coherent DMA memory,
which may be mapped uncached on 32-bit powerpc. The optimized memset()
path can use dcbz there and trigger an alignment warning.
Use WRITE_ONCE() for each field to prevent the compiler from merging
the stores back into a memset() call.
The skb tracking arrays remain ordinary CPU memory and still use memset().
Assisted-by: Codex:GPT-5.5
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
v2: Use WRITE_ONCE
drivers/net/ethernet/ibm/emac/core.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index d2194b406c9e..b7568d96aa47 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -1162,6 +1162,17 @@ static void emac_clean_rx_ring(struct emac_instance *dev)
}
}
+static void emac_clear_mal_desc(struct mal_descriptor *desc, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ WRITE_ONCE(desc[i].ctrl, 0);
+ WRITE_ONCE(desc[i].data_len, 0);
+ WRITE_ONCE(desc[i].data_ptr, 0);
+ }
+}
+
static int
__emac_prepare_rx_skb(struct sk_buff *skb, struct emac_instance *dev, int slot)
{
@@ -3089,8 +3100,8 @@ static int emac_probe(struct platform_device *ofdev)
DBG(dev, "rx_desc %p" NL, dev->rx_desc);
/* Clean rings */
- memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor));
- memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor));
+ emac_clear_mal_desc(dev->tx_desc, NUM_TX_BUFF);
+ emac_clear_mal_desc(dev->rx_desc, NUM_RX_BUFF);
memset(dev->tx_skb, 0, NUM_TX_BUFF * sizeof(struct sk_buff *));
memset(dev->rx_skb, 0, NUM_RX_BUFF * sizeof(struct sk_buff *));
--
2.54.0