Netdev List
 help / color / mirror / Atom feed
* Re: [PATCHSET net-next v3 00/07] Support for byte queue limits on various drivers
From: Tino Reichardt @ 2013-10-20 20:19 UTC (permalink / raw)
  To: netdev
In-Reply-To: <1382296991-20289-1-git-send-email-milky-kernel@mcmilk.de>

* Tino Reichardt <milky-kernel@mcmilk.de> wrote:
> Hello again,
> 
> this patchset is intended for net-next/linux-3.13.
> 
> It adds support for byte queue limits on various network drivers.
> 
> Since not all of them are fully tested by now, I added an bql_disable
> module parameter, which can be used to disable the BQL code.
> 
> "if (likely(bql_disable == false))" was replaced by
> "if (unlikely(bql_disable))" ...


Please ignore Patchset v3... "unlikely(bql_disable)" is of cause not
correct :(


Please use "[PATCHSET net-next v3 00/07]" instead.

Sorry for all the noise here ;)

-- 
Best regards, TR

^ permalink raw reply

* Re: [PATCHSET net-next v3 00/07] Support for byte queue limits on various drivers
From: Joe Perches @ 2013-10-20 19:38 UTC (permalink / raw)
  To: Tino Reichardt; +Cc: netdev, David S. Miller
In-Reply-To: <1382296991-20289-1-git-send-email-milky-kernel@mcmilk.de>

On Sun, 2013-10-20 at 21:23 +0200, Tino Reichardt wrote:
> Hello again,

Hi again Tino.

> "if (likely(bql_disable == false))" was replaced by
> "if (unlikely(bql_disable))" ...

Sorry for suggesting this, but it's not an
equivalent transform unless the then & else
paths are also inverted.

Here there are no else branches.
Doesn't this need to be?

from:
	if (likely(bql_disable == false))
to:
	if (likely(!bql_disable))

^ permalink raw reply

* [PATCH net-next v3 07/07] natsemi: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 19:23 UTC (permalink / raw)
  To: netdev, Greg Kroah-Hartman, David S. Miller, Jiri Pirko,
	Bill Pemberton
In-Reply-To: <1382296991-20289-1-git-send-email-milky-kernel@mcmilk.de>

Changes to natsemi driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/natsemi/natsemi.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index 7a5e295..1f6efbc 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -71,6 +71,8 @@
 				 NETIF_MSG_TX_ERR)
 static int debug = -1;
 
+static bool bql_disable;
+
 static int mtu;
 
 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
@@ -139,12 +141,15 @@ MODULE_LICENSE("GPL");
 
 module_param(mtu, int, 0);
 module_param(debug, int, 0);
+module_param(bql_disable, bool, 0);
 module_param(rx_copybreak, int, 0);
 module_param(dspcfg_workaround, int, 0);
 module_param_array(options, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
 MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)");
 MODULE_PARM_DESC(debug, "DP8381x default debug level");
+MODULE_PARM_DESC(bql_disable,
+	"Disable Byte Queue Limits functionality (default: false)");
 MODULE_PARM_DESC(rx_copybreak,
 	"DP8381x copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(dspcfg_workaround, "DP8381x: control DspCfg workaround");
@@ -1974,6 +1979,9 @@ static void init_ring(struct net_device *dev)
 		np->tx_ring[i].cmd_status = 0;
 	}
 
+	if (unlikely(bql_disable))
+		netdev_reset_queue(dev);
+
 	/* 2) RX ring */
 	np->dirty_rx = 0;
 	np->cur_rx = RX_RING_SIZE;
@@ -2012,6 +2020,9 @@ static void drain_tx(struct net_device *dev)
 		}
 		np->tx_skbuff[i] = NULL;
 	}
+
+	if (unlikely(bql_disable))
+		netdev_reset_queue(dev);
 }
 
 static void drain_rx(struct net_device *dev)
@@ -2116,6 +2127,9 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
 		dev_kfree_skb_irq(skb);
 		dev->stats.tx_dropped++;
 	}
+
+	if (unlikely(bql_disable))
+		netdev_sent_queue(dev, skb->len);
 	spin_unlock_irqrestore(&np->lock, flags);
 
 	if (netif_msg_tx_queued(np)) {
@@ -2128,6 +2142,7 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
 static void netdev_tx_done(struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
+	unsigned bytes_compl = 0, pkts_compl = 0;
 
 	for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
 		int entry = np->dirty_tx % TX_RING_SIZE;
@@ -2158,9 +2173,15 @@ static void netdev_tx_done(struct net_device *dev)
 					np->tx_skbuff[entry]->len,
 					PCI_DMA_TODEVICE);
 		/* Free the original skb. */
+		bytes_compl += np->tx_skbuff[entry]->len;
+		pkts_compl++;
 		dev_kfree_skb_irq(np->tx_skbuff[entry]);
 		np->tx_skbuff[entry] = NULL;
 	}
+
+	if (unlikely(bql_disable))
+		netdev_completed_queue(dev, pkts_compl, bytes_compl);
+
 	if (netif_queue_stopped(dev) &&
 	    np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
 		/* The ring is no longer full, wake queue. */
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v3 06/07] 3c59x: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 19:23 UTC (permalink / raw)
  To: netdev, Steffen Klassert
In-Reply-To: <1382296991-20289-1-git-send-email-milky-kernel@mcmilk.de>

Changes to 3c59x driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/3com/3c59x.c | 47 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index ad5272b..6a7b77d 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -795,6 +795,7 @@ static int global_options = -1;
 static int global_full_duplex = -1;
 static int global_enable_wol = -1;
 static int global_use_mmio = -1;
+static bool bql_disable;
 
 /* Variables to work-around the Compaq PCI BIOS32 problem. */
 static int compaq_ioaddr, compaq_irq, compaq_device_id = 0x5900;
@@ -819,6 +820,8 @@ module_param(compaq_device_id, int, 0);
 module_param(watchdog, int, 0);
 module_param(global_use_mmio, int, 0);
 module_param_array(use_mmio, int, NULL, 0);
+module_param(bql_disable, bool, 0);
+
 MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
 MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
 MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
@@ -836,6 +839,7 @@ MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem wor
 MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");
 MODULE_PARM_DESC(global_use_mmio, "3c59x: same as use_mmio, but applies to all NICs if options is unset");
 MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)");
+MODULE_PARM_DESC(bql_disable, "3c59x: Disable Byte Queue Limits functionality (default: false)");
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void poll_vortex(struct net_device *dev)
@@ -1726,6 +1730,9 @@ vortex_up(struct net_device *dev)
 	iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
 	if (vp->cb_fn_base)			/* The PCMCIA people are idiots.  */
 		iowrite32(0x8000, vp->cb_fn_base + 4);
+
+	if (unlikely(bql_disable))
+		netdev_reset_queue(dev);
 	netif_start_queue (dev);
 err_out:
 	return err;
@@ -2080,10 +2087,15 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		spin_unlock_irq(&vp->window_lock);
 		vp->tx_skb = skb;
 		iowrite16(StartDMADown, ioaddr + EL3_CMD);
+		if (unlikely(bql_disable))
+			netdev_sent_queue(dev, len);
 		/* netif_wake_queue() will be called at the DMADone interrupt. */
 	} else {
 		/* ... and the packet rounded to a doubleword. */
-		iowrite32_rep(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+		int len = (skb->len + 3) >> 2;
+		iowrite32_rep(ioaddr + TX_FIFO, skb->data, len);
+		if (unlikely(bql_disable))
+			netdev_sent_queue(dev, len);
 		dev_kfree_skb (skb);
 		if (ioread16(ioaddr + TxFree) > 1536) {
 			netif_start_queue (dev);	/* AKPM: redundant? */
@@ -2094,7 +2106,6 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 
-
 	/* Clear the Tx status stack. */
 	{
 		int tx_status;
@@ -2164,12 +2175,14 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
 										skb->len, PCI_DMA_TODEVICE));
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len | LAST_FRAG);
+		netdev_sent_queue(dev, skb->len);
 	} else {
-		int i;
+		int i, len;
 
 		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
 										skb_headlen(skb), PCI_DMA_TODEVICE));
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb_headlen(skb));
+		len = skb_headlen(skb);
 
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -2180,16 +2193,21 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 						(void *)skb_frag_address(frag),
 						skb_frag_size(frag), PCI_DMA_TODEVICE));
 
-			if (i == skb_shinfo(skb)->nr_frags-1)
+			if (i == skb_shinfo(skb)->nr_frags - 1) {
 					vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag)|LAST_FRAG);
-			else
+					len += skb_frag_size(frag) | LAST_FRAG;
+			} else {
 					vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag));
+					len += skb_frag_size(frag);
+			}
 		}
+		netdev_sent_queue(dev, len);
 	}
 #else
 	vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, PCI_DMA_TODEVICE));
 	vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
 	vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
