[PATCH] net/macb: move to circ_buf macros and fix initial condition

Subsystems: atmel macb ethernet driver, networking drivers, the rest

STALE5020d

4 messages, 3 authors, 2012-11-19 · open the first message on its own page

[PATCH] net/macb: move to circ_buf macros and fix initial condition

From: Nicolas Ferre <hidden>
Date: 2012-11-19 15:17:29

Move to circular buffers management macro and correct an error
with circular buffer initial condition.

Without this patch, the macb_tx_ring_avail() function was
not reporting the proper ring availability at startup:
macb macb: eth0: BUG! Tx Ring full when queue awake!
macb macb: eth0: tx_head = 0, tx_tail = 0
And hanginig forever...

I remove the macb_tx_ring_avail() function and use the
proven macros from circ_buf.h. CIRC_CNT() is used in the
"consumer" part of the driver: macb_tx_interrupt() to match
advice from Documentation/circular-buffers.txt.

Signed-off-by: Nicolas Ferre <redacted>
---
 drivers/net/ethernet/cadence/macb.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index edb2aba..27991dd 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -14,6 +14,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/circ_buf.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
@@ -38,8 +39,8 @@
 #define TX_RING_SIZE		128 /* must be power of 2 */
 #define TX_RING_BYTES		(sizeof(struct macb_dma_desc) * TX_RING_SIZE)
 
-/* minimum number of free TX descriptors before waking up TX process */
-#define MACB_TX_WAKEUP_THRESH	(TX_RING_SIZE / 4)
+/* level of occupied TX descriptors under which we wake up TX process */
+#define MACB_TX_WAKEUP_THRESH	(3 * TX_RING_SIZE / 4)
 
 #define MACB_RX_INT_FLAGS	(MACB_BIT(RCOMP) | MACB_BIT(RXUBR)	\
 				 | MACB_BIT(ISR_ROVR))
@@ -60,11 +61,6 @@ static unsigned int macb_tx_ring_wrap(unsigned int index)
 	return index & (TX_RING_SIZE - 1);
 }
 
-static unsigned int macb_tx_ring_avail(struct macb *bp)
-{
-	return (bp->tx_tail - bp->tx_head) & (TX_RING_SIZE - 1);
-}
-
 static struct macb_dma_desc *macb_tx_desc(struct macb *bp, unsigned int index)
 {
 	return &bp->tx_ring[macb_tx_ring_wrap(index)];
@@ -524,7 +520,8 @@ static void macb_tx_interrupt(struct macb *bp)
 
 	bp->tx_tail = tail;
 	if (netif_queue_stopped(bp->dev)
-			&& macb_tx_ring_avail(bp) > MACB_TX_WAKEUP_THRESH)
+			&& CIRC_CNT(bp->tx_head, bp->tx_tail,
+				    TX_RING_SIZE) <= MACB_TX_WAKEUP_THRESH)
 		netif_wake_queue(bp->dev);
 }
 
@@ -818,7 +815,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_lock_irqsave(&bp->lock, flags);
 
 	/* This is a hard error, log it. */
-	if (macb_tx_ring_avail(bp) < 1) {
+	if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1) {
 		netif_stop_queue(dev);
 		spin_unlock_irqrestore(&bp->lock, flags);
 		netdev_err(bp->dev, "BUG! Tx Ring full when queue awake!\n");
@@ -855,7 +852,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
 
-	if (macb_tx_ring_avail(bp) < 1)
+	if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1)
 		netif_stop_queue(dev);
 
 	spin_unlock_irqrestore(&bp->lock, flags);
-- 
1.8.0

[PATCH v2] net/macb: move to circ_buf macros and fix initial condition

From: Nicolas Ferre <hidden>
Date: 2012-11-19 16:00:25

Move to circular buffers management macro and correct an error
with circular buffer initial condition.

Without this patch, the macb_tx_ring_avail() function was
not reporting the proper ring availability at startup:
macb macb: eth0: BUG! Tx Ring full when queue awake!
macb macb: eth0: tx_head = 0, tx_tail = 0
And hanginig forever...

