[PATCHv2 net-next] net: ibm: emac: Clear MAL descriptors without memset

Rosen Penev posted 1 patch 4 days, 10 hours ago
There is a newer version of this series
drivers/net/ethernet/ibm/emac/core.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
[PATCHv2 net-next] net: ibm: emac: Clear MAL descriptors without memset
Posted by Rosen Penev 4 days, 10 hours ago
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