+	netdev_sent_queue(dev, skb->len | LAST_FRAG);
 #endif
 
 	spin_lock_irqsave(&vp->lock, flags);
@@ -2234,6 +2252,7 @@ vortex_interrupt(int irq, void *dev_id)
 	int status;
 	int work_done = max_interrupt_work;
 	int handled = 0;
+	unsigned bytes_compl = 0, pkts_compl = 0;
 
 	ioaddr = vp->ioaddr;
 	spin_lock(&vp->lock);
@@ -2279,8 +2298,12 @@ vortex_interrupt(int irq, void *dev_id)
 
 		if (status & DMADone) {
 			if (ioread16(ioaddr + Wn7_MasterStatus) & 0x1000) {
+				int len;
 				iowrite16(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
-				pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
+				len = (vp->tx_skb->len + 3) & ~3;
+				pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, len, PCI_DMA_TODEVICE);
+				bytes_compl += len;
+				pkts_compl++;
 				dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
 				if (ioread16(ioaddr + TxFree) > 1536) {
 					/*
@@ -2327,6 +2350,9 @@ vortex_interrupt(int irq, void *dev_id)
 
 	spin_unlock(&vp->window_lock);
 
+	if (unlikely(bql_disable))
+		netdev_completed_queue(dev, pkts_compl, bytes_compl);
+
 	if (vortex_debug > 4)
 		pr_debug("%s: exiting interrupt, status %4.4x.\n",
 			   dev->name, status);
@@ -2348,6 +2374,7 @@ boomerang_interrupt(int irq, void *dev_id)
 	void __iomem *ioaddr;
 	int status;
 	int work_done = max_interrupt_work;
+	unsigned bytes_compl = 0, pkts_compl = 0;
 
 	ioaddr = vp->ioaddr;
 
@@ -2420,6 +2447,8 @@ boomerang_interrupt(int irq, void *dev_id)
 					pci_unmap_single(VORTEX_PCI(vp),
 						le32_to_cpu(vp->tx_ring[entry].addr), skb->len, PCI_DMA_TODEVICE);
 #endif
+					bytes_compl += skb->len;
+					pkts_compl++;
 					dev_kfree_skb_irq(skb);
 					vp->tx_skbuff[entry] = NULL;
 				} else {
@@ -2467,6 +2496,10 @@ boomerang_interrupt(int irq, void *dev_id)
 handler_exit:
 	vp->handling_irq = 0;
 	spin_unlock(&vp->lock);
+
+	if (unlikely(bql_disable))
+		netdev_completed_queue(dev, pkts_compl, bytes_compl);
+
 	return IRQ_HANDLED;
 }
 
@@ -2660,6 +2693,8 @@ vortex_down(struct net_device *dev, int final_down)
 	struct vortex_private *vp = netdev_priv(dev);
 	void __iomem *ioaddr = vp->ioaddr;
 
+	if (unlikely(bql_disable))
+		netdev_reset_queue(dev);
 	netif_stop_queue (dev);
 
 	del_timer_sync(&vp->rx_oom_timer);
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v3 05/07] via-velocity: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 19:23 UTC (permalink / raw)
  To: netdev, Francois Romieu
In-Reply-To: <1382296991-20289-1-git-send-email-milky-kernel@mcmilk.de>

Changes to via-velocity driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/via/via-velocity.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
index d022bf9..b084404 100644
--- a/drivers/net/ethernet/via/via-velocity.c
+++ b/drivers/net/ethernet/via/via-velocity.c
@@ -1,3 +1,4 @@
+
 /*
  * This code is derived from the VIA reference driver (copyright message
  * below) provided to Red Hat by VIA Networking Technologies, Inc. for
@@ -368,6 +369,11 @@ static int rx_copybreak = 200;
 module_param(rx_copybreak, int, 0644);
 MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
 
+static bool bql_disable;
+module_param(bql_disable, bool, 0);
+MODULE_PARM_DESC(bql_disable,
+	"Disable Byte Queue Limits functionality (default: false)");
+
 /*
  *	Internal board variants. At the moment we have only one
  */
@@ -1751,6 +1757,9 @@ static void velocity_free_tx_buf(struct velocity_info *vptr,
 					le16_to_cpu(pktlen), DMA_TO_DEVICE);
 		}
 	}
+
+	if (unlikely(bql_disable))
+		netdev_reset_queue(vptr->netdev);
 	dev_kfree_skb_irq(skb);
 	tdinfo->skb = NULL;
 }
@@ -1915,6 +1924,7 @@ static int velocity_tx_srv(struct velocity_info *vptr)
 	int works = 0;
 	struct velocity_td_info *tdinfo;
 	struct net_device_stats *stats = &vptr->netdev->stats;
+	unsigned int pkts_compl = 0, bytes_compl = 0;
 
 	for (qnum = 0; qnum < vptr->tx.numq; qnum++) {
 		for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0;
@@ -1946,6 +1956,8 @@ static int velocity_tx_srv(struct velocity_info *vptr)
 			} else {
 				stats->tx_packets++;
 				stats->tx_bytes += tdinfo->skb->len;
+				pkts_compl++;
+				bytes_compl += tdinfo->skb->len;
 			}
 			velocity_free_tx_buf(vptr, tdinfo, td);
 			vptr->tx.used[qnum]--;
@@ -1955,6 +1967,10 @@ static int velocity_tx_srv(struct velocity_info *vptr)
 		if (AVAIL_TD(vptr, qnum) < 1)
 			full = 1;
 	}
+
+	if (unlikely(bql_disable))
+		netdev_completed_queue(vptr->netdev, pkts_compl, bytes_compl);
+
 	/*
 	 *	Look to see if we should kick the transmit network
 	 *	layer for more work.
@@ -2641,6 +2657,8 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
 	td_ptr->td_buf[0].size |= TD_QUEUE;
 	mac_tx_queue_wake(vptr->mac_regs, qnum);
 
+	if (unlikely(bql_disable))
+		netdev_sent_queue(vptr->netdev, skb->len);
 	spin_unlock_irqrestore(&vptr->lock, flags);
 out:
 	return NETDEV_TX_OK;
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v3 04/07] via-rhine: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 19:23 UTC (permalink / raw)
  To: netdev, Roger Luethi
In-Reply-To: <1382296991-20289-1-git-send-email-milky-kernel@mcmilk.de>

Changes to via-rhine driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/via/via-rhine.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index bdf697b..067b4ab 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -53,6 +53,8 @@ static int rx_copybreak = 1518;
 static int rx_copybreak;
 #endif
 
+static bool bql_disable;
+
 /* Work-around for broken BIOSes: they are unable to get the chip back out of
    power state D3 so PXE booting fails. bootparam(7): via-rhine.avoid_D3=1 */
 static bool avoid_D3;
@@ -128,9 +130,11 @@ MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver");
 MODULE_LICENSE("GPL");
 
 module_param(debug, int, 0);
+module_param(bql_disable, bool, 0);
 module_param(rx_copybreak, int, 0);
 module_param(avoid_D3, bool, 0);
 MODULE_PARM_DESC(debug, "VIA Rhine debug message flags");
+MODULE_PARM_DESC(bql_disable, "Disable Byte Queue Limits functionality (default: false)");
 MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)");
 
@@ -1220,6 +1224,8 @@ static void alloc_tbufs(struct net_device* dev)
 	}
 	rp->tx_ring[i-1].next_desc = cpu_to_le32(rp->tx_ring_dma);
 
+	if (unlikely(bql_disable))
+		netdev_reset_queue(dev);
 }
 
 static void free_tbufs(struct net_device* dev)
@@ -1719,6 +1725,8 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
 	/* lock eth irq */
 	wmb();
 	rp->tx_ring[entry].tx_status |= cpu_to_le32(DescOwn);
+	if (unlikely(bql_disable))
+		netdev_sent_queue(dev, skb->len);
 	wmb();
 
 	rp->cur_tx++;
@@ -1783,6 +1791,7 @@ static void rhine_tx(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
 	int txstatus = 0, entry = rp->dirty_tx % TX_RING_SIZE;
+	unsigned int pkts_compl = 0, bytes_compl = 0;
 
 	/* find and cleanup dirty tx descriptors */
 	while (rp->dirty_tx != rp->cur_tx) {
@@ -1830,10 +1839,18 @@ static void rhine_tx(struct net_device *dev)
 					 rp->tx_skbuff[entry]->len,
 					 PCI_DMA_TODEVICE);
 		}
+
+		bytes_compl += rp->tx_skbuff[entry]->len;
+		pkts_compl++;
 		dev_kfree_skb(rp->tx_skbuff[entry]);
+
 		rp->tx_skbuff[entry] = NULL;
 		entry = (++rp->dirty_tx) % TX_RING_SIZE;
 	}