I remove the macb_tx_ring_avail() function and use the
proven macros from circ_buf.h. CIRC_CNT() is used in the
"consumer" part of the driver: macb_tx_interrupt() to match
advice from Documentation/circular-buffers.txt.

Reported-by: Jean-Christophe PLAGNIOL-VILLARD <redacted>
Signed-off-by: Nicolas Ferre <redacted>
Tested-by: Jean-Christophe PLAGNIOL-VILLARD <redacted>
---
v2: - added tags from Jean-Christophe PLAGNIOL-VILLARD

 drivers/net/ethernet/cadence/macb.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index edb2aba..27991dd 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -14,6 +14,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/circ_buf.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
@@ -38,8 +39,8 @@
 #define TX_RING_SIZE		128 /* must be power of 2 */
 #define TX_RING_BYTES		(sizeof(struct macb_dma_desc) * TX_RING_SIZE)
 
-/* minimum number of free TX descriptors before waking up TX process */
-#define MACB_TX_WAKEUP_THRESH	(TX_RING_SIZE / 4)
+/* level of occupied TX descriptors under which we wake up TX process */
+#define MACB_TX_WAKEUP_THRESH	(3 * TX_RING_SIZE / 4)
 
 #define MACB_RX_INT_FLAGS	(MACB_BIT(RCOMP) | MACB_BIT(RXUBR)	\
 				 | MACB_BIT(ISR_ROVR))
@@ -60,11 +61,6 @@ static unsigned int macb_tx_ring_wrap(unsigned int index)
 	return index & (TX_RING_SIZE - 1);
 }
 
-static unsigned int macb_tx_ring_avail(struct macb *bp)
-{
-	return (bp->tx_tail - bp->tx_head) & (TX_RING_SIZE - 1);
-}
-
 static struct macb_dma_desc *macb_tx_desc(struct macb *bp, unsigned int index)
 {
 	return &bp->tx_ring[macb_tx_ring_wrap(index)];
@@ -524,7 +520,8 @@ static void macb_tx_interrupt(struct macb *bp)
 
 	bp->tx_tail = tail;
 	if (netif_queue_stopped(bp->dev)
-			&& macb_tx_ring_avail(bp) > MACB_TX_WAKEUP_THRESH)
+			&& CIRC_CNT(bp->tx_head, bp->tx_tail,
+				    TX_RING_SIZE) <= MACB_TX_WAKEUP_THRESH)
 		netif_wake_queue(bp->dev);
 }
 
@@ -818,7 +815,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_lock_irqsave(&bp->lock, flags);
 
 	/* This is a hard error, log it. */
-	if (macb_tx_ring_avail(bp) < 1) {
+	if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1) {
 		netif_stop_queue(dev);
 		spin_unlock_irqrestore(&bp->lock, flags);
 		netdev_err(bp->dev, "BUG! Tx Ring full when queue awake!\n");
@@ -855,7 +852,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
 
-	if (macb_tx_ring_avail(bp) < 1)
+	if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1)
 		netif_stop_queue(dev);
 
 	spin_unlock_irqrestore(&bp->lock, flags);
-- 
1.8.0

Re: [PATCH] net/macb: move to circ_buf macros and fix initial condition

From: Jean-Christophe PLAGNIOL-VILLARD <hidden>
Date: 2012-11-19 16:00:56

On 16:17 Mon 19 Nov     , Nicolas Ferre wrote:
Move to circular buffers management macro and correct an error
with circular buffer initial condition.

Without this patch, the macb_tx_ring_avail() function was
not reporting the proper ring availability at startup:
macb macb: eth0: BUG! Tx Ring full when queue awake!
macb macb: eth0: tx_head = 0, tx_tail = 0
And hanginig forever...

I remove the macb_tx_ring_avail() function and use the
proven macros from circ_buf.h. CIRC_CNT() is used in the
"consumer" part of the driver: macb_tx_interrupt() to match
advice from Documentation/circular-buffers.txt.

Signed-off-by: Nicolas Ferre <redacted>
Just tested on 9260
Tested-by: Jean-Christophe PLAGNIOL-VILLARD <redacted>

