[PATCH] net: moxa: fix TX overrun memory leak

Subsystems: networking drivers, the rest

STALE4073d

2 messages, 2 authors, 2015-06-08 · open the first message on its own page

[PATCH] net: moxa: fix TX overrun memory leak

From: Jonas Jensen <hidden>
Date: 2015-06-05 13:46:36

moxart_mac_start_xmit() doesn't care where tx_tail is, tx_head can
catch and pass tx_tail, which is bad because moxart_tx_finished()
isn't guaranteed to catch up on freeing resources from tx_tail.

Add a check in moxart_mac_start_xmit(), exit to make sure tx_head
never passes tx_tail.

Move tx_head and place tx_tail within spinlock, avoiding read-write
race that could happen when interrupts hit at the wrong moment.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=99451

Signed-off-by: Jonas Jensen <redacted>
---

Notes:
    Applies to next-20150604

 drivers/net/ethernet/moxa/moxart_ether.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index becbb5f..e0af86c 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -25,6 +25,7 @@
 #include <linux/of_irq.h>
 #include <linux/crc32.h>
 #include <linux/crc32c.h>
+#include <linux/circ_buf.h>
 
 #include "moxart_ether.h"
 
@@ -312,13 +313,22 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
 	void __iomem *desc;
 	unsigned int len;
-	unsigned int tx_head = priv->tx_head;
+	unsigned int tx_head, tx_tail;
 	u32 txdes1;
 	int ret = NETDEV_TX_BUSY;
 
+	spin_lock_irq(&priv->txlock);
+
+	tx_head = priv->tx_head;
+	tx_tail = priv->tx_tail;
+
 	desc = priv->tx_desc_base + (TX_REG_DESC_SIZE * tx_head);
 
-	spin_lock_irq(&priv->txlock);
+	if (CIRC_SPACE(tx_head, tx_tail, TX_DESC_NUM) == 0) {
+		priv->stats.tx_dropped++;
+		goto out_unlock;
+	}
+
 	if (readl(desc + TX_REG_OFFSET_DESC0) & TX_DESC0_DMA_OWN) {
 		net_dbg_ratelimited("no TX space for packet\n");
 		priv->stats.tx_dropped++;
-- 
1.8.2.1

Re: [PATCH] net: moxa: fix TX overrun memory leak

From: David Miller <davem@davemloft.net>
Date: 2015-06-08 02:22:10

From: Jonas Jensen <redacted>
Date: Fri,  5 Jun 2015 15:46:18 +0200
 	desc = priv->tx_desc_base + (TX_REG_DESC_SIZE * tx_head);
 
-	spin_lock_irq(&priv->txlock);
+	if (CIRC_SPACE(tx_head, tx_tail, TX_DESC_NUM) == 0) {
+		priv->stats.tx_dropped++;
+		goto out_unlock;
+	}
You can't do this.

Whatever code creates this condition _must_ stop the TX queue
so that the core netdevice transmit layer does not call your
transmit method.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help