+
+	if (unlikely(bql_disable))
+		netdev_completed_queue(dev, pkts_compl, bytes_compl);
+
 	if ((rp->cur_tx - rp->dirty_tx) < TX_QUEUE_LEN - 4)
 		netif_wake_queue(dev);
 }
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v3 03/07] tulip: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 19:23 UTC (permalink / raw)
  To: netdev, Grant Grundler
In-Reply-To: <1382296991-20289-1-git-send-email-milky-kernel@mcmilk.de>

Changes to tulip driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/dec/tulip/interrupt.c  | 4 ++++
 drivers/net/ethernet/dec/tulip/tulip.h      | 1 +
 drivers/net/ethernet/dec/tulip/tulip_core.c | 9 ++++++++-
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/dec/tulip/interrupt.c b/drivers/net/ethernet/dec/tulip/interrupt.c
index 92306b3..7084267 100644
--- a/drivers/net/ethernet/dec/tulip/interrupt.c
+++ b/drivers/net/ethernet/dec/tulip/interrupt.c
@@ -532,6 +532,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
 #endif
 	unsigned int work_count = tulip_max_interrupt_work;
 	unsigned int handled = 0;
+	unsigned int bytes_compl = 0;
 
 	/* Let's see whether the interrupt really is for us */
 	csr5 = ioread32(ioaddr + CSR5);
@@ -634,6 +635,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
 						 PCI_DMA_TODEVICE);
 
 				/* Free the original skb. */
+				bytes_compl += tp->tx_buffers[entry].skb->len;
 				dev_kfree_skb_irq(tp->tx_buffers[entry].skb);
 				tp->tx_buffers[entry].skb = NULL;
 				tp->tx_buffers[entry].mapping = 0;
@@ -802,6 +804,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
 	}
 #endif /* CONFIG_TULIP_NAPI */
 
+	if (likely(tulip_bql_disable == false))
+		netdev_completed_queue(dev, tx, bytes_compl);
 	if ((missed = ioread32(ioaddr + CSR8) & 0x1ffff)) {
 		dev->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
 	}
diff --git a/drivers/net/ethernet/dec/tulip/tulip.h b/drivers/net/ethernet/dec/tulip/tulip.h
index 38431a1..3c62870 100644
--- a/drivers/net/ethernet/dec/tulip/tulip.h
+++ b/drivers/net/ethernet/dec/tulip/tulip.h
@@ -513,6 +513,7 @@ void comet_timer(unsigned long data);
 
 /* tulip_core.c */
 extern int tulip_debug;
+extern bool tulip_bql_disable;
 extern const char * const medianame[];
 extern const char tulip_media_cap[];
 extern struct tulip_chip_table tulip_tbl[];
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index 4e8cfa2..d02eaa1 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -106,11 +106,13 @@ static int csr0 = 0x00A00000 | 0x4800;
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  (4*HZ)
 
-
 MODULE_AUTHOR("The Linux Kernel Team");
 MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
+module_param(tulip_bql_disable, bool, 0);
+MODULE_PARM_DESC(tulip_bql_disable,
+	"Disable Byte Queue Limits functionality (default: false)");
 module_param(tulip_debug, int, 0);
 module_param(max_interrupt_work, int, 0);
 module_param(rx_copybreak, int, 0);
@@ -123,6 +125,7 @@ int tulip_debug = TULIP_DEBUG;
 #else
 int tulip_debug = 1;
 #endif
+bool tulip_bql_disable;
 
 static void tulip_timer(unsigned long data)
 {
@@ -703,6 +706,8 @@ tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	wmb();
 
 	tp->cur_tx++;
+	if (likely(tulip_bql_disable == false))
+		netdev_sent_queue(dev, skb->len);
 
 	/* Trigger an immediate transmit demand. */
 	iowrite32(0, tp->base_addr + CSR1);
@@ -746,6 +751,8 @@ static void tulip_clean_tx_ring(struct tulip_private *tp)
 		tp->tx_buffers[entry].skb = NULL;
 		tp->tx_buffers[entry].mapping = 0;
 	}
+	if (likely(tulip_bql_disable == false))
+		netdev_reset_queue(tp->dev);
 }
 
 static void tulip_down (struct net_device *dev)
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v3 02/07] r8169: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 19:23 UTC (permalink / raw)
  To: netdev, Realtek linux nic maintainers, Igor Maravic,
	Francois Romieu
In-Reply-To: <1382296991-20289-1-git-send-email-milky-kernel@mcmilk.de>

Changes to r8169 driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/realtek/r8169.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 3397cee..8f12145 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -313,6 +313,7 @@ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
 
 static int rx_buf_sz = 16383;
 static int use_dac;
+static bool bql_disable;
 static struct {
 	u32 msg_enable;
 } debug = { -1 };
@@ -818,6 +819,9 @@ MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
 module_param(use_dac, int, 0);
 MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
+module_param(bql_disable, bool, 0);
+MODULE_PARM_DESC(bql_disable,
+	"Disable Byte Queue Limits functionality (default: false)");
 module_param_named(debug, debug.msg_enable, int, 0);
 MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
 MODULE_LICENSE("GPL");
@@ -5841,6 +5845,8 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp)
 {
 	rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC);
 	tp->cur_tx = tp->dirty_tx = 0;
+	if (unlikely(bql_disable))
+		netdev_reset_queue(tp->dev);
 }
 
 static void rtl_reset_work(struct rtl8169_private *tp)
@@ -6017,6 +6023,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
 	txd->opts2 = cpu_to_le32(opts[1]);
 
 	skb_tx_timestamp(skb);
+	if (unlikely(bql_disable))
+		netdev_sent_queue(dev, skb->len);
 
 	wmb();
 
@@ -6116,6 +6124,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
 static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
 {
 	unsigned int dirty_tx, tx_left;
+	unsigned int pkts_compl = 0, bytes_compl = 0;
 
 	dirty_tx = tp->dirty_tx;
 	smp_rmb();
@@ -6138,6 +6147,9 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
 			tp->tx_stats.packets++;
 			tp->tx_stats.bytes += tx_skb->skb->len;
 			u64_stats_update_end(&tp->tx_stats.syncp);
+
+			bytes_compl += tx_skb->skb->len;
+			pkts_compl++;
 			dev_kfree_skb(tx_skb->skb);
 			tx_skb->skb = NULL;
 		}
@@ -6155,6 +6167,8 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
 		 * ring status.
 		 */
 		smp_mb();
+		if (unlikely(bql_disable))
+			netdev_completed_queue(dev, pkts_compl, bytes_compl);
 		if (netif_queue_stopped(dev) &&
 		    TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) {
 			netif_wake_queue(dev);
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v3 01/07] 8139too: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 19:23 UTC (permalink / raw)
  To: netdev, David S. Miller, Joe Perches, Jiri Pirko, Bill Pemberton,
	Greg Kroah-Hartman
In-Reply-To: <1382296991-20289-1-git-send-email-milky-kernel@mcmilk.de>

Changes to 8139too driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/realtek/8139too.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index 3ccedeb..c17c12f 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -160,6 +160,8 @@ static int multicast_filter_limit = 32;
 /* bitmapped message enable number */
 static int debug = -1;
 
+static bool bql_disable;
+
 /*
  * Receive ring size
  * Warning: 64K ring has hardware issues and may lock up.
@@ -626,10 +628,12 @@ module_param(multicast_filter_limit, int, 0);
 module_param_array(media, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
 module_param(debug, int, 0);
-MODULE_PARM_DESC (debug, "8139too bitmapped message enable number");
-MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered multicast addresses");
-MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
-MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
+module_param(bql_disable, bool, 0);
+MODULE_PARM_DESC(debug, "8139too bitmapped message enable number");
+MODULE_PARM_DESC(multicast_filter_limit, "8139too maximum number of filtered multicast addresses");
+MODULE_PARM_DESC(media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
+MODULE_PARM_DESC(full_duplex, "8139too: Force full duplex for board(s) (1)");
+MODULE_PARM_DESC(bql_disable, "8139too: Disable Byte Queue Limits functionality (default: false)");
 
 static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
 static int rtl8139_open (struct net_device *dev);
@@ -1409,6 +1413,8 @@ static void rtl8139_hw_start (struct net_device *dev)
 	}
 
 	netdev_dbg(dev, "init buffer addresses\n");
+	if (unlikely(bql_disable))
+		netdev_reset_queue(dev);
 
 	/* Lock Config[01234] and BMCR register writes */
 	RTL_W8 (Cfg9346, Cfg9346_Lock);
@@ -1639,6 +1645,9 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
 	tp->cur_tx = 0;
 	tp->dirty_tx = 0;
 
+	if (unlikely(bql_disable))
+		netdev_reset_queue(tp->dev);
+
 	/* XXX account for unsent Tx packets in tp->stats.tx_dropped */
 }
 
