netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] bcm63xx_enet: fix poll callback.
@ 2015-03-02 17:28 Nicolas Schichan
  2015-03-03  3:15 ` David Miller
  0 siblings, 1 reply; 15+ messages in thread
From: Nicolas Schichan @ 2015-03-02 17:28 UTC (permalink / raw)
  To: David S. Miller, Tobias Klauser, Felipe Balbi, Wilfried Klaebe,
	Eric W. Biederman, Nicolas Schichan, Alexander Duyck, netdev,
	linux-kernel

In case there was some tx buffer reclaimed and not enough rx packets
to consume the whole budget, napi_complete would not be called and
interrupts would be kept disabled, effectively resulting in the
network core never to call the poll callback again and no rx/tx
interrupts to be fired either.

Fix that by taking the tx buffer reclaim work into account in the poll
callback, and keeping interrupts off only when the budget allowance
has been exhausted.
---
 drivers/net/ethernet/broadcom/bcm63xx_enet.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index 21206d3..e0d599a 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -427,7 +427,7 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget)
 /*
  * try to or force reclaim of transmitted buffers
  */
-static int bcm_enet_tx_reclaim(struct net_device *dev, int force)
+static int bcm_enet_tx_reclaim(struct net_device *dev, int force, int budget)
 {
 	struct bcm_enet_priv *priv;
 	int released;
@@ -471,6 +471,8 @@ static int bcm_enet_tx_reclaim(struct net_device *dev, int force)
 
 		dev_kfree_skb(skb);
 		released++;
+		if (!force && released == budget)
+			break;
 	}
 
 	if (netif_queue_stopped(dev) && released)
@@ -486,7 +488,7 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget)
 {
 	struct bcm_enet_priv *priv;
 	struct net_device *dev;
-	int tx_work_done, rx_work_done;
+	int work_done;
 
 	priv = container_of(napi, struct bcm_enet_priv, napi);
 	dev = priv->net_dev;
@@ -498,15 +500,15 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget)
 			 ENETDMAC_IR, priv->tx_chan);
 
 	/* reclaim sent skb */
-	tx_work_done = bcm_enet_tx_reclaim(dev, 0);
+	work_done = bcm_enet_tx_reclaim(dev, 0, budget);
 
 	spin_lock(&priv->rx_lock);
-	rx_work_done = bcm_enet_receive_queue(dev, budget);
+	work_done += bcm_enet_receive_queue(dev, budget - work_done);
 	spin_unlock(&priv->rx_lock);
 
-	if (rx_work_done >= budget || tx_work_done > 0) {
+	if (work_done >= budget) {
 		/* rx/tx queue is not yet empty/clean */
-		return rx_work_done;
+		return work_done;
 	}
 
 	/* no more packet in rx/tx queue, remove device from poll
@@ -519,7 +521,7 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget)
 	enet_dmac_writel(priv, priv->dma_chan_int_mask,
 			 ENETDMAC_IRMASK, priv->tx_chan);
 
-	return rx_work_done;
+	return work_done;
 }
 
 /*
@@ -1208,7 +1210,7 @@ static int bcm_enet_stop(struct net_device *dev)
 	bcm_enet_disable_mac(priv);
 
 	/* force reclaim of all tx buffers */
-	bcm_enet_tx_reclaim(dev, 1);
+	bcm_enet_tx_reclaim(dev, 1, 0);
 
 	/* free the rx skb ring */
 	for (i = 0; i < priv->rx_ring_size; i++) {
@@ -2415,7 +2417,7 @@ static int bcm_enetsw_stop(struct net_device *dev)
 	bcm_enet_disable_dma(priv, priv->rx_chan);
 
 	/* force reclaim of all tx buffers */
-	bcm_enet_tx_reclaim(dev, 1);
+	bcm_enet_tx_reclaim(dev, 1, 0);
 
 	/* free the rx skb ring */
 	for (i = 0; i < priv->rx_ring_size; i++) {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread
* [PATCH] bcm63xx_enet: fix poll callback.
@ 2015-03-03 11:45 Nicolas Schichan
  2015-03-03 13:29 ` Eric Dumazet
  2015-03-04 20:45 ` David Miller
  0 siblings, 2 replies; 15+ messages in thread
From: Nicolas Schichan @ 2015-03-03 11:45 UTC (permalink / raw)
  To: David S. Miller, Tobias Klauser, Felipe Balbi, Wilfried Klaebe,
	Eric W. Biederman, Nicolas Schichan, Alexander Duyck, netdev,
	linux-kernel

In case there was some tx buffer reclaimed and not enough rx packets
to consume the whole budget, napi_complete would not be called and
interrupts would be kept disabled, effectively resulting in the
network core never to call the poll callback again and no rx/tx
interrupts to be fired either.

Fix that by only accounting the rx work done in the poll callback.

Signed-off-by: Nicolas Schichan <nschichan@freebox.fr>
---
 drivers/net/ethernet/broadcom/bcm63xx_enet.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index 21206d3..a7f2cc3 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -486,7 +486,7 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget)
 {
 	struct bcm_enet_priv *priv;
 	struct net_device *dev;
-	int tx_work_done, rx_work_done;
+	int rx_work_done;
 
 	priv = container_of(napi, struct bcm_enet_priv, napi);
 	dev = priv->net_dev;
@@ -498,14 +498,14 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget)
 			 ENETDMAC_IR, priv->tx_chan);
 
 	/* reclaim sent skb */
-	tx_work_done = bcm_enet_tx_reclaim(dev, 0);
+	bcm_enet_tx_reclaim(dev, 0);
 
 	spin_lock(&priv->rx_lock);
 	rx_work_done = bcm_enet_receive_queue(dev, budget);
 	spin_unlock(&priv->rx_lock);
 
-	if (rx_work_done >= budget || tx_work_done > 0) {
-		/* rx/tx queue is not yet empty/clean */
+	if (rx_work_done >= budget) {
+		/* rx queue is not yet empty/clean */
 		return rx_work_done;
 	}
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2015-03-04 20:45 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-02 17:28 [PATCH] bcm63xx_enet: fix poll callback Nicolas Schichan
2015-03-03  3:15 ` David Miller
2015-03-03 11:18   ` Nicolas Schichan
2015-03-03 19:03     ` David Miller
  -- strict thread matches above, loose matches on Subject: below --
2015-03-03 11:45 Nicolas Schichan
2015-03-03 13:29 ` Eric Dumazet
2015-03-03 13:42   ` Eric Dumazet
2015-03-03 13:53     ` Nicolas Schichan
2015-03-03 14:18       ` Eric Dumazet
2015-03-03 14:43         ` Nicolas Schichan
2015-03-03 17:42       ` Florian Fainelli
2015-03-03 23:05         ` Jonas Gorski
2015-03-03 16:09     ` Alexander Duyck
2015-03-03 16:32       ` Eric Dumazet
2015-03-04 20:45 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).