Best Regards,
J.
quoted hunk
---
 drivers/net/ethernet/cadence/macb.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index edb2aba..27991dd 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -14,6 +14,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/circ_buf.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
@@ -38,8 +39,8 @@
 #define TX_RING_SIZE		128 /* must be power of 2 */
 #define TX_RING_BYTES		(sizeof(struct macb_dma_desc) * TX_RING_SIZE)
 
-/* minimum number of free TX descriptors before waking up TX process */
-#define MACB_TX_WAKEUP_THRESH	(TX_RING_SIZE / 4)
+/* level of occupied TX descriptors under which we wake up TX process */
+#define MACB_TX_WAKEUP_THRESH	(3 * TX_RING_SIZE / 4)
 
 #define MACB_RX_INT_FLAGS	(MACB_BIT(RCOMP) | MACB_BIT(RXUBR)	\
 				 | MACB_BIT(ISR_ROVR))
@@ -60,11 +61,6 @@ static unsigned int macb_tx_ring_wrap(unsigned int index)
 	return index & (TX_RING_SIZE - 1);
 }
 
-static unsigned int macb_tx_ring_avail(struct macb *bp)
-{
-	return (bp->tx_tail - bp->tx_head) & (TX_RING_SIZE - 1);
-}
-
 static struct macb_dma_desc *macb_tx_desc(struct macb *bp, unsigned int index)
 {
 	return &bp->tx_ring[macb_tx_ring_wrap(index)];
@@ -524,7 +520,8 @@ static void macb_tx_interrupt(struct macb *bp)
 
 	bp->tx_tail = tail;
 	if (netif_queue_stopped(bp->dev)
-			&& macb_tx_ring_avail(bp) > MACB_TX_WAKEUP_THRESH)
+			&& CIRC_CNT(bp->tx_head, bp->tx_tail,
+				    TX_RING_SIZE) <= MACB_TX_WAKEUP_THRESH)
 		netif_wake_queue(bp->dev);
 }
 
@@ -818,7 +815,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_lock_irqsave(&bp->lock, flags);
 
 	/* This is a hard error, log it. */
-	if (macb_tx_ring_avail(bp) < 1) {
+	if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1) {
 		netif_stop_queue(dev);
 		spin_unlock_irqrestore(&bp->lock, flags);
 		netdev_err(bp->dev, "BUG! Tx Ring full when queue awake!\n");
@@ -855,7 +852,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
 
-	if (macb_tx_ring_avail(bp) < 1)
+	if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1)
 		netif_stop_queue(dev);
 
 	spin_unlock_irqrestore(&bp->lock, flags);
-- 
1.8.0

Re: [PATCH v2] net/macb: move to circ_buf macros and fix initial condition

From: David Miller <davem@davemloft.net>
Date: 2012-11-19 19:22:49

From: Nicolas Ferre <redacted>
Date: Mon, 19 Nov 2012 17:00:21 +0100
Move to circular buffers management macro and correct an error
with circular buffer initial condition.

Without this patch, the macb_tx_ring_avail() function was
not reporting the proper ring availability at startup:
macb macb: eth0: BUG! Tx Ring full when queue awake!
macb macb: eth0: tx_head = 0, tx_tail = 0
And hanginig forever...

I remove the macb_tx_ring_avail() function and use the
proven macros from circ_buf.h. CIRC_CNT() is used in the
"consumer" part of the driver: macb_tx_interrupt() to match
advice from Documentation/circular-buffers.txt.

Reported-by: Jean-Christophe PLAGNIOL-VILLARD <redacted>
Signed-off-by: Nicolas Ferre <redacted>
Tested-by: Jean-Christophe PLAGNIOL-VILLARD <redacted>
Applied, thanks.
---
v2: - added tags from Jean-Christophe PLAGNIOL-VILLARD
Note that under normal circumstances, if the only change is the
tags that people added in replies, you don't need to do this.

Patchwork accumulates all of the signoffs, acks, tested-by,
reviewed-by, etc. tags made in replies to the patch automatically for
me, so when I apply the patch they will be there.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help