@@ -1729,10 +1738,13 @@ static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
 	 * to make sure that the device sees the updated data.
 	 */
 	wmb();
+	len = max_t(unsigned int, len, (unsigned int)ETH_ZLEN);
 	RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
-		   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
+		   tp->tx_flag | len);
 
 	tp->cur_tx++;
+	if (unlikely(bql_disable))
+		netdev_sent_queue(dev, len);
 
 	if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
 		netif_stop_queue (dev);
@@ -1750,6 +1762,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
 				  void __iomem *ioaddr)
 {
 	unsigned long dirty_tx, tx_left;
+	unsigned bytes_compl = 0, pkts_compl = 0;
 
 	assert (dev != NULL);
 	assert (ioaddr != NULL);
@@ -1792,6 +1805,8 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
 			u64_stats_update_begin(&tp->tx_stats.syncp);
 			tp->tx_stats.packets++;
 			tp->tx_stats.bytes += txstatus & 0x7ff;
+			pkts_compl++;
+			bytes_compl += txstatus & 0x7ff;
 			u64_stats_update_end(&tp->tx_stats.syncp);
 		}
 
@@ -1807,6 +1822,9 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
 	}
 #endif /* RTL8139_NDEBUG */
 
+	if (unlikely(bql_disable))
+		netdev_completed_queue(dev, pkts_compl, bytes_compl);
+
 	/* only wake the queue if we did work, and the queue is stopped */
 	if (tp->dirty_tx != dirty_tx) {
 		tp->dirty_tx = dirty_tx;
-- 
1.8.4.1

^ permalink raw reply related

* [PATCHSET net-next v3 00/07] Support for byte queue limits on various drivers
From: Tino Reichardt @ 2013-10-20 19:23 UTC (permalink / raw)
  To: netdev, David S. Miller

Hello again,

this patchset is intended for net-next/linux-3.13.

It adds support for byte queue limits on various network drivers.

Since not all of them are fully tested by now, I added an bql_disable
module parameter, which can be used to disable the BQL code.

"if (likely(bql_disable == false))" was replaced by
"if (unlikely(bql_disable))" ...


Any comments are welcome, thanks.
Tino Reichardt

This BQL patchset contains the following patches by now:
0001-8139too-Support-for-byte-queue-limits.patch
0002-r8169-Support-for-byte-queue-limits.patch
0003-tulip-Support-for-byte-queue-limits.patch
0004-via-rhine-Support-for-byte-queue-limits.patch
0005-via-velocity-Support-for-byte-queue-limits.patch
0006-3c59x-Support-for-byte-queue-limits.patch
0007-natsemi-Support-for-byte-queue-limits.patch

---
 drivers/net/ethernet/3com/3c59x.c           | 47 +++++++++++++++++++++++++----
 drivers/net/ethernet/dec/tulip/interrupt.c  |  4 +++
 drivers/net/ethernet/dec/tulip/tulip.h      |  1 +
 drivers/net/ethernet/dec/tulip/tulip_core.c |  9 +++++-
 drivers/net/ethernet/natsemi/natsemi.c      | 21 +++++++++++++
 drivers/net/ethernet/realtek/8139too.c      | 28 ++++++++++++++---
 drivers/net/ethernet/realtek/r8169.c        | 14 +++++++++
 drivers/net/ethernet/via/via-rhine.c        | 17 +++++++++++
 drivers/net/ethernet/via/via-velocity.c     | 18 +++++++++++
 9 files changed, 147 insertions(+), 12 deletions(-)

^ permalink raw reply

* Re: [PATCH net-next v2 01/07] 8139too: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 19:14 UTC (permalink / raw)
  To: netdev
In-Reply-To: <1382295089.2041.42.camel@joe-AO722>

* Joe Perches <joe@perches.com> wrote:
> On Sun, 2013-10-20 at 20:13 +0200, Tino Reichardt wrote:
> > Changes to 8139too driver to use byte queue limits.
> []
> > diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
> []
> > @@ -1409,6 +1413,8 @@ static void rtl8139_hw_start (struct net_device *dev)
> []
> >  	netdev_dbg(dev, "init buffer addresses\n");
> > +	if (likely(bql_disable == false))
> > +		netdev_reset_queue(dev);
> 
> Much prefer:
> 
> 	if (unlikely(bql_disable))

Okay, i will resend an updated v3 patchset.



-- 
Best regards, TR

^ permalink raw reply

* Re: [PATCH net-next v2 01/07] 8139too: Support for byte queue limits
From: Joe Perches @ 2013-10-20 18:51 UTC (permalink / raw)
  To: Tino Reichardt
  Cc: netdev, David S. Miller, Jiri Pirko, Bill Pemberton,
	Greg Kroah-Hartman
In-Reply-To: <1382292803-18875-2-git-send-email-milky-kernel@mcmilk.de>

On Sun, 2013-10-20 at 20:13 +0200, Tino Reichardt wrote:
> Changes to 8139too driver to use byte queue limits.
[]
> diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
[]
> @@ -1409,6 +1413,8 @@ static void rtl8139_hw_start (struct net_device *dev)
[]
>  	netdev_dbg(dev, "init buffer addresses\n");
> +	if (likely(bql_disable == false))
> +		netdev_reset_queue(dev);

Much prefer:

	if (unlikely(bql_disable))

> @@ -1639,6 +1645,9 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
[]
> +	if (likely(bql_disable == false))
> +		netdev_reset_queue(tp->dev);

etc...

^ permalink raw reply

* Re: kernel BUG at net/core/skbuff.c:1048!
From: Patrick McHardy @ 2013-10-20 18:33 UTC (permalink / raw)
  To: Wim Vandersmissen, netdev, kernelspam
In-Reply-To: <20131020182523.GF27787@order.stressinduktion.org>

On Sun, Oct 20, 2013 at 08:25:23PM +0200, Hannes Frederic Sowa wrote:
> Hi Patrick!
> 
> On Sat, Oct 05, 2013 at 11:01:05AM +0100, Patrick McHardy wrote:
> > On Fri, Oct 04, 2013 at 11:35:55AM +0200, Wim Vandersmissen wrote:
> > > Hi,
> > > 
> > > Got the following BUG when using ipv6 netfilter/conntrack/ipv6
> > > forwarding and traffic flowing.
> > > 
> > > No issues in 3.4.x, but triggered in 3.10.x (introduced in 3.7)
> > 
> > Please also send me your 3.10.x config and the ip6tables rules you're
> > using.
> > 
> > Are you actually using IPv6 NAT? 
> 
> Maybe the same bug was hit by someone else and was reported in kernel
> bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=63331
> 
> I added him in Cc.

Thanks, didn't really get to it yet. The problem is obviously that we're
rerouting the individual fragments, during which their headroom gets
expanded while a reference to them is held by the reassembled skb. Just
not sure yet how to fix it.

^ permalink raw reply

* Re: [PATCH net 2/3] ipv6: fill rt6i_gateway with nexthop address
From: Hannes Frederic Sowa @ 2013-10-20 18:33 UTC (permalink / raw)
  To: Julian Anastasov
  Cc: David Miller, netdev, netfilter-devel, lvs-devel,
	Hideaki YOSHIFUJI
In-Reply-To: <1382272985-1528-3-git-send-email-ja@ssi.bg>

On Sun, Oct 20, 2013 at 03:43:04PM +0300, Julian Anastasov wrote:
> Make sure rt6i_gateway contains nexthop information in
> all routes returned from lookup or when routes are directly
> attached to skb for generated ICMP packets.
> 
> The effect of this patch should be a faster version of
> rt6_nexthop() and the consideration of local addresses as
> nexthop.
> 
> Signed-off-by: Julian Anastasov <ja@ssi.bg>
> ---
>  include/net/ip6_route.h | 6 ++----
>  net/ipv6/ip6_output.c   | 4 ++--
>  net/ipv6/route.c        | 8 ++++++--
>  3 files changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
> index 481404a..2b786b7 100644
> --- a/include/net/ip6_route.h
> +++ b/include/net/ip6_route.h
> @@ -194,11 +194,9 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
>  	       skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
>  }
>  
> -static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt, struct in6_addr *dest)
> +static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt)
>  {
> -	if (rt->rt6i_flags & RTF_GATEWAY || !ipv6_addr_any(&rt->rt6i_gateway))
> -		return &rt->rt6i_gateway;
> -	return dest;
> +	return &rt->rt6i_gateway;
>  }
>  

Hm, looks good. Will test is soon.

One small remark:

Maybe we can kill rt6_nexthop completly and use rt6i_gateway directly so a
reader does not have to lookup this function.

Thanks,

  Hannes


^ permalink raw reply

* Re: kernel BUG at net/core/skbuff.c:1048!
From: Hannes Frederic Sowa @ 2013-10-20 18:25 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Wim Vandersmissen, netdev, kernelspam
In-Reply-To: <20131005100105.GA2457@macbook.localnet>

