* Re: [PATCHSET net-next v3 00/07] Support for byte queue limits on various drivers
From: Andi Kleen @ 2013-10-20 21:13 UTC (permalink / raw)
To: Tino Reichardt; +Cc: netdev, David S. Miller
In-Reply-To: <1382296991-20289-1-git-send-email-milky-kernel@mcmilk.de>
Tino Reichardt <milky-kernel@mcmilk.de> writes:
>
> 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))" ...
If it's untested it should probably be disabled by default,
until someone tests it.
-Andi
--
ak@linux.intel.com -- Speaking for myself only
^ permalink raw reply
* Fw: [Bug 63321] New: tcp_fastretrans_alert
From: Stephen Hemminger @ 2013-10-20 20:40 UTC (permalink / raw)
To: netdev
Begin forwarded message:
Date: Sun, 20 Oct 2013 06:20:25 -0700
From: "bugzilla-daemon@bugzilla.kernel.org" <bugzilla-daemon@bugzilla.kernel.org>
To: "stephen@networkplumber.org" <stephen@networkplumber.org>
Subject: [Bug 63321] New: tcp_fastretrans_alert
https://bugzilla.kernel.org/show_bug.cgi?id=63321
Bug ID: 63321
Summary: tcp_fastretrans_alert
Product: Networking
Version: 2.5
Kernel Version: 3.11.6
Hardware: x86-64
OS: Linux
Tree: Mainline
Status: NEW
Severity: normal
Priority: P1
Component: IPV4
Assignee: shemminger@linux-foundation.org
Reporter: warrior-elite@yandex.ru
Regression: No
[ 865.064799] ------------[ cut here ]------------
[ 865.064813] WARNING: CPU: 0 PID: 0 at
/home/apw/COD/linux/net/ipv4/tcp_input.c:2711
tcp_fastretrans_alert+0x5df/0x620()
[ 865.064815] Modules linked in: pci_stub vboxpci(OF) vboxnetadp(OF)
vboxnetflt(OF) joydev hid_generic usbhid hid vboxdrv(OF) binfmt_misc
snd_hda_codec_realtek ppdev uvcvideo videobuf2_vmalloc videobuf2_memops
videobuf2_core videodev snd_usb_audio snd_usbmidi_lib nvidia(POF) snd_hda_intel
snd_hda_codec snd_hwdep snd_pcm kvm_amd kvm snd_page_alloc snd_seq_midi
snd_seq_midi_event snd_rawmidi snd_seq microcode snd_seq_device snd_timer snd
serio_raw soundcore edac_core k10temp edac_mce_amd drm sp5100_tco ohci_pci
i2c_piix4 wmi mac_hid parport_pc lp parport pata_acpi ahci r8169 pata_atiixp
libahci mii
[ 865.064843] CPU: 0 PID: 0 Comm: swapper/0 Tainted: PF O
3.11.6-031106-generic #201310181453
[ 865.064845] Hardware name: Gigabyte Technology Co., Ltd.
GA-MA770-UD3/GA-MA770-UD3, BIOS FKb 07/08/2010
[ 865.064846] 0000000000000a97 ffff88012fc039a0 ffffffff81714a56
000000000000259d
[ 865.064849] 0000000000000000 ffff88012fc039e0 ffffffff8106539c
ffff88012fc03a00
[ 865.064851] ffff880114f45400 000000000000000c 0000000000004120
0000000000000001
[ 865.064853] Call Trace:
[ 865.064855] <IRQ> [<ffffffff81714a56>] dump_stack+0x46/0x58
[ 865.064861] [<ffffffff8106539c>] warn_slowpath_common+0x8c/0xc0
[ 865.064863] [<ffffffff810653ea>] warn_slowpath_null+0x1a/0x20
[ 865.064865] [<ffffffff8165f9df>] tcp_fastretrans_alert+0x5df/0x620
[ 865.064867] [<ffffffff816608c8>] tcp_ack+0x498/0x630
[ 865.064868] [<ffffffff8166109a>] tcp_rcv_established+0x31a/0x780
[ 865.064871] [<ffffffff8166b3b5>] tcp_v4_do_rcv+0x155/0x240
[ 865.064873] [<ffffffff8166d230>] tcp_v4_rcv+0x5f0/0x770
[ 865.064875] [<ffffffff81099f42>] ? try_to_wake_up+0x192/0x210
[ 865.064878] [<ffffffff81647a6e>] ip_local_deliver_finish+0xce/0x250
[ 865.064880] [<ffffffff81647d7b>] ip_local_deliver+0x4b/0x90
[ 865.064881] [<ffffffff81647761>] ip_rcv_finish+0x121/0x360
[ 865.064883] [<ffffffff81647ff6>] ip_rcv+0x236/0x350
[ 865.064886] [<ffffffff81611a2a>] __netif_receive_skb_core+0x5ca/0x720
[ 865.064888] [<ffffffff81611ba1>] __netif_receive_skb+0x21/0x70
[ 865.064890] [<ffffffff81611c13>] netif_receive_skb+0x23/0x90
[ 865.064891] [<ffffffff81612330>] napi_gro_receive+0xb0/0x130
[ 865.064898] [<ffffffffa00217f2>] rtl_rx+0xe2/0x320 [r8169]
[ 865.064903] [<ffffffffa00254c5>] rtl8169_poll+0x105/0x120 [r8169]
[ 865.064905] [<ffffffff8108d00e>] ? hrtimer_get_next_event+0xce/0xd0
[ 865.064907] [<ffffffff81612ca4>] net_rx_action+0x134/0x260
[ 865.064910] [<ffffffff814734c1>] ? add_interrupt_randomness+0x41/0x190
[ 865.064913] [<ffffffff8106a510>] __do_softirq+0xe0/0x280
[ 865.064915] [<ffffffff8172005e>] ? _raw_spin_lock+0xe/0x20
[ 865.064918] [<ffffffff8172ae9c>] call_softirq+0x1c/0x30
[ 865.064921] [<ffffffff81015e35>] do_softirq+0x65/0xa0
[ 865.064923] [<ffffffff8106a82e>] irq_exit+0x9e/0xc0
[ 865.064924] [<ffffffff8172b7a3>] do_IRQ+0x63/0xe0
[ 865.064926] [<ffffffff8172066d>] common_interrupt+0x6d/0x6d
[ 865.064927] <EOI> [<ffffffff810504f6>] ? native_safe_halt+0x6/0x10
[ 865.064932] [<ffffffff8101c803>] default_idle+0x23/0xe0
[ 865.064934] [<ffffffff8101c93a>] amd_e400_idle+0x7a/0x100
[ 865.064936] [<ffffffff8101d096>] arch_cpu_idle+0x26/0x30
[ 865.064938] [<ffffffff810ba77e>] cpu_idle_loop+0x7e/0x250
[ 865.064940] [<ffffffff810ba9bb>] cpu_startup_entry+0x6b/0x70
[ 865.064943] [<ffffffff816fcbd7>] rest_init+0x77/0x80
[ 865.064946] [<ffffffff81d24f23>] start_kernel+0x407/0x414
[ 865.064948] [<ffffffff81d249ae>] ? do_early_param+0x87/0x87
[ 865.064950] [<ffffffff81d24120>] ? early_idt_handlers+0x120/0x120
[ 865.064952] [<ffffffff81d245e8>] x86_64_start_reservations+0x2a/0x2c
[ 865.064954] [<ffffffff81d246f2>] x86_64_start_kernel+0x108/0x117
[ 865.064955] ---[ end trace 7fed0fa1e4d5f06f ]---
--
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* 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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox