* [PATCH v2 net-next 2/2] tcp: reduce out_of_order memory use
From: Eric Dumazet @ 2012-03-18 21:07 UTC (permalink / raw)
To: Neal Cardwell
Cc: David Miller, netdev, Tom Herbert, Ilpo Järvinen,
H.K. Jerry Chu, Yuchung Cheng
In-Reply-To: <CADVnQy=_Adr9xTd=7aUFT6m38YQ8V-V7KQc9c6L4nej-dfvekQ@mail.gmail.com>
With increasing receive window sizes, but speed of light not improved
that much, out of order queue can contain a huge number of skbs, waiting
to be moved to receive_queue when missing packets can fill the holes.
Some devices happen to use fat skbs (truesize of 4096 + sizeof(struct
sk_buff)) to store regular (MTU <= 1500) frames. This makes highly
probable sk_rmem_alloc hits sk_rcvbuf limit, which can be 4Mbytes in
many cases.
When limit is hit, tcp stack calls tcp_collapse_ofo_queue(), a true
latency killer and cpu cache blower.
Doing the coalescing attempt each time we add a frame in ofo queue
permits to keep memory use tight and in many cases avoid the
tcp_collapse() thing later.
Tested on various wireless setups (b43, ath9k, ...) known to use big skb
truesize, this patch removed the "packets collapsed in receive queue due
to low socket buffer" I had before.
This also reduced average memory used by tcp sockets.
With help from Neal Cardwell.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Yuchung Cheng <ycheng@google.com>
Cc: H.K. Jerry Chu <hkchu@google.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
V2: rebase after tcp_data_queue_ofo() introduction.
include/linux/snmp.h | 1 +
net/ipv4/proc.c | 1 +
net/ipv4/tcp_input.c | 19 ++++++++++++++++++-
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index 8ee8af4..2e68f5b 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -233,6 +233,7 @@ enum
LINUX_MIB_TCPREQQFULLDOCOOKIES, /* TCPReqQFullDoCookies */
LINUX_MIB_TCPREQQFULLDROP, /* TCPReqQFullDrop */
LINUX_MIB_TCPRETRANSFAIL, /* TCPRetransFail */
+ LINUX_MIB_TCPRCVCOALESCE, /* TCPRcvCoalesce */
__LINUX_MIB_MAX
};
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 02d6107..8af0d44 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -257,6 +257,7 @@ static const struct snmp_mib snmp4_net_list[] = {
SNMP_MIB_ITEM("TCPReqQFullDoCookies", LINUX_MIB_TCPREQQFULLDOCOOKIES),
SNMP_MIB_ITEM("TCPReqQFullDrop", LINUX_MIB_TCPREQQFULLDROP),
SNMP_MIB_ITEM("TCPRetransFail", LINUX_MIB_TCPRETRANSFAIL),
+ SNMP_MIB_ITEM("TCPRcvCoalesce", LINUX_MIB_TCPRCVCOALESCE),
SNMP_MIB_SENTINEL
};
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index fa7de12..e886e2f 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4484,7 +4484,24 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
end_seq = TCP_SKB_CB(skb)->end_seq;
if (seq == TCP_SKB_CB(skb1)->end_seq) {
- __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
+ /* Packets in ofo can stay in queue a long time.
+ * Better try to coalesce them right now
+ * to avoid future tcp_collapse_ofo_queue(),
+ * probably the most expensive function in tcp stack.
+ */
+ if (skb->len <= skb_tailroom(skb1) && !tcp_hdr(skb)->fin) {
+ NET_INC_STATS_BH(sock_net(sk),
+ LINUX_MIB_TCPRCVCOALESCE);
+ BUG_ON(skb_copy_bits(skb, 0,
+ skb_put(skb1, skb->len),
+ skb->len));
+ TCP_SKB_CB(skb1)->end_seq = end_seq;
+ TCP_SKB_CB(skb1)->ack_seq = TCP_SKB_CB(skb)->ack_seq;
+ __kfree_skb(skb);
+ skb = NULL;
+ } else {
+ __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
+ }
if (!tp->rx_opt.num_sacks ||
tp->selective_acks[0].end_seq != seq)
^ permalink raw reply related
* [PATCH v2 net-next 1/2] tcp: introduce tcp_data_queue_ofo
From: Eric Dumazet @ 2012-03-18 21:06 UTC (permalink / raw)
To: Neal Cardwell
Cc: David Miller, netdev, Tom Herbert, Ilpo Järvinen,
H.K. Jerry Chu, Yuchung Cheng
In-Reply-To: <CADVnQy=_Adr9xTd=7aUFT6m38YQ8V-V7KQc9c6L4nej-dfvekQ@mail.gmail.com>
Split tcp_data_queue() in two parts for better readability.
tcp_data_queue_ofo() is responsible for queueing incoming skb into out
of order queue.
Change code layout so that the skb_set_owner_r() is performed only if
skb is not dropped.
This is a preliminary patch before "reduce out_of_order memory use"
following patch.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Yuchung Cheng <ycheng@google.com>
Cc: H.K. Jerry Chu <hkchu@google.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
net/ipv4/tcp_input.c | 214 ++++++++++++++++++++++-------------------
1 file changed, 115 insertions(+), 99 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 68d4057..fa7de12 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4446,6 +4446,120 @@ static inline int tcp_try_rmem_schedule(struct sock *sk, unsigned int size)
return 0;
}
+static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
+{
+ struct tcp_sock *tp = tcp_sk(sk);
+ struct sk_buff *skb1;
+ u32 seq, end_seq;
+
+ TCP_ECN_check_ce(tp, skb);
+
+ if (tcp_try_rmem_schedule(sk, skb->truesize)) {
+ /* TODO: should increment a counter */
+ __kfree_skb(skb);
+ return;
+ }
+
+ /* Disable header prediction. */
+ tp->pred_flags = 0;
+ inet_csk_schedule_ack(sk);
+
+ SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n",
+ tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
+
+ skb1 = skb_peek_tail(&tp->out_of_order_queue);
+ if (!skb1) {
+ /* Initial out of order segment, build 1 SACK. */
+ if (tcp_is_sack(tp)) {
+ tp->rx_opt.num_sacks = 1;
+ tp->selective_acks[0].start_seq = TCP_SKB_CB(skb)->seq;
+ tp->selective_acks[0].end_seq =
+ TCP_SKB_CB(skb)->end_seq;
+ }
+ __skb_queue_head(&tp->out_of_order_queue, skb);
+ goto end;
+ }
+
+ seq = TCP_SKB_CB(skb)->seq;
+ end_seq = TCP_SKB_CB(skb)->end_seq;
+
+ if (seq == TCP_SKB_CB(skb1)->end_seq) {
+ __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
+
+ if (!tp->rx_opt.num_sacks ||
+ tp->selective_acks[0].end_seq != seq)
+ goto add_sack;
+
+ /* Common case: data arrive in order after hole. */
+ tp->selective_acks[0].end_seq = end_seq;
+ goto end;
+ }
+
+ /* Find place to insert this segment. */
+ while (1) {
+ if (!after(TCP_SKB_CB(skb1)->seq, seq))
+ break;
+ if (skb_queue_is_first(&tp->out_of_order_queue, skb1)) {
+ skb1 = NULL;
+ break;
+ }
+ skb1 = skb_queue_prev(&tp->out_of_order_queue, skb1);
+ }
+
+ /* Do skb overlap to previous one? */
+ if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) {
+ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
+ /* All the bits are present. Drop. */
+ __kfree_skb(skb);
+ skb = NULL;
+ tcp_dsack_set(sk, seq, end_seq);
+ goto add_sack;
+ }
+ if (after(seq, TCP_SKB_CB(skb1)->seq)) {
+ /* Partial overlap. */
+ tcp_dsack_set(sk, seq,
+ TCP_SKB_CB(skb1)->end_seq);
+ } else {
+ if (skb_queue_is_first(&tp->out_of_order_queue,
+ skb1))
+ skb1 = NULL;
+ else
+ skb1 = skb_queue_prev(
+ &tp->out_of_order_queue,
+ skb1);
+ }
+ }
+ if (!skb1)
+ __skb_queue_head(&tp->out_of_order_queue, skb);
+ else
+ __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
+
+ /* And clean segments covered by new one as whole. */
+ while (!skb_queue_is_last(&tp->out_of_order_queue, skb)) {
+ skb1 = skb_queue_next(&tp->out_of_order_queue, skb);
+
+ if (!after(end_seq, TCP_SKB_CB(skb1)->seq))
+ break;
+ if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
+ tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
+ end_seq);
+ break;
+ }
+ __skb_unlink(skb1, &tp->out_of_order_queue);
+ tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
+ TCP_SKB_CB(skb1)->end_seq);
+ __kfree_skb(skb1);
+ }
+
+add_sack:
+ if (tcp_is_sack(tp))
+ tcp_sack_new_ofo_skb(sk, seq, end_seq);
+end:
+ if (skb)
+ skb_set_owner_r(skb, sk);
+}
+
+
static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
{
const struct tcphdr *th = tcp_hdr(skb);
@@ -4561,105 +4675,7 @@ drop:
goto queue_and_out;
}
- TCP_ECN_check_ce(tp, skb);
-
- if (tcp_try_rmem_schedule(sk, skb->truesize))
- goto drop;
-
- /* Disable header prediction. */
- tp->pred_flags = 0;
- inet_csk_schedule_ack(sk);
-
- SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n",
- tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
-
- skb_set_owner_r(skb, sk);
-
- if (!skb_peek(&tp->out_of_order_queue)) {
- /* Initial out of order segment, build 1 SACK. */
- if (tcp_is_sack(tp)) {
- tp->rx_opt.num_sacks = 1;
- tp->selective_acks[0].start_seq = TCP_SKB_CB(skb)->seq;
- tp->selective_acks[0].end_seq =
- TCP_SKB_CB(skb)->end_seq;
- }
- __skb_queue_head(&tp->out_of_order_queue, skb);
- } else {
- struct sk_buff *skb1 = skb_peek_tail(&tp->out_of_order_queue);
- u32 seq = TCP_SKB_CB(skb)->seq;
- u32 end_seq = TCP_SKB_CB(skb)->end_seq;
-
- if (seq == TCP_SKB_CB(skb1)->end_seq) {
- __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
-
- if (!tp->rx_opt.num_sacks ||
- tp->selective_acks[0].end_seq != seq)
- goto add_sack;
-
- /* Common case: data arrive in order after hole. */
- tp->selective_acks[0].end_seq = end_seq;
- return;
- }
-
- /* Find place to insert this segment. */
- while (1) {
- if (!after(TCP_SKB_CB(skb1)->seq, seq))
- break;
- if (skb_queue_is_first(&tp->out_of_order_queue, skb1)) {
- skb1 = NULL;
- break;
- }
- skb1 = skb_queue_prev(&tp->out_of_order_queue, skb1);
- }
-
- /* Do skb overlap to previous one? */
- if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) {
- if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
- /* All the bits are present. Drop. */
- __kfree_skb(skb);
- tcp_dsack_set(sk, seq, end_seq);
- goto add_sack;
- }
- if (after(seq, TCP_SKB_CB(skb1)->seq)) {
- /* Partial overlap. */
- tcp_dsack_set(sk, seq,
- TCP_SKB_CB(skb1)->end_seq);
- } else {
- if (skb_queue_is_first(&tp->out_of_order_queue,
- skb1))
- skb1 = NULL;
- else
- skb1 = skb_queue_prev(
- &tp->out_of_order_queue,
- skb1);
- }
- }
- if (!skb1)
- __skb_queue_head(&tp->out_of_order_queue, skb);
- else
- __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
-
- /* And clean segments covered by new one as whole. */
- while (!skb_queue_is_last(&tp->out_of_order_queue, skb)) {
- skb1 = skb_queue_next(&tp->out_of_order_queue, skb);
-
- if (!after(end_seq, TCP_SKB_CB(skb1)->seq))
- break;
- if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
- tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
- end_seq);
- break;
- }
- __skb_unlink(skb1, &tp->out_of_order_queue);
- tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
- TCP_SKB_CB(skb1)->end_seq);
- __kfree_skb(skb1);
- }
-
-add_sack:
- if (tcp_is_sack(tp))
- tcp_sack_new_ofo_skb(sk, seq, end_seq);
- }
+ tcp_data_queue_ofo(sk, skb);
}
static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb,
^ permalink raw reply related
* Re: [PATCH net-next 1/3] gianfar: Add support for byte queue limits.
From: Paul Gortmaker @ 2012-03-18 21:04 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem, therbert, netdev, linuxppc-dev
In-Reply-To: <1332102032.3722.53.camel@edumazet-laptop>
On Sun, Mar 18, 2012 at 4:20 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le dimanche 18 mars 2012 à 12:56 -0400, Paul Gortmaker a écrit :
>
> ...
>
>> * we add this skb back into the pool, if it's the right size
>> @@ -2557,13 +2568,15 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
>> }
>>
>> /* If we freed a buffer, we can restart transmission, if necessary */
>> - if (__netif_subqueue_stopped(dev, tx_queue->qindex) && tx_queue->num_txbdfree)
>> - netif_wake_subqueue(dev, tx_queue->qindex);
>> + if (__netif_subqueue_stopped(dev, tqi) && tx_queue->num_txbdfree)
>> + netif_wake_subqueue(dev, tqi);
>>
>
> You can use netif_tx_queue_stopped(txq) here instead of
> __netif_subqueue_stopped(dev, tqi)
Yes, and it looks better too. I will do it as a patch #4 since I think
there is some small value in leaving the above patch chunk alone,
since it makes it clear that it was just the introduction of a local
variable and the code was otherwise unchanged here.
Will resend shortly....
Thanks,
Paul.
---
>
>> /* Update dirty indicators */
>> tx_queue->skb_dirtytx = skb_dirtytx;
>> tx_queue->dirty_tx = bdp;
>>
>> + netdev_tx_completed_queue(txq, howmany, bytes_sent);
>> +
>> return howmany;
>> }
>>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2 net-next] phy: add am79c874 PHY support
From: Anatolij Gustschin @ 2012-03-18 21:03 UTC (permalink / raw)
To: netdev, davem; +Cc: Heiko Schocher
From: Heiko Schocher <hs@denx.de>
Signed-off-by: Heiko Schocher <hs@denx.de>
Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
Changes since initial patch version (was only on linuxppc-dev list):
- slightly rework function names and rename driver file to amd.c
- remove not needed includes
- fix interrupt initialization
- add module device ID table
drivers/net/phy/Kconfig | 5 ++
drivers/net/phy/Makefile | 1 +
drivers/net/phy/amd.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 108 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/phy/amd.c
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index fbdcdf8..0e01f4e 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -15,6 +15,11 @@ if PHYLIB
comment "MII PHY device drivers"
+config AMD_PHY
+ tristate "Drivers for the AMD PHYs"
+ ---help---
+ Currently supports the am79c874
+
config MARVELL_PHY
tristate "Drivers for Marvell PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index e15c83f..b7438b1 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_STE10XP) += ste10Xp.o
obj-$(CONFIG_MICREL_PHY) += micrel.o
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
+obj-$(CONFIG_AMD_PHY) += amd.o
diff --git a/drivers/net/phy/amd.c b/drivers/net/phy/amd.c
new file mode 100644
index 0000000..cfabd5f
--- /dev/null
+++ b/drivers/net/phy/amd.c
@@ -0,0 +1,102 @@
+/*
+ * Driver for AMD am79c PHYs
+ *
+ * Author: Heiko Schocher <hs@denx.de>
+ *
+ * Copyright (c) 2011 DENX Software Engineering GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#define PHY_ID_AM79C874 0x0022561b
+
+#define MII_AM79C_IR 17 /* Interrupt Status/Control Register */
+#define MII_AM79C_IR_EN_LINK 0x0400 /* IR enable Linkstate */
+#define MII_AM79C_IR_EN_ANEG 0x0100 /* IR enable Aneg Complete */
+#define MII_AM79C_IR_IMASK_INIT (MII_AM79C_IR_EN_LINK | MII_AM79C_IR_EN_ANEG)
+
+MODULE_DESCRIPTION("AMD PHY driver");
+MODULE_AUTHOR("Heiko Schocher <hs@denx.de>");
+MODULE_LICENSE("GPL");
+
+static int am79c_ack_interrupt(struct phy_device *phydev)
+{
+ int err;
+
+ err = phy_read(phydev, MII_BMSR);
+ if (err < 0)
+ return err;
+
+ err = phy_read(phydev, MII_AM79C_IR);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int am79c_config_init(struct phy_device *phydev)
+{
+ return 0;
+}
+
+static int am79c_config_intr(struct phy_device *phydev)
+{
+ int err;
+
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+ err = phy_write(phydev, MII_AM79C_IR, MII_AM79C_IR_IMASK_INIT);
+ else
+ err = phy_write(phydev, MII_AM79C_IR, 0);
+
+ return err;
+}
+
+static struct phy_driver am79c_driver = {
+ .phy_id = PHY_ID_AM79C874,
+ .name = "AM79C874",
+ .phy_id_mask = 0xfffffff0,
+ .features = PHY_BASIC_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = am79c_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+ .ack_interrupt = am79c_ack_interrupt,
+ .config_intr = am79c_config_intr,
+ .driver = { .owner = THIS_MODULE,},
+};
+
+static int __init am79c_init(void)
+{
+ int ret;
+
+ ret = phy_driver_register(&am79c_driver);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void __exit am79c_exit(void)
+{
+ phy_driver_unregister(&am79c_driver);
+}
+
+module_init(am79c_init);
+module_exit(am79c_exit);
+
+static struct mdio_device_id __maybe_unused amd_tbl[] = {
+ { PHY_ID_AM79C874, 0xfffffff0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(mdio, amd_tbl);
--
1.7.7.6
^ permalink raw reply related
* Re: netfilter: Hung task
From: Sasha Levin @ 2012-03-18 20:52 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: kaber, davem, Dave Jones, netfilter-devel,
linux-kernel@vger.kernel.org List, netdev
In-Reply-To: <20120318141943.GA28850@1984>
On Sun, Mar 18, 2012 at 4:19 PM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Sun, Mar 18, 2012 at 12:55:13PM +0200, Sasha Levin wrote:
>> Hi all,
>>
>> I got the following spew after fuzzing using trinity on a KVM tools
>> guest, using the latest linux-next.
>>
>> It reminds me a lot of https://lkml.org/lkml/2012/3/14/375 and
>> https://lkml.org/lkml/2012/1/14/45
>
> You mention neither Linux kernel version nor the way you trigger this.
>
> With that little information it's really hard to really know.
Hum? I've mentioned it happened with "the latest linux-next" (which is
currently two days old), and using the trinity fuzzer - which means
that I don't have a specific method to reproduce the problem.
> Time ago we applied this to Netfilter which is already in mainline:
>
> http://git.kernel.org/?p=linux/kernel/git/davem/net.git;a=commit;h=70e9942f17a6193e9172a804e6569a8806633d6b
FWIW, that patch is part of linux-next.
^ permalink raw reply
* Re: [PATCH net-next 0/3] Gianfar byte queue limits
From: Paul Gortmaker @ 2012-03-18 20:50 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem, therbert, netdev, linuxppc-dev
In-Reply-To: <1332102634.3647.1.camel@edumazet-laptop>
On Sun, Mar 18, 2012 at 4:30 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le dimanche 18 mars 2012 à 12:56 -0400, Paul Gortmaker a écrit :
>> The BQL support here is unchanged from what I posted earlier as an
>> RFC[1] -- with the exception of the fact that I'm now happier with
>> the runtime testing vs. the simple "hey it boots" that I'd done
>> for the RFC. Plus I added a couple trivial cleanup patches.
>>
>> For testing, I made a couple spiders homeless by reviving an ancient
>> 10baseT hub. I connected an sbc8349 into that, and connected the
>> yellowing hub into a GigE 16port, which was also connected to the
>> recipient x86 box.
>>
>> Gianfar saw the interface as follows:
>>
>> fsl-gianfar e0024000.ethernet: eth0: mac: 00:a0:1e:a0:26:5a
>> fsl-gianfar e0024000.ethernet: eth0: Running with NAPI enabled
>> fsl-gianfar e0024000.ethernet: eth0: RX BD ring size for Q[0]: 256
>> fsl-gianfar e0024000.ethernet: eth0: TX BD ring size for Q[0]: 256
>> PHY: mdio@e0024520:19 - Link is Up - 10/Half
>>
>> With the sbc8349 being diskless, I simply used an scp of /proc/kcore
>> to the connected x86 box as a rudimentary Tx heavy workload.
>>
>> BQL data was collected by changing into the dir:
>>
>> /sys/devices/e0000000.soc8349/e0024000.ethernet/net/eth0/queues/tx-0/byte_queue_limits
>>
>> and running the following:
>>
>> for i in * ; do echo -n $i": " ; cat $i ; done
>>
>> Running with the defaults, data like below was typical:
>>
>> hold_time: 1000
>> inflight: 4542
>> limit: 3456
>> limit_max: 1879048192
>> limit_min: 0
>>
>> hold_time: 1000
>> inflight: 4542
>> limit: 3378
>> limit_max: 1879048192
>> limit_min: 0
>>
>> i.e. 2 or 3 MTU sized packets in flight and the limit value lying
>> somewhere between those two values.
>>
>> The interesting thing is that the interactive speed reported by scp
>> seemed somewhat erratic, ranging from ~450 to ~700kB/s. (This was
>> the only traffic on the old junk - perhaps expected oscillations such
>> as those seen in isolated ARED tests?) Average speed for 100M was:
>>
>> 104857600 bytes (105 MB) copied, 172.616 s, 607 kB/s
>>
>
> Still half duplex, or full duplex ?
>
> Limiting to one packet on half duplex might avoid collisions :)
Ah yes. It was even in the text I'd had above!
PHY: mdio@e0024520:19 - Link is Up - 10/Half
Now the slowdown makes sense to me.
Thanks for the review as well.
Paul.
>
>> Anyway, back to BQL testing; setting the values as follows:
>>
>> hold_time: 1000
>> inflight: 1514
>> limit: 1400
>> limit_max: 1400
>> limit_min: 1000
>>
>> had the effect of serializing the interface to a single packet, and
>> the crusty old hub seemed much happier with this arrangement, keeping
>> a constant speed and achieving the following on a 100MB Tx block:
>>
>> 104857600 bytes (105 MB) copied, 112.52 s, 932 kB/s
>>
>> It might be interesting to know more about why the defaults suffer
>> the slowdown, but the hub could possibly be ancient spec violating
>> trash. Definitely something that nobody would ever use for anything
>> today. (aside from contrived tests like this)
>>
>> But it did give me an example of where I could see the effects of
>> changing the BQL settings, and I'm reasonably confident they are
>> working as expected.
>>
>
> Seems pretty good to me !
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next 0/3] Gianfar byte queue limits
From: Eric Dumazet @ 2012-03-18 20:30 UTC (permalink / raw)
To: Paul Gortmaker; +Cc: davem, therbert, netdev, linuxppc-dev
In-Reply-To: <1332089787-24086-1-git-send-email-paul.gortmaker@windriver.com>
Le dimanche 18 mars 2012 à 12:56 -0400, Paul Gortmaker a écrit :
> The BQL support here is unchanged from what I posted earlier as an
> RFC[1] -- with the exception of the fact that I'm now happier with
> the runtime testing vs. the simple "hey it boots" that I'd done
> for the RFC. Plus I added a couple trivial cleanup patches.
>
> For testing, I made a couple spiders homeless by reviving an ancient
> 10baseT hub. I connected an sbc8349 into that, and connected the
> yellowing hub into a GigE 16port, which was also connected to the
> recipient x86 box.
>
> Gianfar saw the interface as follows:
>
> fsl-gianfar e0024000.ethernet: eth0: mac: 00:a0:1e:a0:26:5a
> fsl-gianfar e0024000.ethernet: eth0: Running with NAPI enabled
> fsl-gianfar e0024000.ethernet: eth0: RX BD ring size for Q[0]: 256
> fsl-gianfar e0024000.ethernet: eth0: TX BD ring size for Q[0]: 256
> PHY: mdio@e0024520:19 - Link is Up - 10/Half
>
> With the sbc8349 being diskless, I simply used an scp of /proc/kcore
> to the connected x86 box as a rudimentary Tx heavy workload.
>
> BQL data was collected by changing into the dir:
>
> /sys/devices/e0000000.soc8349/e0024000.ethernet/net/eth0/queues/tx-0/byte_queue_limits
>
> and running the following:
>
> for i in * ; do echo -n $i": " ; cat $i ; done
>
> Running with the defaults, data like below was typical:
>
> hold_time: 1000
> inflight: 4542
> limit: 3456
> limit_max: 1879048192
> limit_min: 0
>
> hold_time: 1000
> inflight: 4542
> limit: 3378
> limit_max: 1879048192
> limit_min: 0
>
> i.e. 2 or 3 MTU sized packets in flight and the limit value lying
> somewhere between those two values.
>
> The interesting thing is that the interactive speed reported by scp
> seemed somewhat erratic, ranging from ~450 to ~700kB/s. (This was
> the only traffic on the old junk - perhaps expected oscillations such
> as those seen in isolated ARED tests?) Average speed for 100M was:
>
> 104857600 bytes (105 MB) copied, 172.616 s, 607 kB/s
>
Still half duplex, or full duplex ?
Limiting to one packet on half duplex might avoid collisions :)
> Anyway, back to BQL testing; setting the values as follows:
>
> hold_time: 1000
> inflight: 1514
> limit: 1400
> limit_max: 1400
> limit_min: 1000
>
> had the effect of serializing the interface to a single packet, and
> the crusty old hub seemed much happier with this arrangement, keeping
> a constant speed and achieving the following on a 100MB Tx block:
>
> 104857600 bytes (105 MB) copied, 112.52 s, 932 kB/s
>
> It might be interesting to know more about why the defaults suffer
> the slowdown, but the hub could possibly be ancient spec violating
> trash. Definitely something that nobody would ever use for anything
> today. (aside from contrived tests like this)
>
> But it did give me an example of where I could see the effects of
> changing the BQL settings, and I'm reasonably confident they are
> working as expected.
>
Seems pretty good to me !
^ permalink raw reply
* Re: Kernel Panic with bonding + IPoIB on 3.2.9
From: Joseph Glanville @ 2012-03-18 20:21 UTC (permalink / raw)
To: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAOzFzEiufg40gKBH6D7zeB47SebfPvgzqOLxhF5eQqpYd-r4zQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 19 March 2012 06:41, Joseph Glanville
<joseph.glanville-2MxvZkOi9dvvnOemgxGiVw@public.gmane.org> wrote:
> Hi guys,
>
> I am getting an annoying kernel panic on 3.2.9 that seems to be
> related to bonding (as I can't reproduce the crash without it)
> I believe it might be related to LRO/GRO but there isnt a param to
> disable it anymore that I could see in /ulp/ipoib/
> Let me know if there is anything further I can do to help debug.
>
> Useful information:
>
> Hardware:
> Dell C2100 - Intel Xeon dual socket with 144GB RAM
> Mellanox Connect-X DDR using in kernel mlx4 driver
> Machine is also a Xen dom0
>
> ibstatCA 'mlx4_0'
> CA type: MT26418
> Number of ports: 2
> Firmware version: 2.9.1000
> Hardware version: a0
> Node GUID: 0x0002c9030008d7be
> System image GUID: 0x0002c9030008d7c1
> Port 1:
> State: Active
> Physical state: LinkUp
> Rate: 20
> Base lid: 6
> LMC: 0
> SM lid: 1
> Capability mask: 0x02590868
> Port GUID: 0x0002c9030008d7bf
> Link layer: InfiniBand
> Port 2:
> State: Active
> Physical state: LinkUp
> Rate: 20
> Base lid: 9
> LMC: 0
> SM lid: 1
> Capability mask: 0x02590868
> Port GUID: 0x0002c9030008d7c0
> Link layer: InfiniBand
>
>
> ip link show
> 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
> link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
> 2: ib0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 65220 qdisc
> pfifo_fast master bond0 state UP qlen 256
> link/infiniband
> 80:00:00:48:fe:80:00:00:00:00:00:00:00:02:c9:03:00:08:d7:bf brd
> 00:ff:ff:ff:ff:12:40:1b:ff:ff:00:00:00:00:00:00:ff:ff:ff:ff
> 3: ib1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 65220 qdisc
> pfifo_fast master bond0 state UP qlen 256
> link/infiniband
> 80:00:00:49:fe:80:00:00:00:00:00:00:00:02:c9:03:00:08:d7:c0 brd
> 00:ff:ff:ff:ff:12:40:1b:ff:ff:00:00:00:00:00:00:ff:ff:ff:ff
> 4: gre0: <NOARP> mtu 1476 qdisc noop state DOWN
> link/gre 0.0.0.0 brd 0.0.0.0
> 5: sit0: <NOARP> mtu 1480 qdisc noop state DOWN
> link/sit 0.0.0.0 brd 0.0.0.0
> 6: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 65220 qdisc
> noqueue state UP
> link/infiniband
> 80:00:00:48:fe:80:00:00:00:00:00:00:00:02:c9:03:00:08:d7:bf brd
> 00:ff:ff:ff:ff:12:40:1b:ff:ff:00:00:00:00:00:00:ff:ff:ff:f
>
> The KP itself:
> [ 422.046837] ------------[ cut here ]------------
> [ 422.047024] kernel BUG at net/core/dev.c:1896!
> [ 422.047126] invalid opcode: 0000 [#1] SMP
> [ 422.047289] CPU 1
> [ 422.047328] Modules linked in: ib_srpt(O) scst_vdisk(O) scst(O)
> bonding raid1 raid0 md_mod dm_multipath
> [ 422.047869]
> [ 422.047962] Pid: 3352, comm: sshd Tainted: G O
> 3.2.1-orion #4 Dell PowerEdge C2100 /0P19C9
> [ 422.048237] RIP: e030:[<ffffffff81559b92>] [<ffffffff81559b92>]
> skb_checksum_help+0x142/0x150
> [ 422.048450] RSP: e02b:ffff88006cb11758 EFLAGS: 00010282
> [ 422.048556] RAX: 0000000000000108 RBX: ffff880072f7f4e8 RCX: 0000000060004420
> [ 422.048668] RDX: 0000000000000108 RSI: 0000000000000000 RDI: ffff880072f7f4e8
> [ 422.048780] RBP: ffff88006cb11778 R08: ffff88000e53529c R09: 0000000000000104
> [ 422.048892] R10: ffffffff8151a7d0 R11: 0000000000000000 R12: 00000000ffff0018
> [ 422.049005] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> [ 422.049119] FS: 00007fea22aa8700(0000) GS:ffff8800bf435000(0000)
> knlGS:0000000000000000
> [ 422.049288] CS: e033 DS: 0000 ES: 0000 CR0: 000000008005003b
> [ 422.049395] CR2: 00007fff14d07ed8 CR3: 00000000085dc000 CR4: 0000000000002660
> [ 422.049506] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [ 422.049618] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> [ 422.049742] Process sshd (pid: 3352, threadinfo ffff88006cb10000,
> task ffff88000cea4920)
> [ 422.049909] Stack:
> [ 422.050002] ffff880072f7f4e8 ffff88000ce64000 0000000000000000
> 0000000000000000
> [ 422.050290] ffff88006cb117e8 ffffffff8155f15e ffff88006cb11858
> ffffffff8187ba80
> [ 422.050580] ffff88000ce5bc80 0000000000000000 0000000000000006
> 0000000000000000
> [ 422.050869] Call Trace:
> [ 422.050967] [<ffffffff8155f15e>] dev_hard_start_xmit+0x36e/0x6c0
> [ 422.051084] [<ffffffff8157a19b>] sch_direct_xmit+0xdb/0x1e0
> [ 422.051191] [<ffffffff8155f638>] dev_queue_xmit+0x188/0x620
> [ 422.051301] [<ffffffffa003b297>] bond_dev_queue_xmit+0x27/0x70 [bonding]
> [ 422.051413] [<ffffffffa003b5e4>] bond_start_xmit+0x304/0x4e0 [bonding]
> [ 422.051524] [<ffffffff8155f099>] dev_hard_start_xmit+0x2a9/0x6c0
> [ 422.051633] [<ffffffff8155f895>] dev_queue_xmit+0x3e5/0x620
> [ 422.051742] [<ffffffff81567cbd>] neigh_connected_output+0xbd/0xf0
> [ 422.051853] [<ffffffff815a7120>] ? ip_fragment+0x850/0x850
> [ 422.051960] [<ffffffff815a72ae>] ip_finish_output+0x18e/0x300
> [ 422.052068] [<ffffffff815a7dd8>] ip_output+0x98/0xa0
> [ 422.052172] [<ffffffff815a74be>] ? __ip_local_out+0x9e/0xa0
> [ 422.052279] [<ffffffff815a74e4>] ip_local_out+0x24/0x30
> [ 422.052385] [<ffffffff815a764a>] ip_queue_xmit+0x15a/0x400
> [ 422.052510] [<ffffffff815bdade>] tcp_transmit_skb+0x3de/0x8f0
> [ 422.052617] [<ffffffff815be702>] tcp_write_xmit+0x1d2/0x9c0
> [ 422.052725] [<ffffffff81129057>] ? ksize+0x17/0xc0
> [ 422.052829] [<ffffffff815bef41>] __tcp_push_pending_frames+0x21/0x90
> [ 422.052939] [<ffffffff815b09ae>] tcp_sendmsg+0x75e/0xd80
> [ 422.053047] [<ffffffff815d4c0f>] inet_sendmsg+0x5f/0xb0
> [ 422.053155] [<ffffffff81009f3f>] ? xen_restore_fl_direct_reloc+0x4/0x4
> [ 422.053267] [<ffffffff8126734e>] ? selinux_socket_sendmsg+0x1e/0x20
> [ 422.053377] [<ffffffff8154732a>] sock_aio_write+0x15a/0x170
> [ 422.053486] [<ffffffff812652d1>] ? inode_has_perm.clone.15+0x21/0x30
> [ 422.053597] [<ffffffff8113133a>] do_sync_write+0xda/0x120
> [ 422.053704] [<ffffffff81268003>] ? selinux_file_permission+0xb3/0x140
> [ 422.053821] [<ffffffff812e8efa>] ? put_ldisc+0x5a/0xc0
> [ 422.053937] [<ffffffff81262237>] ? security_file_permission+0x27/0xb0
> [ 422.054048] [<ffffffff81131ca9>] vfs_write+0x169/0x180
> [ 422.054153] [<ffffffff81131f1c>] sys_write+0x4c/0x90
> [ 422.054260] [<ffffffff816891d2>] system_call_fastpath+0x16/0x1b
> [ 422.054367] Code: 65 86 ff ff 85 c0 0f 84 75 ff ff ff eb a6 41 29
> d4 48 8b 83 d8 00 00 00 0f b7 53 72 45 8d 64 04 02 41 39 d4 77 cd e9
> 5d ff ff ff <0f> 0b 0f 0b 66 2e 0f 1f 84 00 00 00 00 00 55 b8 ea ff ff
> ff 48
> [ 422.056691] RIP [<ffffffff81559b92>] skb_checksum_help+0x142/0x150
> [ 422.056831] RSP <ffff88006cb11758>
> [ 422.056930] ---[ end trace 751906f8ee2b0c91 ]---
> [ 422.057032] Kernel panic - not syncing: Fatal exception in interrupt
> [ 422.057141] Pid: 3352, comm: sshd Tainted: G D O 3.2.1-orion #4
> [ 422.057250] Call Trace:
> [ 422.057348] [<ffffffff8167e944>] panic+0x8c/0x1a0
> [ 422.057451] [<ffffffff816825fa>] oops_end+0xea/0xf0
> [ 422.057557] [<ffffffff81016636>] die+0x56/0x90
> [ 422.057660] [<ffffffff81681f64>] do_trap+0xc4/0x170
> [ 422.057764] [<ffffffff81013e50>] do_invalid_op+0x90/0xb0
> [ 422.057870] [<ffffffff81559b92>] ? skb_checksum_help+0x142/0x150
> [ 422.057989] [<ffffffff8168b1ab>] invalid_op+0x1b/0x20
> [ 422.058101] [<ffffffff8151a7d0>] ? ipoib_setup+0x330/0x330
> [ 422.058207] [<ffffffff81559b92>] ? skb_checksum_help+0x142/0x150
> [ 422.058316] [<ffffffff8155f15e>] dev_hard_start_xmit+0x36e/0x6c0
> [ 422.058425] [<ffffffff8157a19b>] sch_direct_xmit+0xdb/0x1e0
> [ 422.058533] [<ffffffff8155f638>] dev_queue_xmit+0x188/0x620
> [ 422.058641] [<ffffffffa003b297>] bond_dev_queue_xmit+0x27/0x70 [bonding]
> [ 422.058753] [<ffffffffa003b5e4>] bond_start_xmit+0x304/0x4e0 [bonding]
> [ 422.058864] [<ffffffff8155f099>] dev_hard_start_xmit+0x2a9/0x6c0
> [ 422.058973] [<ffffffff8155f895>] dev_queue_xmit+0x3e5/0x620
> [ 422.059080] [<ffffffff81567cbd>] neigh_connected_output+0xbd/0xf0
> [ 422.059190] [<ffffffff815a7120>] ? ip_fragment+0x850/0x850
> [ 422.059296] [<ffffffff815a72ae>] ip_finish_output+0x18e/0x300
> [ 422.059412] [<ffffffff815a7dd8>] ip_output+0x98/0xa0
> [ 422.059517] [<ffffffff815a74be>] ? __ip_local_out+0x9e/0xa0
> [ 422.059624] [<ffffffff815a74e4>] ip_local_out+0x24/0x30
> [ 422.059730] [<ffffffff815a764a>] ip_queue_xmit+0x15a/0x400
> [ 422.059836] [<ffffffff815bdade>] tcp_transmit_skb+0x3de/0x8f0
> [ 422.059944] [<ffffffff815be702>] tcp_write_xmit+0x1d2/0x9c0
>
> --
> Founder | Director | VP Research
> Orion Virtualisation Solutions | www.orionvm.com.au | Phone: 1300 56
> 99 52 | Mobile: 0428 754 846
CC'ing netdev as that is probably the most appropriate now that I
think about it.
--
Founder | Director | VP Research
Orion Virtualisation Solutions | www.orionvm.com.au | Phone: 1300 56
99 52 | Mobile: 0428 754 846
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next 1/3] gianfar: Add support for byte queue limits.
From: Eric Dumazet @ 2012-03-18 20:20 UTC (permalink / raw)
To: Paul Gortmaker; +Cc: davem, therbert, netdev, linuxppc-dev
In-Reply-To: <1332089787-24086-2-git-send-email-paul.gortmaker@windriver.com>
Le dimanche 18 mars 2012 à 12:56 -0400, Paul Gortmaker a écrit :
...
> * we add this skb back into the pool, if it's the right size
> @@ -2557,13 +2568,15 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
> }
>
> /* If we freed a buffer, we can restart transmission, if necessary */
> - if (__netif_subqueue_stopped(dev, tx_queue->qindex) && tx_queue->num_txbdfree)
> - netif_wake_subqueue(dev, tx_queue->qindex);
> + if (__netif_subqueue_stopped(dev, tqi) && tx_queue->num_txbdfree)
> + netif_wake_subqueue(dev, tqi);
>
You can use netif_tx_queue_stopped(txq) here instead of
__netif_subqueue_stopped(dev, tqi)
> /* Update dirty indicators */
> tx_queue->skb_dirtytx = skb_dirtytx;
> tx_queue->dirty_tx = bdp;
>
> + netdev_tx_completed_queue(txq, howmany, bytes_sent);
> +
> return howmany;
> }
>
^ permalink raw reply
* Re: tun oops dereferencing garbage nsproxy-> address.
From: Maciej Rutecki @ 2012-03-18 20:02 UTC (permalink / raw)
To: Dave Jones; +Cc: netdev, Linux Kernel, serue, ebiederm
In-Reply-To: <20120313034201.GA13156@redhat.com>
On wtorek, 13 marca 2012 o 04:42:02 Dave Jones wrote:
> BUG: unable to handle kernel paging request at 0000000100000029
> IP: [<ffffffffa06ec54f>] tun_chr_open+0x4f/0x80 [tun]
> PGD 5ae4f067 PUD 0
> Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
> CPU 1
> Modules linked in: tun binfmt_misc can_bcm cmtp kernelcapi nfnetlink bnep
> can_raw af_802154 phonet bluetooth can pppoe pppox ppp_generic slhc irda
> crc_ccitt rds af_key rose ax25 appletalk atm ipx p8022 psnap llc p8023
> tcp_lp iwlwifi mac80211 cfg80211 nfs fscache auth_rpcgss nfs_acl fuse
> lockd ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter
> ip6_tables nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack xts
> gf128mul dm_crypt dm_mirror dm_region_hash dm_log arc4 snd_hda_codec_hdmi
> uvcvideo snd_hda_codec_idt videobuf2_core snd_usb_audio snd_hda_intel
> videodev snd_hda_codec dell_wmi sparse_keymap media snd_usbmidi_lib
> snd_hwdep v4l2_compat_ioctl32 snd_rawmidi cdc_ether videobuf2_vmalloc
> videobuf2_memops snd_seq usbnet cdc_wdm mii cdc_acm snd_seq_device snd_pcm
> dell_laptop dcdbas joydev microcode snd_timer tg3 snd pcspkr i2c_i801
> iTCO_wdt iTCO_vendor_support soundcore snd_page_alloc rfkill wmi sunrpc
> i915 drm_kms_helper drm i2c_algo_bit i2c_core video [last unloaded:
> cfg80211]
>
> Pid: 15413, comm: trinity Not tainted 3.3.0-rc7+ #54 Dell Inc. Adamo 13
> /0N70T0 RIP: 0010:[<ffffffffa06ec54f>] [<ffffffffa06ec54f>]
> tun_chr_open+0x4f/0x80 [tun] RSP: 0018:ffff8800a5e29bc8 EFLAGS: 00010286
> RAX: ffff88012036fd88 RBX: ffff8801084c4dc0 RCX: 0000000000000006
> RDX: 0000000100000001 RSI: ffff88000fd9abc8 RDI: 0000000000000292
> RBP: ffff8800a5e29bd8 R08: 0000000000000000 R09: 0000000000000001
> R10: 0000000000000000 R11: 0000000000000000 R12: ffff8801084c4dc0
> R13: ffff88012eb10d20 R14: ffffffffa06f0000 R15: ffffffff81856ae0
> FS: 00007f3ebcb1a700(0000) GS:ffff88013b400000(0000)
> knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000100000029 CR3: 00000000032bb000 CR4: 00000000000406e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> Process trinity (pid: 15413, threadinfo ffff8800a5e28000, task
> ffff88000fd9a4a0) Stack:
> 00000000000000c8 0000000000000000 ffff8800a5e29c38 ffffffff813fcf38
> ffffffff81c54838 0000000000000001 ffff8800a5e29c18 ffffffff816a1afd
> ffff8801084c4dc0 ffff8801396bbab8 ffff88012eb10d20 0000000000000000
> Call Trace:
> [<ffffffff813fcf38>] misc_open+0x1d8/0x670
> [<ffffffff816a1afd>] ? sub_preempt_count+0x9d/0xd0
> [<ffffffff811c2978>] chrdev_open+0x258/0x350
> [<ffffffff811baa04>] __dentry_open+0x384/0x550
> [<ffffffff816a1afd>] ? sub_preempt_count+0x9d/0xd0
> [<ffffffff811c2720>] ? cdev_put+0x30/0x30
> [<ffffffff811bc224>] nameidata_to_filp+0x74/0x80
> [<ffffffff811ce59c>] do_last+0x26c/0x930
> [<ffffffff811ced76>] path_openat+0xd6/0x3e0
> [<ffffffff810a6298>] ? sched_clock_cpu+0xb8/0x130
> [<ffffffff811cf1a2>] do_filp_open+0x42/0xa0
> [<ffffffff8169d845>] ? _raw_spin_unlock+0x35/0x60
> [<ffffffff811dd7cd>] ? alloc_fd+0x18d/0x210
> [<ffffffff811bc328>] do_sys_open+0xf8/0x1d0
> [<ffffffff810faadc>] ? __audit_syscall_entry+0xcc/0x310
> [<ffffffff811bc421>] sys_open+0x21/0x30
> [<ffffffff816a5a69>] system_call_fastpath+0x16/0x1b
> Code: 00 00 00 e8 64 8d ab e0 48 85 c0 74 46 c7 00 00 00 00 00 48 c7 40 08
> 00 00 00 00 65 48 8b 14 25 00 c9 00 00 48 8b 92 50 05 00 00 <48> 8b 52 28
> f0 ff 42 04 48 89 50 10 48 89 83 28 01 00 00 31 c0 RIP
> [<ffffffffa06ec54f>] tun_chr_open+0x4f/0x80 [tun]
> RSP <ffff8800a5e29bc8>
> CR2: 0000000100000029
> Disabling lock debugging due to kernel taint
> ---[ end trace 9e00e91b0629ad80 ]---
>
>
> oops happened here..
>
> tfile->net = get_net(current->nsproxy->net_ns);
> 548: 48 8b 92 50 05 00 00 mov 0x550(%rdx),%rdx
> 54f: 48 8b 52 28 mov 0x28(%rdx),%rdx
>
> My guess is the fuzzer called some syscall that set current->nsproxy
> to garbage (0x0000000100000001), which later got dereferenced when it
> subsequently randomly did an open() on tun.
>
> Any thoughts ?
>
> Dave
>
I created a Bugzilla entry at
https://bugzilla.kernel.org/show_bug.cgi?id=42960
for your bug/regression report, please add your address to the CC list in
there, thanks!
--
Maciej Rutecki
http://www.mrutecki.pl
^ permalink raw reply
* Re: [PATCH net-next] tcp: reduce out_of_order memory use
From: Eric Dumazet @ 2012-03-18 19:40 UTC (permalink / raw)
To: Neal Cardwell
Cc: David Miller, netdev, Tom Herbert, Ilpo Järvinen,
H.K. Jerry Chu, Yuchung Cheng
In-Reply-To: <CADVnQy=_Adr9xTd=7aUFT6m38YQ8V-V7KQc9c6L4nej-dfvekQ@mail.gmail.com>
On Sun, 2012-03-18 at 12:55 -0400, Neal Cardwell wrote:
>
> At this point in tcp_data_queue() we have already called
> skb_set_owner_r() to charge the full truesize to the socket. So
> probably we need to adjust rmem accounting variables to account for
> the fact that the memory corresponding to the overhead of the freed
> skb is now gone?
This is automatically done in the __kfree_skb(skb) call.
I thought of avoiding the skb_set_owner_r() but it was simpler to let
the code as is.
Thinking again, we might just defer it at the end of function if skb is
not NULL, but it adds a new conditional and a "returb;" must be changed
to "goto end;"
>
> The patch as written seems to only coalesce if the incoming skb fits
> immediately after the first skb in the ofo queue. If we're going to
> add logic to coalesce then it would be nice to also coalesce in the
> case where the skb falls immediately after any later skb in the ofo queue,
I tried this but it was almost never used code in my experiments.
Most of the times packets come in natural order (no OOO).
> i.e. at some point after the "Find place to insert this segment" loop,
> probably right before or after the "Do skb overlap to previous one?"
> check. Perhaps the coalescing logic could be factored out into its own
> little function, and called in either of the two places?
>
Absolutely, I was already working on splitting tcp_data_queue() in two
functions to reduce indentation level by one tabulation make it more
readable.
Yes, we probably can expand the coalescing logic to be able to cope with
OOO, so that not only we coalesce this skb with prior one in queue, but
also with next one if there is one.
> (BTW, a few lines are longer than 80 characters.)
This wont be the case once tcp_data_queue_ofo() is introduced.
I'll send a V2 with two patches.
1/2 tcp: introduce tcp_data_queue_ofo()
(No change, only code movement to make smaller code units)
2/2 tcp: reduce out_of_order memory use
(with the attempt to avoid the skb_set_owner_r()/__kfree_skb() as
you suggested)
Thanks !
^ permalink raw reply
* [PATCH net-next 3/3] gianfar: delete orphaned version strings and dead macros
From: Paul Gortmaker @ 2012-03-18 16:56 UTC (permalink / raw)
To: davem, eric.dumazet, therbert; +Cc: netdev, linuxppc-dev, Paul Gortmaker
In-Reply-To: <1332089787-24086-1-git-send-email-paul.gortmaker@windriver.com>
There were two version strings, and neither one was being used.
Also in the same proximity were some unused #define that were
left over from the past. Delete them all.
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
drivers/net/ethernet/freescale/gianfar.c | 3 ---
drivers/net/ethernet/freescale/gianfar.h | 3 ---
2 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index a4c934b..6e66cc3 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -104,10 +104,7 @@
#include "fsl_pq_mdio.h"
#define TX_TIMEOUT (1*HZ)
-#undef BRIEF_GFAR_ERRORS
-#undef VERBOSE_GFAR_ERRORS
-const char gfar_driver_name[] = "Gianfar Ethernet";
const char gfar_driver_version[] = "1.3";
static int gfar_enet_open(struct net_device *dev);
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
index 4fe0f34..fc2488a 100644
--- a/drivers/net/ethernet/freescale/gianfar.h
+++ b/drivers/net/ethernet/freescale/gianfar.h
@@ -78,11 +78,8 @@ struct ethtool_rx_list {
#define INCREMENTAL_BUFFER_SIZE 512
#define PHY_INIT_TIMEOUT 100000
-#define GFAR_PHY_CHANGE_TIME 2
-#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.2, "
#define DRV_NAME "gfar-enet"
-extern const char gfar_driver_name[];
extern const char gfar_driver_version[];
/* MAXIMUM NUMBER OF QUEUES SUPPORTED */
--
1.7.9.1
^ permalink raw reply related
* [PATCH net-next 1/3] gianfar: Add support for byte queue limits.
From: Paul Gortmaker @ 2012-03-18 16:56 UTC (permalink / raw)
To: davem, eric.dumazet, therbert; +Cc: netdev, linuxppc-dev, Paul Gortmaker
In-Reply-To: <1332089787-24086-1-git-send-email-paul.gortmaker@windriver.com>
Add support for byte queue limits (BQL), based on the similar
modifications made to intel/igb/igb_main.c from Eric Dumazet
in commit bdbc063129e811264cd6c311d8c2d9b95de01231
"igb: Add support for byte queue limits."
A local variable for tx_queue->qindex was introduced in
gfar_clean_tx_ring, since it is now used often enough to warrant it,
and it cleans up the readability somewhat as well.
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
drivers/net/ethernet/freescale/gianfar.c | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index adb0ae4..a4c934b 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -1755,9 +1755,12 @@ static void free_skb_resources(struct gfar_private *priv)
/* Go through all the buffer descriptors and free their data buffers */
for (i = 0; i < priv->num_tx_queues; i++) {
+ struct netdev_queue *txq;
tx_queue = priv->tx_queue[i];
+ txq = netdev_get_tx_queue(tx_queue->dev, tx_queue->qindex);
if(tx_queue->tx_skbuff)
free_skb_tx_queue(tx_queue);
+ netdev_tx_reset_queue(txq);
}
for (i = 0; i < priv->num_rx_queues; i++) {
@@ -2217,6 +2220,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
}
+ netdev_tx_sent_queue(txq, skb->len);
+
/*
* We can work in parallel with gfar_clean_tx_ring(), except
* when modifying num_txbdfree. Note that we didn't grab the lock
@@ -2460,6 +2465,7 @@ static void gfar_align_skb(struct sk_buff *skb)
static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
{
struct net_device *dev = tx_queue->dev;
+ struct netdev_queue *txq;
struct gfar_private *priv = netdev_priv(dev);
struct gfar_priv_rx_q *rx_queue = NULL;
struct txbd8 *bdp, *next = NULL;
@@ -2471,10 +2477,13 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
int frags = 0, nr_txbds = 0;
int i;
int howmany = 0;
+ int tqi = tx_queue->qindex;
+ unsigned int bytes_sent = 0;
u32 lstatus;
size_t buflen;
- rx_queue = priv->rx_queue[tx_queue->qindex];
+ rx_queue = priv->rx_queue[tqi];
+ txq = netdev_get_tx_queue(dev, tqi);
bdp = tx_queue->dirty_tx;
skb_dirtytx = tx_queue->skb_dirtytx;
@@ -2533,6 +2542,8 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
bdp = next_txbd(bdp, base, tx_ring_size);
}
+ bytes_sent += skb->len;
+
/*
* If there's room in the queue (limit it to rx_buffer_size)
* we add this skb back into the pool, if it's the right size
@@ -2557,13 +2568,15 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
}
/* If we freed a buffer, we can restart transmission, if necessary */
- if (__netif_subqueue_stopped(dev, tx_queue->qindex) && tx_queue->num_txbdfree)
- netif_wake_subqueue(dev, tx_queue->qindex);
+ if (__netif_subqueue_stopped(dev, tqi) && tx_queue->num_txbdfree)
+ netif_wake_subqueue(dev, tqi);
/* Update dirty indicators */
tx_queue->skb_dirtytx = skb_dirtytx;
tx_queue->dirty_tx = bdp;
+ netdev_tx_completed_queue(txq, howmany, bytes_sent);
+
return howmany;
}
--
1.7.9.1
^ permalink raw reply related
* [PATCH net-next 2/3] gianfar: constify giant block of status descriptor strings
From: Paul Gortmaker @ 2012-03-18 16:56 UTC (permalink / raw)
To: davem, eric.dumazet, therbert; +Cc: netdev, linuxppc-dev, Paul Gortmaker
In-Reply-To: <1332089787-24086-1-git-send-email-paul.gortmaker@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
drivers/net/ethernet/freescale/gianfar_ethtool.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c
index 5a78d55..8d74efd 100644
--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
+++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
@@ -58,7 +58,7 @@ static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rv
static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals);
static void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo);
-static char stat_gstrings[][ETH_GSTRING_LEN] = {
+static const char stat_gstrings[][ETH_GSTRING_LEN] = {
"rx-dropped-by-kernel",
"rx-large-frame-errors",
"rx-short-frame-errors",
--
1.7.9.1
^ permalink raw reply related
* [PATCH net-next 0/3] Gianfar byte queue limits
From: Paul Gortmaker @ 2012-03-18 16:56 UTC (permalink / raw)
To: davem, eric.dumazet, therbert; +Cc: netdev, linuxppc-dev, Paul Gortmaker
The BQL support here is unchanged from what I posted earlier as an
RFC[1] -- with the exception of the fact that I'm now happier with
the runtime testing vs. the simple "hey it boots" that I'd done
for the RFC. Plus I added a couple trivial cleanup patches.
For testing, I made a couple spiders homeless by reviving an ancient
10baseT hub. I connected an sbc8349 into that, and connected the
yellowing hub into a GigE 16port, which was also connected to the
recipient x86 box.
Gianfar saw the interface as follows:
fsl-gianfar e0024000.ethernet: eth0: mac: 00:a0:1e:a0:26:5a
fsl-gianfar e0024000.ethernet: eth0: Running with NAPI enabled
fsl-gianfar e0024000.ethernet: eth0: RX BD ring size for Q[0]: 256
fsl-gianfar e0024000.ethernet: eth0: TX BD ring size for Q[0]: 256
PHY: mdio@e0024520:19 - Link is Up - 10/Half
With the sbc8349 being diskless, I simply used an scp of /proc/kcore
to the connected x86 box as a rudimentary Tx heavy workload.
BQL data was collected by changing into the dir:
/sys/devices/e0000000.soc8349/e0024000.ethernet/net/eth0/queues/tx-0/byte_queue_limits
and running the following:
for i in * ; do echo -n $i": " ; cat $i ; done
Running with the defaults, data like below was typical:
hold_time: 1000
inflight: 4542
limit: 3456
limit_max: 1879048192
limit_min: 0
hold_time: 1000
inflight: 4542
limit: 3378
limit_max: 1879048192
limit_min: 0
i.e. 2 or 3 MTU sized packets in flight and the limit value lying
somewhere between those two values.
The interesting thing is that the interactive speed reported by scp
seemed somewhat erratic, ranging from ~450 to ~700kB/s. (This was
the only traffic on the old junk - perhaps expected oscillations such
as those seen in isolated ARED tests?) Average speed for 100M was:
104857600 bytes (105 MB) copied, 172.616 s, 607 kB/s
Anyway, back to BQL testing; setting the values as follows:
hold_time: 1000
inflight: 1514
limit: 1400
limit_max: 1400
limit_min: 1000
had the effect of serializing the interface to a single packet, and
the crusty old hub seemed much happier with this arrangement, keeping
a constant speed and achieving the following on a 100MB Tx block:
104857600 bytes (105 MB) copied, 112.52 s, 932 kB/s
It might be interesting to know more about why the defaults suffer
the slowdown, but the hub could possibly be ancient spec violating
trash. Definitely something that nobody would ever use for anything
today. (aside from contrived tests like this)
But it did give me an example of where I could see the effects of
changing the BQL settings, and I'm reasonably confident they are
working as expected.
Paul.
---
[1] http://lists.openwall.net/netdev/2012/01/06/64
Paul Gortmaker (3):
gianfar: Add support for byte queue limits.
gianfar: constify giant block of status descriptor strings
gianfar: delete orphaned version strings and dead macros
drivers/net/ethernet/freescale/gianfar.c | 22 ++++++++++++++++------
drivers/net/ethernet/freescale/gianfar.h | 3 ---
drivers/net/ethernet/freescale/gianfar_ethtool.c | 2 +-
3 files changed, 17 insertions(+), 10 deletions(-)
--
1.7.9.1
^ permalink raw reply
* Re: [PATCH net-next] tcp: reduce out_of_order memory use
From: Neal Cardwell @ 2012-03-18 16:55 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, netdev, Tom Herbert, Ilpo Järvinen,
H.K. Jerry Chu, Yuchung Cheng
In-Reply-To: <1332077854.3722.52.camel@edumazet-laptop>
On Sun, Mar 18, 2012 at 9:37 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> With increasing receive window sizes, but speed of light not improved
> that much, out of order queue can contain a huge number of skbs, waiting
> to be moved to receive_queue when missing packets can fill the holes.
>
> Some devices happen to use fat skbs (truesize of 4096 + sizeof(struct
> sk_buff)) to store regular (MTU <= 1500) frames. This makes highly
> probable sk_rmem_alloc hits sk_rcvbuf limit, which can be 4Mbytes in
> many cases.
>
> When limit is hit, tcp stack calls tcp_collapse_ofo_queue(), a true
> latency killer and cpu cache blower.
>
> Doing the coalescing attempt each time we add a frame in ofo queue
> permits to keep memory use tight and in many cases avoid the
> tcp_collapse() thing later.
>
> Tested on various wireless setups (b43, ath9k, ...) known to use big skb
> truesize, this patch removed the "packets collapsed in receive queue due
> to low socket buffer" I had before.
>
> This also reduced average memory used by tcp sockets.
At this point in tcp_data_queue() we have already called
skb_set_owner_r() to charge the full truesize to the socket. So
probably we need to adjust rmem accounting variables to account for
the fact that the memory corresponding to the overhead of the freed
skb is now gone?
The patch as written seems to only coalesce if the incoming skb fits
immediately after the first skb in the ofo queue. If we're going to
add logic to coalesce then it would be nice to also coalesce in the
case where the skb falls immediately after any later skb in the ofo queue,
i.e. at some point after the "Find place to insert this segment" loop,
probably right before or after the "Do skb overlap to previous one?"
check. Perhaps the coalescing logic could be factored out into its own
little function, and called in either of the two places?
(BTW, a few lines are longer than 80 characters.)
neal
^ permalink raw reply
* [net-next PATCH 4/4] be2net: fix programming of VLAN tags for VF
From: Ajit Khaparde @ 2012-03-18 16:23 UTC (permalink / raw)
To: davem; +Cc: netdev
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 1 +
drivers/net/ethernet/emulex/benet/be_cmds.c | 83 +++++++++++++++++++++++++++
drivers/net/ethernet/emulex/benet/be_cmds.h | 55 ++++++++++++++++++
drivers/net/ethernet/emulex/benet/be_main.c | 23 ++++++--
4 files changed, 157 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 03fc3db..9576ac0 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -303,6 +303,7 @@ struct be_vf_cfg {
unsigned char mac_addr[ETH_ALEN];
int if_handle;
int pmac_id;
+ u16 def_vid;
u16 vlan_tag;
u32 tx_rate;
};
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index d72c2b4..67b030d 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -2419,6 +2419,89 @@ err:
return status;
}
+int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
+ u32 domain, u16 intf_id)
+{
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_set_hsw_config *req;
+ void *ctxt;
+ int status;
+
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err;
+ }
+
+ req = embedded_payload(wrb);
+ ctxt = &req->context;
+
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_SET_HSW_CONFIG, sizeof(*req), wrb, NULL);
+
+ req->hdr.domain = domain;
+ AMAP_SET_BITS(struct amap_set_hsw_context, interface_id, ctxt, intf_id);
+ if (pvid) {
+ AMAP_SET_BITS(struct amap_set_hsw_context, pvid_valid, ctxt, 1);
+ AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid);
+ }
+
+ be_dws_cpu_to_le(req->context, sizeof(req->context));
+ status = be_mcc_notify_wait(adapter);
+
+err:
+ spin_unlock_bh(&adapter->mcc_lock);
+ return status;
+}
+
+/* Get Hyper switch config */
+int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
+ u32 domain, u16 intf_id)
+{
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_get_hsw_config *req;
+ void *ctxt;
+ int status;
+ u16 vid;
+
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err;
+ }
+
+ req = embedded_payload(wrb);
+ ctxt = &req->context;
+
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req), wrb, NULL);
+
+ req->hdr.domain = domain;
+ AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id, ctxt,
+ intf_id);
+ AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1);
+ be_dws_cpu_to_le(req->context, sizeof(req->context));
+
+ status = be_mcc_notify_wait(adapter);
+ if (!status) {
+ struct be_cmd_resp_get_hsw_config *resp =
+ embedded_payload(wrb);
+ be_dws_le_to_cpu(&resp->context,
+ sizeof(resp->context));
+ vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
+ pvid, &resp->context);
+ *pvid = le16_to_cpu(vid);
+ }
+
+err:
+ spin_unlock_bh(&adapter->mcc_lock);
+ return status;
+}
+
int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
{
struct be_mcc_wrb *wrb;
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 345d49e..d5b680c 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -191,6 +191,8 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121
#define OPCODE_COMMON_GET_MAC_LIST 147
#define OPCODE_COMMON_SET_MAC_LIST 148
+#define OPCODE_COMMON_GET_HSW_CONFIG 152
+#define OPCODE_COMMON_SET_HSW_CONFIG 153
#define OPCODE_COMMON_READ_OBJECT 171
#define OPCODE_COMMON_WRITE_OBJECT 172
@@ -1413,6 +1415,55 @@ struct be_cmd_req_set_mac_list {
struct macaddr mac[BE_MAX_MAC];
} __packed;
+/*********************** HSW Config ***********************/
+struct amap_set_hsw_context {
+ u8 interface_id[16];
+ u8 rsvd0[14];
+ u8 pvid_valid;
+ u8 rsvd1;
+ u8 rsvd2[16];
+ u8 pvid[16];
+ u8 rsvd3[32];
+ u8 rsvd4[32];
+ u8 rsvd5[32];
+} __packed;
+
+struct be_cmd_req_set_hsw_config {
+ struct be_cmd_req_hdr hdr;
+ u8 context[sizeof(struct amap_set_hsw_context) / 8];
+} __packed;
+
+struct be_cmd_resp_set_hsw_config {
+ struct be_cmd_resp_hdr hdr;
+ u32 rsvd;
+};
+
+struct amap_get_hsw_req_context {
+ u8 interface_id[16];
+ u8 rsvd0[14];
+ u8 pvid_valid;
+ u8 pport;
+} __packed;
+
+struct amap_get_hsw_resp_context {
+ u8 rsvd1[16];
+ u8 pvid[16];
+ u8 rsvd2[32];
+ u8 rsvd3[32];
+ u8 rsvd4[32];
+} __packed;
+
+struct be_cmd_req_get_hsw_config {
+ struct be_cmd_req_hdr hdr;
+ u8 context[sizeof(struct amap_get_hsw_req_context) / 8];
+} __packed;
+
+struct be_cmd_resp_get_hsw_config {
+ struct be_cmd_resp_hdr hdr;
+ u8 context[sizeof(struct amap_get_hsw_resp_context) / 8];
+ u32 rsvd;
+};
+
/*************** HW Stats Get v1 **********************************/
#define BE_TXP_SW_SZ 48
struct be_port_rxf_stats_v1 {
@@ -1617,5 +1668,9 @@ extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
bool *pmac_id_active, u32 *pmac_id, u8 *mac);
extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
u8 mac_count, u32 domain);
+extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
+ u32 domain, u16 intf_id);
+extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
+ u32 domain, u16 intf_id);
extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 1c84bc8..528a886 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -978,14 +978,21 @@ static int be_set_vf_vlan(struct net_device *netdev,
return -EINVAL;
if (vlan) {
- adapter->vf_cfg[vf].vlan_tag = vlan;
- adapter->vlans_added++;
+ if (adapter->vf_cfg[vf].vlan_tag != vlan) {
+ /* If this is new value, program it. Else skip. */
+ adapter->vf_cfg[vf].vlan_tag = vlan;
+
+ status = be_cmd_set_hsw_config(adapter, vlan,
+ vf + 1, adapter->vf_cfg[vf].if_handle);
+ }
} else {
+ /* Reset Transparent Vlan Tagging. */
adapter->vf_cfg[vf].vlan_tag = 0;
- adapter->vlans_added--;
+ vlan = adapter->vf_cfg[vf].def_vid;
+ status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
+ adapter->vf_cfg[vf].if_handle);
}
- status = be_vid_config(adapter, true, vf);
if (status)
dev_info(&adapter->pdev->dev,
@@ -2525,7 +2532,7 @@ static int be_vf_setup(struct be_adapter *adapter)
{
struct be_vf_cfg *vf_cfg;
u32 cap_flags, en_flags, vf;
- u16 lnk_speed;
+ u16 def_vlan, lnk_speed;
int status;
be_vf_setup_init(adapter);
@@ -2549,6 +2556,12 @@ static int be_vf_setup(struct be_adapter *adapter)
if (status)
goto err;
vf_cfg->tx_rate = lnk_speed * 10;
+
+ status = be_cmd_get_hsw_config(adapter, &def_vlan,
+ vf + 1, vf_cfg->if_handle);
+ if (status)
+ goto err;
+ vf_cfg->def_vid = def_vlan;
}
return 0;
err:
--
1.7.5.4
^ permalink raw reply related
* [net-next PATCH 3/4] be2net: Fix number of vlan slots in flex mode
From: Ajit Khaparde @ 2012-03-18 16:23 UTC (permalink / raw)
To: davem; +Cc: netdev
In flex10 mode the number of vlan slots supported is halved.
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index b4348b8..1c84bc8 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -3292,7 +3292,7 @@ static int be_get_config(struct be_adapter *adapter)
return status;
if (adapter->function_mode & FLEX10_MODE)
- adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4;
+ adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/8;
else
adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
--
1.7.5.4
^ permalink raw reply related
* [net-next PATCH 2/4] be2net: Program secondary UC MAC address into MAC filter
From: Ajit Khaparde @ 2012-03-18 16:23 UTC (permalink / raw)
To: davem; +Cc: netdev
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 6 +++-
drivers/net/ethernet/emulex/benet/be_main.c | 53 ++++++++++++++++++++++++---
2 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index cabe1b8..03fc3db 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -309,6 +309,8 @@ struct be_vf_cfg {
#define BE_FLAGS_LINK_STATUS_INIT 1
#define BE_FLAGS_WORKER_SCHEDULED (1 << 3)
+#define BE_UC_PMAC_COUNT 30
+#define BE_VF_UC_PMAC_COUNT 2
struct be_adapter {
struct pci_dev *pdev;
@@ -361,7 +363,7 @@ struct be_adapter {
/* Ethtool knobs and info */
char fw_ver[FW_VER_LEN];
int if_handle; /* Used to configure filtering */
- u32 pmac_id; /* MAC addr handle used by BE card */
+ u32 *pmac_id; /* MAC addr handle used by BE card */
u32 beacon_state; /* for set_phys_id */
bool eeh_err;
@@ -391,6 +393,8 @@ struct be_adapter {
u16 pvid;
u8 wol_cap;
bool wol;
+ u32 max_pmac_cnt; /* Max secondary UC MACs programmable */
+ u32 uc_macs; /* Count of secondary UC MAC programmed */
};
#define be_physfn(adapter) (!adapter->is_virtfn)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 050e3eb..b4348b8 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -235,7 +235,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
struct sockaddr *addr = p;
int status = 0;
u8 current_mac[ETH_ALEN];
- u32 pmac_id = adapter->pmac_id;
+ u32 pmac_id = adapter->pmac_id[0];
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
@@ -248,7 +248,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
if (memcmp(addr->sa_data, current_mac, ETH_ALEN)) {
status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
- adapter->if_handle, &adapter->pmac_id, 0);
+ adapter->if_handle, &adapter->pmac_id[0], 0);
if (status)
goto err;
@@ -885,6 +885,29 @@ static void be_set_rx_mode(struct net_device *netdev)
goto done;
}
+ if (netdev_uc_count(netdev) != adapter->uc_macs) {
+ struct netdev_hw_addr *ha;
+ int i = 1; /* First slot is claimed by the Primary MAC */
+
+ for (; adapter->uc_macs > 0; adapter->uc_macs--, i++) {
+ be_cmd_pmac_del(adapter, adapter->if_handle,
+ adapter->pmac_id[i], 0);
+ }
+
+ if (netdev_uc_count(netdev) > adapter->max_pmac_cnt) {
+ be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
+ adapter->promiscuous = true;
+ goto done;
+ }
+
+ netdev_for_each_uc_addr(ha, adapter->netdev) {
+ adapter->uc_macs++; /* First slot is for Primary MAC */
+ be_cmd_pmac_add(adapter, (u8 *)ha->addr,
+ adapter->if_handle,
+ &adapter->pmac_id[adapter->uc_macs], 0);
+ }
+ }
+
be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
done:
return;
@@ -2458,6 +2481,8 @@ static void be_vf_clear(struct be_adapter *adapter)
static int be_clear(struct be_adapter *adapter)
{
+ int i = 1;
+
if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) {
cancel_delayed_work_sync(&adapter->work);
adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED;
@@ -2466,6 +2491,10 @@ static int be_clear(struct be_adapter *adapter)
if (sriov_enabled(adapter))
be_vf_clear(adapter);
+ for (; adapter->uc_macs > 0; adapter->uc_macs--, i++)
+ be_cmd_pmac_del(adapter, adapter->if_handle,
+ adapter->pmac_id[i], 0);
+
be_cmd_if_destroy(adapter, adapter->if_handle, 0);
be_mcc_queues_destroy(adapter);
@@ -2477,6 +2506,7 @@ static int be_clear(struct be_adapter *adapter)
be_cmd_fw_clean(adapter);
be_msix_disable(adapter);
+ kfree(adapter->pmac_id);
return 0;
}
@@ -2552,10 +2582,10 @@ static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac)
false, adapter->if_handle, pmac_id);
if (!status)
- adapter->pmac_id = pmac_id;
+ adapter->pmac_id[0] = pmac_id;
} else {
status = be_cmd_pmac_add(adapter, mac,
- adapter->if_handle, &adapter->pmac_id, 0);
+ adapter->if_handle, &adapter->pmac_id[0], 0);
}
do_none:
return status;
@@ -2610,7 +2640,7 @@ static int be_setup(struct be_adapter *adapter)
}
status = be_cmd_if_create(adapter, cap_flags, en_flags,
netdev->dev_addr, &adapter->if_handle,
- &adapter->pmac_id, 0);
+ &adapter->pmac_id[0], 0);
if (status != 0)
goto err;
@@ -3059,6 +3089,8 @@ static void be_netdev_init(struct net_device *netdev)
netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ netdev->priv_flags |= IFF_UNICAST_FLT;
+
netdev->flags |= IFF_MULTICAST;
netif_set_gso_max_size(netdev, 65535);
@@ -3264,6 +3296,17 @@ static int be_get_config(struct be_adapter *adapter)
else
adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
+ if (be_physfn(adapter))
+ adapter->max_pmac_cnt = BE_UC_PMAC_COUNT;
+ else
+ adapter->max_pmac_cnt = BE_VF_UC_PMAC_COUNT;
+
+ /* primary mac needs 1 pmac entry */
+ adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1,
+ sizeof(u32), GFP_KERNEL);
+ if (!adapter->pmac_id)
+ return -ENOMEM;
+
status = be_cmd_get_cntl_attributes(adapter);
if (status)
return status;
--
1.7.5.4
^ permalink raw reply related
* [net-next PATCH 1/4] be2net: enable WOL by default if h/w supports it
From: Ajit Khaparde @ 2012-03-18 16:23 UTC (permalink / raw)
To: davem; +Cc: netdev
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 26 +++++++++++-
drivers/net/ethernet/emulex/benet/be_cmds.c | 55 ++++++++++++++++++++++++
drivers/net/ethernet/emulex/benet/be_cmds.h | 28 ++++++++++++
drivers/net/ethernet/emulex/benet/be_ethtool.c | 27 +++++-------
drivers/net/ethernet/emulex/benet/be_main.c | 17 +++++++
5 files changed, 136 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index ab24e46..cabe1b8 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -52,6 +52,10 @@
#define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */
#define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */
#define OC_DEVICE_ID5 0x720 /* Device Id for Skyhawk cards */
+#define OC_SUBSYS_DEVICE_ID1 0xE602
+#define OC_SUBSYS_DEVICE_ID2 0xE642
+#define OC_SUBSYS_DEVICE_ID3 0xE612
+#define OC_SUBSYS_DEVICE_ID4 0xE652
static inline char *nic_name(struct pci_dev *pdev)
{
@@ -365,7 +369,6 @@ struct be_adapter {
bool fw_timeout;
u32 port_num;
bool promiscuous;
- bool wol;
u32 function_mode;
u32 function_caps;
u32 rx_fc; /* Rx flow control */
@@ -386,6 +389,8 @@ struct be_adapter {
u32 sli_family;
u8 hba_port_num;
u16 pvid;
+ u8 wol_cap;
+ bool wol;
};
#define be_physfn(adapter) (!adapter->is_virtfn)
@@ -549,9 +554,28 @@ static inline bool be_error(struct be_adapter *adapter)
return adapter->eeh_err || adapter->ue_detected || adapter->fw_timeout;
}
+static inline bool be_is_wol_excluded(struct be_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ if (!be_physfn(adapter))
+ return true;
+
+ switch (pdev->subsystem_device) {
+ case OC_SUBSYS_DEVICE_ID1:
+ case OC_SUBSYS_DEVICE_ID2:
+ case OC_SUBSYS_DEVICE_ID3:
+ case OC_SUBSYS_DEVICE_ID4:
+ return true;
+ default:
+ return false;
+ }
+}
+
extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
u16 num_popped);
extern void be_link_status_update(struct be_adapter *adapter, u8 link_status);
extern void be_parse_stats(struct be_adapter *adapter);
extern int be_load_fw(struct be_adapter *adapter, u8 *func);
+extern bool be_is_wol_supported(struct be_adapter *adapter);
#endif /* BE_H */
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 398fb5c..d72c2b4 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -2418,3 +2418,58 @@ err:
spin_unlock_bh(&adapter->mcc_lock);
return status;
}
+
+int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
+{
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_acpi_wol_magic_config_v1 *req;
+ int status;
+ int payload_len = sizeof(*req);
+ struct be_dma_mem cmd;
+
+ memset(&cmd, 0, sizeof(struct be_dma_mem));
+ cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1);
+ cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size,
+ &cmd.dma);
+ if (!cmd.va) {
+ dev_err(&adapter->pdev->dev,
+ "Memory allocation failure\n");
+ return -ENOMEM;
+ }
+
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
+
+ wrb = wrb_from_mbox(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err;
+ }
+
+ req = cmd.va;
+
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
+ OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
+ payload_len, wrb, &cmd);
+
+ req->hdr.version = 1;
+ req->query_options = BE_GET_WOL_CAP;
+
+ status = be_mbox_notify_wait(adapter);
+ if (!status) {
+ struct be_cmd_resp_acpi_wol_magic_config_v1 *resp;
+ resp = (struct be_cmd_resp_acpi_wol_magic_config_v1 *) cmd.va;
+
+ /* the command could succeed misleadingly on old f/w
+ * which is not aware of the V1 version. fake an error. */
+ if (resp->hdr.response_length < payload_len) {
+ status = -1;
+ goto err;
+ }
+ adapter->wol_cap = resp->wol_settings;
+ }
+err:
+ mutex_unlock(&adapter->mbox_lock);
+ pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
+ return status;
+}
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 687c420..345d49e 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -1206,6 +1206,33 @@ struct be_cmd_req_acpi_wol_magic_config{
u8 rsvd2[2];
} __packed;
+struct be_cmd_req_acpi_wol_magic_config_v1 {
+ struct be_cmd_req_hdr hdr;
+ u8 rsvd0[2];
+ u8 query_options;
+ u8 rsvd1[5];
+ u32 rsvd2[288];
+ u8 magic_mac[6];
+ u8 rsvd3[22];
+} __packed;
+
+struct be_cmd_resp_acpi_wol_magic_config_v1 {
+ struct be_cmd_resp_hdr hdr;
+ u8 rsvd0[2];
+ u8 wol_settings;
+ u8 rsvd1[5];
+ u32 rsvd2[295];
+} __packed;
+
+#define BE_GET_WOL_CAP 2
+
+#define BE_WOL_CAP 0x1
+#define BE_PME_D0_CAP 0x8
+#define BE_PME_D1_CAP 0x10
+#define BE_PME_D2_CAP 0x20
+#define BE_PME_D3HOT_CAP 0x40
+#define BE_PME_D3COLD_CAP 0x80
+
/********************** LoopBack test *********************/
struct be_cmd_req_loopback_test {
struct be_cmd_req_hdr hdr;
@@ -1590,4 +1617,5 @@ extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
bool *pmac_id_active, u32 *pmac_id, u8 *mac);
extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
u8 mac_count, u32 domain);
+extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 30ce178..c1ff73c 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -600,26 +600,16 @@ be_set_phys_id(struct net_device *netdev,
return 0;
}
-static bool
-be_is_wol_supported(struct be_adapter *adapter)
-{
- if (!be_physfn(adapter))
- return false;
- else
- return true;
-}
static void
be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct be_adapter *adapter = netdev_priv(netdev);
- if (be_is_wol_supported(adapter))
- wol->supported = WAKE_MAGIC;
-
- if (adapter->wol)
- wol->wolopts = WAKE_MAGIC;
- else
+ if (be_is_wol_supported(adapter)) {
+ wol->supported |= WAKE_MAGIC;
+ wol->wolopts |= WAKE_MAGIC;
+ } else
wol->wolopts = 0;
memset(&wol->sopass, 0, sizeof(wol->sopass));
}
@@ -630,9 +620,14 @@ be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
struct be_adapter *adapter = netdev_priv(netdev);
if (wol->wolopts & ~WAKE_MAGIC)
- return -EINVAL;
+ return -EOPNOTSUPP;
+
+ if (!be_is_wol_supported(adapter)) {
+ dev_warn(&adapter->pdev->dev, "WOL not supported\n");
+ return -EOPNOTSUPP;
+ }
- if ((wol->wolopts & WAKE_MAGIC) && be_is_wol_supported(adapter))
+ if (wol->wolopts & WAKE_MAGIC)
adapter->wol = true;
else
adapter->wol = false;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index e382278..050e3eb 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -3244,6 +3244,12 @@ static void __devexit be_remove(struct pci_dev *pdev)
free_netdev(adapter->netdev);
}
+bool be_is_wol_supported(struct be_adapter *adapter)
+{
+ return ((adapter->wol_cap & BE_WOL_CAP) &&
+ !be_is_wol_excluded(adapter)) ? true : false;
+}
+
static int be_get_config(struct be_adapter *adapter)
{
int status;
@@ -3262,6 +3268,17 @@ static int be_get_config(struct be_adapter *adapter)
if (status)
return status;
+ status = be_cmd_get_acpi_wol_cap(adapter);
+ if (status) {
+ /* in case of a failure to get wol capabillities
+ * check the exclusion list to determine WOL capability */
+ if (!be_is_wol_excluded(adapter))
+ adapter->wol_cap |= BE_WOL_CAP;
+ }
+
+ if (be_is_wol_supported(adapter))
+ adapter->wol = true;
+
return 0;
}
--
1.7.5.4
^ permalink raw reply related
* [net-next RFC 0/4] be2net: patch series
From: Ajit Khaparde @ 2012-03-18 16:22 UTC (permalink / raw)
To: davem; +Cc: netdev
Please apply.
[1/4] be2net: enable WOL by default if h/w supports it
[2/4] be2net: Program secondary UC MAC address into MAC filter
[3/4] be2net: Fix number of vlan slots in flex mode
[4/4] be2net: fix programming of transparent VLAN tags for VF
Thanks
-Ajit
^ permalink raw reply
* contact me immediately
From: Ho Chen Tung @ 2012-03-17 19:15 UTC (permalink / raw)
Greetings
I have to disturb you today for the reward of an opportunity that should properly be used to advantage.In reverence to your valuable time, I would like to get straight to the point.There is a legal way to transfer ownership of US$ 21,400,000.00 to you. This fund originally belongs to a client who had no blood relation in his account-opening package.
Ho Chen Tung.
^ permalink raw reply
* [PATCH net V1] mlx4_core: fix race on comm channel
From: Yevgeny Petrilin @ 2012-03-18 14:32 UTC (permalink / raw)
To: davem; +Cc: netdev, yevgenyp, eugenia
From: Eugenia Emantayev <eugenia@mellanox.co.il>
Prevent race condition between commands on comm channel.
Happened while unloading the driver when switching from
event to polling mode. VF got completion on the last command
before switching to polling mode, but toggle was not changed.
After the fix - VF will not write the next command before
toggle is updated.
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.co.il>
---
Diff from V0:
Fixed comments style
drivers/net/ethernet/mellanox/mlx4/cmd.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index eaf09d4..6037d36 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -239,6 +239,7 @@ static int mlx4_comm_cmd_wait(struct mlx4_dev *dev, u8 op,
{
struct mlx4_cmd *cmd = &mlx4_priv(dev)->cmd;
struct mlx4_cmd_context *context;
+ unsigned long end;
int err = 0;
down(&cmd->event_sem);
@@ -268,6 +269,14 @@ static int mlx4_comm_cmd_wait(struct mlx4_dev *dev, u8 op,
}
out:
+ /* wait for comm channel ready
+ * this is necessary for prevention the race
+ * when switching between event to polling mode
+ */
+ end = msecs_to_jiffies(timeout) + jiffies;
+ while (comm_pending(dev) && time_before(jiffies, end))
+ cond_resched();
+
spin_lock(&cmd->context_lock);
context->next = cmd->free_head;
cmd->free_head = context - cmd->context;
--
1.7.7
^ permalink raw reply related
* Re: netfilter: Hung task
From: Pablo Neira Ayuso @ 2012-03-18 14:19 UTC (permalink / raw)
To: Sasha Levin
Cc: kaber, davem, Dave Jones, netfilter-devel,
linux-kernel@vger.kernel.org List, netdev
In-Reply-To: <CA+1xoqfCTXxXsbfUjttuOVutyD_FzYS8PoOoAOOtB72P8SwdVg@mail.gmail.com>
On Sun, Mar 18, 2012 at 12:55:13PM +0200, Sasha Levin wrote:
> Hi all,
>
> I got the following spew after fuzzing using trinity on a KVM tools
> guest, using the latest linux-next.
>
> It reminds me a lot of https://lkml.org/lkml/2012/3/14/375 and
> https://lkml.org/lkml/2012/1/14/45
You mention neither Linux kernel version nor the way you trigger this.
With that little information it's really hard to really know.
Time ago we applied this to Netfilter which is already in mainline:
http://git.kernel.org/?p=linux/kernel/git/davem/net.git;a=commit;h=70e9942f17a6193e9172a804e6569a8806633d6b
^ permalink raw reply
* Re: [net-next 8/9] bnx2x: consistent statistics for old FW
From: Yuval Mintz @ 2012-03-18 20:52 UTC (permalink / raw)
To: netdev
In-Reply-To: <1332102825-7838-9-git-send-email-yuvalmin@broadcom.com>
> Previously applied patch making the bnx2x statistics consistent
> did not apply to old FWs. This remedies it, extending the consistent
> behaviour to all drivers.
Oops, forgot to thank Michal for finding this one.
Reported-by: Michal Schmidt <mschmidt@redhat.com>
^ 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