Hi Patrick!

On Sat, Oct 05, 2013 at 11:01:05AM +0100, Patrick McHardy wrote:
> On Fri, Oct 04, 2013 at 11:35:55AM +0200, Wim Vandersmissen wrote:
> > Hi,
> > 
> > Got the following BUG when using ipv6 netfilter/conntrack/ipv6
> > forwarding and traffic flowing.
> > 
> > No issues in 3.4.x, but triggered in 3.10.x (introduced in 3.7)
> 
> Please also send me your 3.10.x config and the ip6tables rules you're
> using.
> 
> Are you actually using IPv6 NAT? 

Maybe the same bug was hit by someone else and was reported in kernel
bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=63331

I added him in Cc.

Greetings,

  Hannes

^ permalink raw reply

* [PATCH net-next v2 07/07] natsemi: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 18:13 UTC (permalink / raw)
  To: netdev, Greg Kroah-Hartman, David S. Miller, Jiri Pirko,
	Bill Pemberton
In-Reply-To: <1382292803-18875-1-git-send-email-milky-kernel@mcmilk.de>

Changes to natsemi driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/natsemi/natsemi.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index 7a5e295..1f6efbc 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -71,6 +71,8 @@
 				 NETIF_MSG_TX_ERR)
 static int debug = -1;
 
+static bool bql_disable;
+
 static int mtu;
 
 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
@@ -139,12 +141,15 @@ MODULE_LICENSE("GPL");
 
 module_param(mtu, int, 0);
 module_param(debug, int, 0);
+module_param(bql_disable, bool, 0);
 module_param(rx_copybreak, int, 0);
 module_param(dspcfg_workaround, int, 0);
 module_param_array(options, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
 MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)");
 MODULE_PARM_DESC(debug, "DP8381x default debug level");
+MODULE_PARM_DESC(bql_disable,
+	"Disable Byte Queue Limits functionality (default: false)");
 MODULE_PARM_DESC(rx_copybreak,
 	"DP8381x copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(dspcfg_workaround, "DP8381x: control DspCfg workaround");
@@ -1974,6 +1979,9 @@ static void init_ring(struct net_device *dev)
 		np->tx_ring[i].cmd_status = 0;
 	}
 
+	if (likely(bql_disable == false))
+		netdev_reset_queue(dev);
+
 	/* 2) RX ring */
 	np->dirty_rx = 0;
 	np->cur_rx = RX_RING_SIZE;
@@ -2012,6 +2020,9 @@ static void drain_tx(struct net_device *dev)
 		}
 		np->tx_skbuff[i] = NULL;
 	}
+
+	if (likely(bql_disable == false))
+		netdev_reset_queue(dev);
 }
 
 static void drain_rx(struct net_device *dev)
@@ -2116,6 +2127,9 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
 		dev_kfree_skb_irq(skb);
 		dev->stats.tx_dropped++;
 	}
+
+	if (likely(bql_disable == false))
+		netdev_sent_queue(dev, skb->len);
 	spin_unlock_irqrestore(&np->lock, flags);
 
 	if (netif_msg_tx_queued(np)) {
@@ -2128,6 +2142,7 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
 static void netdev_tx_done(struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
+	unsigned bytes_compl = 0, pkts_compl = 0;
 
 	for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
 		int entry = np->dirty_tx % TX_RING_SIZE;
@@ -2158,9 +2173,15 @@ static void netdev_tx_done(struct net_device *dev)
 					np->tx_skbuff[entry]->len,
 					PCI_DMA_TODEVICE);
 		/* Free the original skb. */
+		bytes_compl += np->tx_skbuff[entry]->len;
+		pkts_compl++;
 		dev_kfree_skb_irq(np->tx_skbuff[entry]);
 		np->tx_skbuff[entry] = NULL;
 	}
+
+	if (likely(bql_disable == false))
+		netdev_completed_queue(dev, pkts_compl, bytes_compl);
+
 	if (netif_queue_stopped(dev) &&
 	    np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
 		/* The ring is no longer full, wake queue. */
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v2 06/07] 3c59x: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 18:13 UTC (permalink / raw)
  To: netdev, Steffen Klassert
In-Reply-To: <1382292803-18875-1-git-send-email-milky-kernel@mcmilk.de>

Changes to 3c59x driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/3com/3c59x.c | 47 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index ad5272b..6a7b77d 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -795,6 +795,7 @@ static int global_options = -1;
 static int global_full_duplex = -1;
 static int global_enable_wol = -1;
 static int global_use_mmio = -1;
+static bool bql_disable;
 
 /* Variables to work-around the Compaq PCI BIOS32 problem. */
 static int compaq_ioaddr, compaq_irq, compaq_device_id = 0x5900;
@@ -819,6 +820,8 @@ module_param(compaq_device_id, int, 0);
 module_param(watchdog, int, 0);
 module_param(global_use_mmio, int, 0);
 module_param_array(use_mmio, int, NULL, 0);
+module_param(bql_disable, bool, 0);
+
 MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
 MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
 MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
@@ -836,6 +839,7 @@ MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem wor
 MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");
 MODULE_PARM_DESC(global_use_mmio, "3c59x: same as use_mmio, but applies to all NICs if options is unset");
 MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)");
+MODULE_PARM_DESC(bql_disable, "3c59x: Disable Byte Queue Limits functionality (default: false)");
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void poll_vortex(struct net_device *dev)
@@ -1726,6 +1730,9 @@ vortex_up(struct net_device *dev)
 	iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
 	if (vp->cb_fn_base)			/* The PCMCIA people are idiots.  */
 		iowrite32(0x8000, vp->cb_fn_base + 4);
+
+	if (likely(bql_disable == false))
+		netdev_reset_queue(dev);
 	netif_start_queue (dev);
 err_out:
 	return err;
@@ -2080,10 +2087,15 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		spin_unlock_irq(&vp->window_lock);
 		vp->tx_skb = skb;
 		iowrite16(StartDMADown, ioaddr + EL3_CMD);
+		if (likely(bql_disable == false))
+			netdev_sent_queue(dev, len);
 		/* netif_wake_queue() will be called at the DMADone interrupt. */
 	} else {
 		/* ... and the packet rounded to a doubleword. */
-		iowrite32_rep(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+		int len = (skb->len + 3) >> 2;
+		iowrite32_rep(ioaddr + TX_FIFO, skb->data, len);
+		if (likely(bql_disable == false))
+			netdev_sent_queue(dev, len);
 		dev_kfree_skb (skb);
 		if (ioread16(ioaddr + TxFree) > 1536) {
 			netif_start_queue (dev);	/* AKPM: redundant? */
@@ -2094,7 +2106,6 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 
-
 	/* Clear the Tx status stack. */
 	{
 		int tx_status;
@@ -2164,12 +2175,14 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
 										skb->len, PCI_DMA_TODEVICE));
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len | LAST_FRAG);
+		netdev_sent_queue(dev, skb->len);
 	} else {
-		int i;
+		int i, len;
 
 		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
 										skb_headlen(skb), PCI_DMA_TODEVICE));
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb_headlen(skb));
+		len = skb_headlen(skb);
 
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -2180,16 +2193,21 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 						(void *)skb_frag_address(frag),
 						skb_frag_size(frag), PCI_DMA_TODEVICE));
 
-			if (i == skb_shinfo(skb)->nr_frags-1)
+			if (i == skb_shinfo(skb)->nr_frags - 1) {
 					vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag)|LAST_FRAG);
-			else
+					len += skb_frag_size(frag) | LAST_FRAG;
+			} else {
 					vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag));
+					len += skb_frag_size(frag);
+			}
 		}
+		netdev_sent_queue(dev, len);
 	}
 #else
 	vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, PCI_DMA_TODEVICE));
 	vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
 	vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
+	netdev_sent_queue(dev, skb->len | LAST_FRAG);
 #endif
 
 	spin_lock_irqsave(&vp->lock, flags);
@@ -2234,6 +2252,7 @@ vortex_interrupt(int irq, void *dev_id)
 	int status;
 	int work_done = max_interrupt_work;
 	int handled = 0;
+	unsigned bytes_compl = 0, pkts_compl = 0;
 
 	ioaddr = vp->ioaddr;
 	spin_lock(&vp->lock);
@@ -2279,8 +2298,12 @@ vortex_interrupt(int irq, void *dev_id)
 
 		if (status & DMADone) {
 			if (ioread16(ioaddr + Wn7_MasterStatus) & 0x1000) {
+				int len;
 				iowrite16(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
-				pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
+				len = (vp->tx_skb->len + 3) & ~3;
+				pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, len, PCI_DMA_TODEVICE);
+				bytes_compl += len;
+				pkts_compl++;
 				dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
 				if (ioread16(ioaddr + TxFree) > 1536) {
 					/*
@@ -2327,6 +2350,9 @@ vortex_interrupt(int irq, void *dev_id)
 
 	spin_unlock(&vp->window_lock);
 
+	if (likely(bql_disable == false))
+		netdev_completed_queue(dev, pkts_compl, bytes_compl);
+
 	if (vortex_debug > 4)
 		pr_debug("%s: exiting interrupt, status %4.4x.\n",
 			   dev->name, status);
@@ -2348,6 +2374,7 @@ boomerang_interrupt(int irq, void *dev_id)
 	void __iomem *ioaddr;
 	int status;
 	int work_done = max_interrupt_work;
+	unsigned bytes_compl = 0, pkts_compl = 0;
 
 	ioaddr = vp->ioaddr;
 
@@ -2420,6 +2447,8 @@ boomerang_interrupt(int irq, void *dev_id)
 					pci_unmap_single(VORTEX_PCI(vp),
 						le32_to_cpu(vp->tx_ring[entry].addr), skb->len, PCI_DMA_TODEVICE);
 #endif
+					bytes_compl += skb->len;
+					pkts_compl++;
 					dev_kfree_skb_irq(skb);
 					vp->tx_skbuff[entry] = NULL;
 				} else {
@@ -2467,6 +2496,10 @@ boomerang_interrupt(int irq, void *dev_id)
 handler_exit:
 	vp->handling_irq = 0;
 	spin_unlock(&vp->lock);
+
+	if (likely(bql_disable == false))
+		netdev_completed_queue(dev, pkts_compl, bytes_compl);
+
 	return IRQ_HANDLED;
 }
 
@@ -2660,6 +2693,8 @@ vortex_down(struct net_device *dev, int final_down)
 	struct vortex_private *vp = netdev_priv(dev);
 	void __iomem *ioaddr = vp->ioaddr;
 
+	if (likely(bql_disable == false))
+		netdev_reset_queue(dev);
 	netif_stop_queue (dev);
 
 	del_timer_sync(&vp->rx_oom_timer);
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v2 05/07] via-velocity: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 18:13 UTC (permalink / raw)
  To: netdev, Francois Romieu
In-Reply-To: <1382292803-18875-1-git-send-email-milky-kernel@mcmilk.de>

Changes to via-velocity driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/via/via-velocity.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
index d022bf9..b084404 100644
--- a/drivers/net/ethernet/via/via-velocity.c
+++ b/drivers/net/ethernet/via/via-velocity.c
@@ -1,3 +1,4 @@
+
 /*
  * This code is derived from the VIA reference driver (copyright message
  * below) provided to Red Hat by VIA Networking Technologies, Inc. for
@@ -368,6 +369,11 @@ static int rx_copybreak = 200;
 module_param(rx_copybreak, int, 0644);
 MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
 
+static bool bql_disable;
+module_param(bql_disable, bool, 0);
+MODULE_PARM_DESC(bql_disable,
+	"Disable Byte Queue Limits functionality (default: false)");
+
 /*
  *	Internal board variants. At the moment we have only one
  */
@@ -1751,6 +1757,9 @@ static void velocity_free_tx_buf(struct velocity_info *vptr,
 					le16_to_cpu(pktlen), DMA_TO_DEVICE);
 		}
 	}
+
+	if (likely(bql_disable == false))
+		netdev_reset_queue(vptr->netdev);
 	dev_kfree_skb_irq(skb);
 	tdinfo->skb = NULL;
 }
@@ -1915,6 +1924,7 @@ static int velocity_tx_srv(struct velocity_info *vptr)
 	int works = 0;
 	struct velocity_td_info *tdinfo;
 	struct net_device_stats *stats = &vptr->netdev->stats;
+	unsigned int pkts_compl = 0, bytes_compl = 0;
 
 	for (qnum = 0; qnum < vptr->tx.numq; qnum++) {
 		for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0;
@@ -1946,6 +1956,8 @@ static int velocity_tx_srv(struct velocity_info *vptr)
 			} else {
 				stats->tx_packets++;
 				stats->tx_bytes += tdinfo->skb->len;
+				pkts_compl++;
+				bytes_compl += tdinfo->skb->len;
 			}
 			velocity_free_tx_buf(vptr, tdinfo, td);
 			vptr->tx.used[qnum]--;
@@ -1955,6 +1967,10 @@ static int velocity_tx_srv(struct velocity_info *vptr)
 		if (AVAIL_TD(vptr, qnum) < 1)
 			full = 1;
 	}
+
+	if (likely(bql_disable == false))
+		netdev_completed_queue(vptr->netdev, pkts_compl, bytes_compl);
+
 	/*
 	 *	Look to see if we should kick the transmit network
 	 *	layer for more work.
@@ -2641,6 +2657,8 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
 	td_ptr->td_buf[0].size |= TD_QUEUE;
 	mac_tx_queue_wake(vptr->mac_regs, qnum);
 
+	if (likely(bql_disable == false))
+		netdev_sent_queue(vptr->netdev, skb->len);
 	spin_unlock_irqrestore(&vptr->lock, flags);
 out:
 	return NETDEV_TX_OK;
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v2 04/07] via-rhine: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 18:13 UTC (permalink / raw)
  To: netdev, Roger Luethi
In-Reply-To: <1382292803-18875-1-git-send-email-milky-kernel@mcmilk.de>

Changes to via-rhine driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/via/via-rhine.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index bdf697b..067b4ab 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -53,6 +53,8 @@ static int rx_copybreak = 1518;
 static int rx_copybreak;
 #endif
 
+static bool bql_disable;
+
 /* Work-around for broken BIOSes: they are unable to get the chip back out of
    power state D3 so PXE booting fails. bootparam(7): via-rhine.avoid_D3=1 */
 static bool avoid_D3;
@@ -128,9 +130,11 @@ MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver");
 MODULE_LICENSE("GPL");
 
 module_param(debug, int, 0);
+module_param(bql_disable, bool, 0);
 module_param(rx_copybreak, int, 0);
 module_param(avoid_D3, bool, 0);
 MODULE_PARM_DESC(debug, "VIA Rhine debug message flags");
+MODULE_PARM_DESC(bql_disable, "Disable Byte Queue Limits functionality (default: false)");
 MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)");
 
@@ -1220,6 +1224,8 @@ static void alloc_tbufs(struct net_device* dev)
 	}
 	rp->tx_ring[i-1].next_desc = cpu_to_le32(rp->tx_ring_dma);
 
+	if (likely(bql_disable == false))
+		netdev_reset_queue(dev);
 }
 
 static void free_tbufs(struct net_device* dev)
@@ -1719,6 +1725,8 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
 	/* lock eth irq */
 	wmb();
 	rp->tx_ring[entry].tx_status |= cpu_to_le32(DescOwn);
+	if (likely(bql_disable == false))
+		netdev_sent_queue(dev, skb->len);
 	wmb();
 
 	rp->cur_tx++;
@@ -1783,6 +1791,7 @@ static void rhine_tx(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
 	int txstatus = 0, entry = rp->dirty_tx % TX_RING_SIZE;
+	unsigned int pkts_compl = 0, bytes_compl = 0;
 
 	/* find and cleanup dirty tx descriptors */
 	while (rp->dirty_tx != rp->cur_tx) {
@@ -1830,10 +1839,18 @@ static void rhine_tx(struct net_device *dev)
 					 rp->tx_skbuff[entry]->len,
 					 PCI_DMA_TODEVICE);
 		}
+
+		bytes_compl += rp->tx_skbuff[entry]->len;
+		pkts_compl++;
 		dev_kfree_skb(rp->tx_skbuff[entry]);
+
 		rp->tx_skbuff[entry] = NULL;
 		entry = (++rp->dirty_tx) % TX_RING_SIZE;
 	}
+
+	if (likely(bql_disable == false))
+		netdev_completed_queue(dev, pkts_compl, bytes_compl);
+
 	if ((rp->cur_tx - rp->dirty_tx) < TX_QUEUE_LEN - 4)
 		netif_wake_queue(dev);
 }
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v2 03/07] tulip: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 18:13 UTC (permalink / raw)
  To: netdev, Grant Grundler
In-Reply-To: <1382292803-18875-1-git-send-email-milky-kernel@mcmilk.de>

Changes to tulip driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/dec/tulip/interrupt.c  | 4 ++++
 drivers/net/ethernet/dec/tulip/tulip.h      | 1 +
 drivers/net/ethernet/dec/tulip/tulip_core.c | 9 ++++++++-
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/dec/tulip/interrupt.c b/drivers/net/ethernet/dec/tulip/interrupt.c
index 92306b3..7084267 100644
--- a/drivers/net/ethernet/dec/tulip/interrupt.c
+++ b/drivers/net/ethernet/dec/tulip/interrupt.c
@@ -532,6 +532,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
 #endif
 	unsigned int work_count = tulip_max_interrupt_work;
 	unsigned int handled = 0;
+	unsigned int bytes_compl = 0;
 
 	/* Let's see whether the interrupt really is for us */
 	csr5 = ioread32(ioaddr + CSR5);
@@ -634,6 +635,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
 						 PCI_DMA_TODEVICE);
 
 				/* Free the original skb. */
+				bytes_compl += tp->tx_buffers[entry].skb->len;
 				dev_kfree_skb_irq(tp->tx_buffers[entry].skb);
 				tp->tx_buffers[entry].skb = NULL;
 				tp->tx_buffers[entry].mapping = 0;
@@ -802,6 +804,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
 	}
 #endif /* CONFIG_TULIP_NAPI */
 
+	if (likely(tulip_bql_disable == false))
+		netdev_completed_queue(dev, tx, bytes_compl);
 	if ((missed = ioread32(ioaddr + CSR8) & 0x1ffff)) {
 		dev->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
 	}
diff --git a/drivers/net/ethernet/dec/tulip/tulip.h b/drivers/net/ethernet/dec/tulip/tulip.h
index 38431a1..3c62870 100644
--- a/drivers/net/ethernet/dec/tulip/tulip.h
+++ b/drivers/net/ethernet/dec/tulip/tulip.h
@@ -513,6 +513,7 @@ void comet_timer(unsigned long data);
 
 /* tulip_core.c */
 extern int tulip_debug;
+extern bool tulip_bql_disable;
 extern const char * const medianame[];
 extern const char tulip_media_cap[];
 extern struct tulip_chip_table tulip_tbl[];
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index 4e8cfa2..d02eaa1 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -106,11 +106,13 @@ static int csr0 = 0x00A00000 | 0x4800;
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  (4*HZ)
 
-
 MODULE_AUTHOR("The Linux Kernel Team");
 MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
+module_param(tulip_bql_disable, bool, 0);
+MODULE_PARM_DESC(tulip_bql_disable,
+	"Disable Byte Queue Limits functionality (default: false)");
 module_param(tulip_debug, int, 0);
 module_param(max_interrupt_work, int, 0);
 module_param(rx_copybreak, int, 0);
@@ -123,6 +125,7 @@ int tulip_debug = TULIP_DEBUG;
 #else
 int tulip_debug = 1;
 #endif
+bool tulip_bql_disable;
 
 static void tulip_timer(unsigned long data)
 {
@@ -703,6 +706,8 @@ tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	wmb();
 
 	tp->cur_tx++;
+	if (likely(tulip_bql_disable == false))
+		netdev_sent_queue(dev, skb->len);
 
 	/* Trigger an immediate transmit demand. */
 	iowrite32(0, tp->base_addr + CSR1);
@@ -746,6 +751,8 @@ static void tulip_clean_tx_ring(struct tulip_private *tp)
 		tp->tx_buffers[entry].skb = NULL;
 		tp->tx_buffers[entry].mapping = 0;
 	}
+	if (likely(tulip_bql_disable == false))
+		netdev_reset_queue(tp->dev);
 }
 
 static void tulip_down (struct net_device *dev)
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v2 02/07] r8169: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 18:13 UTC (permalink / raw)
  To: netdev, Realtek linux nic maintainers, Igor Maravic,
	Francois Romieu
In-Reply-To: <1382292803-18875-1-git-send-email-milky-kernel@mcmilk.de>

Changes to r8169 driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/realtek/r8169.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 3397cee..8f12145 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -313,6 +313,7 @@ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
 
 static int rx_buf_sz = 16383;
 static int use_dac;
+static bool bql_disable;
 static struct {
 	u32 msg_enable;
 } debug = { -1 };
@@ -818,6 +819,9 @@ MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
 module_param(use_dac, int, 0);
 MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
+module_param(bql_disable, bool, 0);
+MODULE_PARM_DESC(bql_disable,
+	"Disable Byte Queue Limits functionality (default: false)");
 module_param_named(debug, debug.msg_enable, int, 0);
 MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
 MODULE_LICENSE("GPL");
@@ -5841,6 +5845,8 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp)
 {
 	rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC);
 	tp->cur_tx = tp->dirty_tx = 0;
+	if (likely(bql_disable == false))
+		netdev_reset_queue(tp->dev);
 }
 
 static void rtl_reset_work(struct rtl8169_private *tp)
@@ -6017,6 +6023,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
 	txd->opts2 = cpu_to_le32(opts[1]);
 
 	skb_tx_timestamp(skb);
+	if (likely(bql_disable == false))
+		netdev_sent_queue(dev, skb->len);
 
 	wmb();
 
@@ -6116,6 +6124,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
 static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
 {
 	unsigned int dirty_tx, tx_left;
+	unsigned int pkts_compl = 0, bytes_compl = 0;
 
 	dirty_tx = tp->dirty_tx;
 	smp_rmb();
@@ -6138,6 +6147,9 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
 			tp->tx_stats.packets++;
 			tp->tx_stats.bytes += tx_skb->skb->len;
 			u64_stats_update_end(&tp->tx_stats.syncp);
+
+			bytes_compl += tx_skb->skb->len;
+			pkts_compl++;
 			dev_kfree_skb(tx_skb->skb);
 			tx_skb->skb = NULL;
 		}
@@ -6155,6 +6167,8 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
 		 * ring status.
 		 */
 		smp_mb();
+		if (likely(bql_disable == false))
+			netdev_completed_queue(dev, pkts_compl, bytes_compl);
 		if (netif_queue_stopped(dev) &&
 		    TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) {
 			netif_wake_queue(dev);
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH net-next v2 01/07] 8139too: Support for byte queue limits
From: Tino Reichardt @ 2013-10-20 18:13 UTC (permalink / raw)
  To: netdev, David S. Miller, Joe Perches, Jiri Pirko, Bill Pemberton,
	Greg Kroah-Hartman
In-Reply-To: <1382292803-18875-1-git-send-email-milky-kernel@mcmilk.de>

Changes to 8139too driver to use byte queue limits.


Signed-off-by: Tino Reichardt <milky-kernel@mcmilk.de>

---
 drivers/net/ethernet/realtek/8139too.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index 3ccedeb..c17c12f 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -160,6 +160,8 @@ static int multicast_filter_limit = 32;
 /* bitmapped message enable number */
 static int debug = -1;
 
+static bool bql_disable;
+
 /*
  * Receive ring size
  * Warning: 64K ring has hardware issues and may lock up.
@@ -626,10 +628,12 @@ module_param(multicast_filter_limit, int, 0);
 module_param_array(media, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
 module_param(debug, int, 0);
-MODULE_PARM_DESC (debug, "8139too bitmapped message enable number");
-MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered multicast addresses");
-MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
-MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
+module_param(bql_disable, bool, 0);
+MODULE_PARM_DESC(debug, "8139too bitmapped message enable number");
+MODULE_PARM_DESC(multicast_filter_limit, "8139too maximum number of filtered multicast addresses");
+MODULE_PARM_DESC(media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
+MODULE_PARM_DESC(full_duplex, "8139too: Force full duplex for board(s) (1)");
+MODULE_PARM_DESC(bql_disable, "8139too: Disable Byte Queue Limits functionality (default: false)");
 
 static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
 static int rtl8139_open (struct net_device *dev);
@@ -1409,6 +1413,8 @@ static void rtl8139_hw_start (struct net_device *dev)
 	}
 
 	netdev_dbg(dev, "init buffer addresses\n");
+	if (likely(bql_disable == false))
+		netdev_reset_queue(dev);
 
 	/* Lock Config[01234] and BMCR register writes */
 	RTL_W8 (Cfg9346, Cfg9346_Lock);
@@ -1639,6 +1645,9 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
 	tp->cur_tx = 0;
 	tp->dirty_tx = 0;
 
+	if (likely(bql_disable == false))
+		netdev_reset_queue(tp->dev);
+
 	/* XXX account for unsent Tx packets in tp->stats.tx_dropped */
 }
 
@@ -1729,10 +1738,13 @@ static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
 	 * to make sure that the device sees the updated data.
 	 */
 	wmb();
+	len = max_t(unsigned int, len, (unsigned int)ETH_ZLEN);
 	RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
-		   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
+		   tp->tx_flag | len);
 
 	tp->cur_tx++;
+	if (likely(bql_disable == false))
+		netdev_sent_queue(dev, len);
 
 	if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
 		netif_stop_queue (dev);
@@ -1750,6 +1762,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
 				  void __iomem *ioaddr)
 {
 	unsigned long dirty_tx, tx_left;
+	unsigned bytes_compl = 0, pkts_compl = 0;
 
 	assert (dev != NULL);
 	assert (ioaddr != NULL);
@@ -1792,6 +1805,8 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
 			u64_stats_update_begin(&tp->tx_stats.syncp);
 			tp->tx_stats.packets++;
 			tp->tx_stats.bytes += txstatus & 0x7ff;
+			pkts_compl++;
+			bytes_compl += txstatus & 0x7ff;
 			u64_stats_update_end(&tp->tx_stats.syncp);
 		}
 
@@ -1807,6 +1822,9 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
 	}
 #endif /* RTL8139_NDEBUG */
 
+	if (likely(bql_disable == false))
+		netdev_completed_queue(dev, pkts_compl, bytes_compl);
+
 	/* only wake the queue if we did work, and the queue is stopped */
 	if (tp->dirty_tx != dirty_tx) {
 		tp->dirty_tx = dirty_tx;
-- 
1.8.4.1

^ permalink raw reply related

* [PATCHSET net-next v2 00/07] Support for byte queue limits on various drivers
From: Tino Reichardt @ 2013-10-20 18:13 UTC (permalink / raw)
  To: netdev, David S. Miller

Hello,

this patchset is intended for net-next/linux-3.13.

It adds support for byte queue limits on various network drivers.

Since not all of them are fully tested by now, I added an bql_disable
module parameter, which can be used to disable the BQL code.


Any comments are welcome, thanks.
Tino Reichardt


This BQL patchset contains the following patches by now:
0001-8139too-Support-for-byte-queue-limits.patch
0002-r8169-Support-for-byte-queue-limits.patch
0003-tulip-Support-for-byte-queue-limits.patch
0004-via-rhine-Support-for-byte-queue-limits.patch
0005-via-velocity-Support-for-byte-queue-limits.patch
0006-3c59x-Support-for-byte-queue-limits.patch
0007-natsemi-Support-for-byte-queue-limits.patch

---
 drivers/net/ethernet/3com/3c59x.c           | 47 +++++++++++++++++++++++++----
 drivers/net/ethernet/dec/tulip/interrupt.c  |  4 +++
 drivers/net/ethernet/dec/tulip/tulip.h      |  1 +
 drivers/net/ethernet/dec/tulip/tulip_core.c |  9 +++++-
 drivers/net/ethernet/natsemi/natsemi.c      | 21 +++++++++++++
 drivers/net/ethernet/realtek/8139too.c      | 28 ++++++++++++++---
 drivers/net/ethernet/realtek/r8169.c        | 14 +++++++++
 drivers/net/ethernet/via/via-rhine.c        | 17 +++++++++++
 drivers/net/ethernet/via/via-velocity.c     | 18 +++++++++++
 9 files changed, 147 insertions(+), 12 deletions(-)

^ permalink raw reply

* [PATCH net v2 9/9] bnx2x: Set NETIF_F_HIGHDMA unconditionally
From: Yuval Mintz @ 2013-10-20 14:51 UTC (permalink / raw)
  To: davem, netdev; +Cc: ariele, eilong, Merav Sicron, Yuval Mintz
In-Reply-To: <1382280694-8428-1-git-send-email-yuvalmin@broadcom.com>

From: Merav Sicron <meravs@broadcom.com>

Current driver implementation incorrectly sets the flag only if 64-bit
DMA mask succeeded.

Signed-off-by: Merav Sicron <meravs@broadcom.com>
Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h      | 1 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 +---
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 310c57a..c5e375d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1528,7 +1528,6 @@ struct bnx2x {
 #define PCI_32BIT_FLAG			(1 << 1)
 #define ONE_PORT_FLAG			(1 << 2)
 #define NO_WOL_FLAG			(1 << 3)
-#define USING_DAC_FLAG			(1 << 4)
 #define USING_MSIX_FLAG			(1 << 5)
 #define USING_MSI_FLAG			(1 << 6)
 #define DISABLE_MSI_FLAG		(1 << 7)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 7a66bd2..b42f89c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -12118,7 +12118,6 @@ static int bnx2x_set_coherency_mask(struct bnx2x *bp)
 	struct device *dev = &bp->pdev->dev;
 
 	if (dma_set_mask(dev, DMA_BIT_MASK(64)) == 0) {
-		bp->flags |= USING_DAC_FLAG;
 		if (dma_set_coherent_mask(dev, DMA_BIT_MASK(64)) != 0) {
 			dev_err(dev, "dma_set_coherent_mask failed, aborting\n");
 			return -EIO;
@@ -12286,8 +12285,7 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
 		NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
 
 	dev->features |= dev->hw_features | NETIF_F_HW_VLAN_CTAG_RX;
-	if (bp->flags & USING_DAC_FLAG)
-		dev->features |= NETIF_F_HIGHDMA;
+	dev->features |= NETIF_F_HIGHDMA;
 
 	/* Add Loopback capability to the device */
 	dev->hw_features |= NETIF_F_LOOPBACK;
-- 
1.8.1.227.g44fe835

^ permalink raw reply related

* [PATCH net v2 7/9] bnx2x: Lock DMAE when used by statistic flow
From: Yuval Mintz @ 2013-10-20 14:51 UTC (permalink / raw)
  To: davem, netdev; +Cc: ariele, eilong, Yuval Mintz
In-Reply-To: <1382280694-8428-1-git-send-email-yuvalmin@broadcom.com>

From: Ariel Elior <ariele@broadcom.com>

bnx2x has several clients to its DMAE machines - all of them with the exception
of the statistics flow used the same locking mechanisms to synchronize the DMAE
machines' usage.

Since statistics (which are periodically entered) use DMAE without taking the
locks, they may erase the commands which were previously set -
e.g., it may cause a VF to timeout while waiting for a PF answer on the VF-PF
channel as that command header would have been overwritten by the statistics'
header.

This patch makes certain that all flows utilizing DMAE will use the same
API, assuring that the locking scheme will be kept by all said flows.

Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h       |  3 ++-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c  | 14 +++++++-------
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c |  2 +-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c  |  2 +-
 4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 275b126..310c57a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -2073,7 +2073,8 @@ u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type,
 
 void bnx2x_prep_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
 			       u8 src_type, u8 dst_type);
-int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae);
+int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
+			       u32 *comp);
 
 /* FLR related routines */
 u32 bnx2x_flr_clnup_poll_count(struct bnx2x *bp);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index c2609c4..2367072 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -503,9 +503,9 @@ void bnx2x_prep_dmae_with_comp(struct bnx2x *bp,
 }
 
 /* issue a dmae command over the init-channel and wait for completion */
-int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae)
+int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
+			       u32 *comp)
 {
-	u32 *wb_comp = bnx2x_sp(bp, wb_comp);
 	int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 4000;
 	int rc = 0;
 
@@ -518,14 +518,14 @@ int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae)
 	spin_lock_bh(&bp->dmae_lock);
 
 	/* reset completion */
-	*wb_comp = 0;
+	*comp = 0;
 
 	/* post the command on the channel used for initializations */
 	bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
 
 	/* wait for completion */
 	udelay(5);
-	while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) {
+	while ((*comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) {
 
 		if (!cnt ||
 		    (bp->recovery_state != BNX2X_RECOVERY_DONE &&
@@ -537,7 +537,7 @@ int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae)
 		cnt--;
 		udelay(50);
 	}
-	if (*wb_comp & DMAE_PCI_ERR_FLAG) {
+	if (*comp & DMAE_PCI_ERR_FLAG) {
 		BNX2X_ERR("DMAE PCI error!\n");
 		rc = DMAE_PCI_ERROR;
 	}
@@ -574,7 +574,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
 	dmae.len = len32;
 
 	/* issue the command and wait for completion */
-	rc = bnx2x_issue_dmae_with_comp(bp, &dmae);
+	rc = bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp));
 	if (rc) {
 		BNX2X_ERR("DMAE returned failure %d\n", rc);
 		bnx2x_panic();
@@ -611,7 +611,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
 	dmae.len = len32;
 
 	/* issue the command and wait for completion */
-	rc = bnx2x_issue_dmae_with_comp(bp, &dmae);
+	rc = bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp));
 	if (rc) {
 		BNX2X_ERR("DMAE returned failure %d\n", rc);
 		bnx2x_panic();
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
index 86436c7..3b75070 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
@@ -196,7 +196,7 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp)
 
 	} else if (bp->func_stx) {
 		*stats_comp = 0;
-		bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
+		bnx2x_issue_dmae_with_comp(bp, dmae, stats_comp);
 	}
 }
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
index da16953..28757df 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
@@ -980,7 +980,7 @@ static int bnx2x_copy32_vf_dmae(struct bnx2x *bp, u8 from_vf,
 	dmae.len = len32;
 
 	/* issue the command and wait for completion */
-	return bnx2x_issue_dmae_with_comp(bp, &dmae);
+	return bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp));
 }
 
 static void bnx2x_vf_mbx_resp(struct bnx2x *bp, struct bnx2x_virtf *vf)
-- 
1.8.1.227.g44fe835

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox