* Re: Network performance with small packets - continued
From: Shirley Ma @ 2011-03-10 0:59 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Tom Lendacky, Rusty Russell, Krishna Kumar2, David Miller, kvm,
netdev, steved
In-Reply-To: <20110309215537.GA11516@redhat.com>
On Wed, 2011-03-09 at 23:56 +0200, Michael S. Tsirkin wrote:
> > Txn Rate: 153,696.59 Txn/Sec, Pkt Rate: 305,358 Pkgs/Sec
> > Exits: 62,603.37 Exits/Sec
> > TxCPU: 3.73% RxCPU: 98.52%
> > Virtio1-input Interrupts/Sec (CPU0/CPU1): 11,564/0
> > Virtio1-output Interrupts/Sec (CPU0/CPU1): 0/0
> >
> > About a 77% increase over baseline and about 74% of baremetal.
>
> Hmm we get about 20 packets per interrupt on average.
> That's pretty decent. The problem is with exits.
> Let's try something adaptive in the host?
I did some hack before, for 32-64 multiple stream TCP_RR cases, either
queue multiple skbs per kick or delay vhost exit from handle_tx, both
improved TCP_RR aggregation performance, but single TCP_RR latency
increased.
Here, the test is about 100 TCP_RR streams from a bare metal client to
KVM guest, the kick_notify from guest RX path should be small (every 1/2
ring size, it does a kick and even under that kick, vhost might already
disable the notification).
The kick_notify from guest TX path seems the main reason causes the
guest huge of exits, (it does a kick for every send skb, under that kick
vhost might mostly likely exit from empty ring not reaching
VHOST_NET_WEIGH. The indirect buffer is used, so I wonder how many
packets per handle_tx processed here?
In theory, for lots of TCP_RR streams, the guest should be able to keep
sending xmit skbs to send vq, so vhost should be able to disable
notification most of the time, then number of guest exits should be
significantly reduced? Why we saw lots of guest exits here still? Is it
worth to try 256 (send queue size) TCP_RRs?
Tom's kick_notify data from Rusty's patch would be helpful to understand
what's going here.
Thanks
Shirley
^ permalink raw reply
* Re: [PATCH 03/18] ipvs: zero percpu stats
From: Simon Horman @ 2011-03-10 1:34 UTC (permalink / raw)
To: Julian Anastasov
Cc: Eric Dumazet, netdev, netfilter-devel, netfilter, lvs-devel,
Hans Schillstrom
In-Reply-To: <alpine.LFD.2.00.1103061218470.1879@ja.ssi.bg>
On Sun, Mar 06, 2011 at 02:18:35PM +0200, Julian Anastasov wrote:
[ snip ]
> Zero the new percpu stats because we copy from there.
> Use the stats spin lock to synchronize the percpu zeroing with
> the percpu reading, both in user context and not in a hot path.
>
> Signed-off-by: Julian Anastasov <ja@ssi.bg>
Eric, do you have any thoughts on this?
It seems clean to me.
> ---
>
> diff -urp lvs-test-2.6-8a80c79/linux/net/netfilter/ipvs/ip_vs_ctl.c linux/net/netfilter/ipvs/ip_vs_ctl.c
> --- lvs-test-2.6-8a80c79/linux/net/netfilter/ipvs/ip_vs_ctl.c 2011-03-06 13:39:59.000000000 +0200
> +++ linux/net/netfilter/ipvs/ip_vs_ctl.c 2011-03-06 13:44:56.108275455 +0200
> @@ -713,8 +713,25 @@ static void ip_vs_trash_cleanup(struct n
> static void
> ip_vs_zero_stats(struct ip_vs_stats *stats)
> {
> + struct ip_vs_cpu_stats *cpustats = stats->cpustats;
> + int i;
> +
> spin_lock_bh(&stats->lock);
>
> + for_each_possible_cpu(i) {
> + struct ip_vs_cpu_stats *u = per_cpu_ptr(cpustats, i);
> + unsigned int start;
> +
> + /* Do not pretend to be writer, it is enough to
> + * sync with writers that modify the u64 counters
> + * because under stats->lock there are no other readers
> + */
> + do {
> + start = u64_stats_fetch_begin(&u->syncp);
> + memset(&u->ustats, 0, sizeof(u->ustats));
> + } while (u64_stats_fetch_retry(&u->syncp, start));
> + }
> +
> memset(&stats->ustats, 0, sizeof(stats->ustats));
> ip_vs_zero_estimator(stats);
>
> @@ -2015,16 +2032,19 @@ static int ip_vs_stats_percpu_show(struc
> seq_printf(seq,
> "CPU Conns Packets Packets Bytes Bytes\n");
>
> + /* Use spin lock early to synchronize with percpu zeroing */
> + spin_lock_bh(&tot_stats->lock);
> +
> for_each_possible_cpu(i) {
> struct ip_vs_cpu_stats *u = per_cpu_ptr(cpustats, i);
> unsigned int start;
> __u64 inbytes, outbytes;
>
> do {
> - start = u64_stats_fetch_begin_bh(&u->syncp);
> + start = u64_stats_fetch_begin(&u->syncp);
> inbytes = u->ustats.inbytes;
> outbytes = u->ustats.outbytes;
> - } while (u64_stats_fetch_retry_bh(&u->syncp, start));
> + } while (u64_stats_fetch_retry(&u->syncp, start));
>
> seq_printf(seq, "%3X %8X %8X %8X %16LX %16LX\n",
> i, u->ustats.conns, u->ustats.inpkts,
> @@ -2032,7 +2052,6 @@ static int ip_vs_stats_percpu_show(struc
> (__u64)outbytes);
> }
>
> - spin_lock_bh(&tot_stats->lock);
> seq_printf(seq, " ~ %8X %8X %8X %16LX %16LX\n\n",
> tot_stats->ustats.conns, tot_stats->ustats.inpkts,
> tot_stats->ustats.outpkts,
>
^ permalink raw reply
* Re: Stale entries in RT_TABLE_LOCAL
From: Julian Anastasov @ 2011-03-10 1:50 UTC (permalink / raw)
To: David Miller; +Cc: alexandre.sidorenko, netdev
In-Reply-To: <alpine.LFD.2.00.1103100139510.2372@ja.ssi.bg>
Hello,
On Thu, 10 Mar 2011, Julian Anastasov wrote:
> On Wed, 9 Mar 2011, David Miller wrote:
>
>> From: Alex Sidorenko <alexandre.sidorenko@hp.com>
>> Date: Wed, 23 Feb 2011 12:43:23 -0500
>>
>>> I am not sure what is the best way to fix this, I can think of several
>>> approaches:
>>>
>>> (a) change the sources so that it would be impossible to add the same IP
>>> multiple times, even with different masks. I cannot think of any
>>> situation where adding the same IP (but with different mask) to the
>>> same
>>> interface could be useful. But maybe I am wrong?
>>
>> I'm leaning towards this solution if it's viable. But I'm not so sure that
>> nobody uses this feature, maybe Julian knows?
>>
>> Julian, the issue is that if you add the same IP address multiple times
>> using
>> different subnet masks, we allow it.
>>
>> But removal doesn't work correctly, we clear the IFA list on the device but
>> we
>> leave stale entries in the local routing table.
>>
>> The test case is:
>>
>> ip addr add 192.168.142.109/23 dev dummy0
>> ip addr add 192.168.142.109/22 dev dummy0
>
> Here I have just one local route.
Aha, it seems the problem happens when the
both lines are executed while there is another address on
device and the last added address becomes secondary
for the 1st, eg:
IP1: 192.168.140.31/22, primary
IP2: 192.168.142.109/23, primary
IP3: 192.168.142.109/22, secondary for primary IP1
It is the route for IP3 that is leaked, with prefsrc=IP1.
We create local route for secondary IPs with prefsrc=ItsPrimaryIP.
Both local routes for 109 differ in prefsrc (fa_info). But on
deletion only one route is deleted due to last_ip check - the first
because on deletion prefsrc is not matched, fib_table_delete
does not work in symmetric way. So, the local route created
for IP3 remains no matter the deletion order.
If we decide to create one unique local route for this case,
there is a risk device unregistration to remove
it (fib_sync_down_dev with force > 0). I have to think more
on this issue...
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply
* Re: [PATCH] via-rhine: Work around invalid MAC address error
From: Alex G. @ 2011-03-10 2:04 UTC (permalink / raw)
To: David Miller; +Cc: netdev, rl, florian
In-Reply-To: <20110309.134436.28819615.davem@davemloft.net>
On 03/09/2011 11:44 PM, David Miller wrote:
> Sorry.
>
Don't sweat it.
> I'm going to ignore you're postings for a day or two,
That means I can bash you and you won't notice too soon.
> I've already
> invested an enormous amount of time and energy into getting you to
> submit patches which are properly formed and actually get accepted by
> the tools that we all use.
You have done nothing more than point me to obsolete documentation, and
bash me after following it. If the the less than five minutes of your
life that you have spent giving me short, uninformative, or outright
wrong information are "an enormous amount of time and energy", please
tell me how much you get paid an hour, so that I can pay you for those
minutes (preferably via PayPal). Please be advised, that I will ask my
bank for a chargeback should it come to this.
> Nobody else has these kinds of problems
> and can submit properly formed patches.
>
I assume this tool is" git". If so, it is called "git" for a reason.
I simply wanted to fix a problem I found. I don't know what tools you
are using, how they work, etc. Please don't expect me to guess. If you
want _everybody_ to get it right the first time, then have the decency
to update the fucking documentation, before insolently directing people
to it.
> I would strongly suggest that you try to email the patch to yourself,
> save the email into a file, and feed it to "git am" on a fresh tree,
> making sure that when then looking at what the resulting commit looks
> like.
Now this is the first useful bit of information you have bothered giving
me this whole time.
Alex
^ permalink raw reply
* Re: [net-next-2.6 PATCH] if_link: Add PORT_REQUEST_MAX
From: roprabhu @ 2011-03-10 2:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20110309.124916.183062823.davem@davemloft.net>
On 3/9/11 12:49 PM, "David Miller" <davem@davemloft.net> wrote:
> From: Roopa Prabhu <roprabhu@cisco.com>
> Date: Wed, 09 Mar 2011 12:34:31 -0800
>
>> From: Roopa Prabhu <roprabhu@cisco.com>
>>
>> This patch adds __PORT_REQUEST_MAX to port request enumeration. And defines
>> PORT_REQUEST_MAX.
>>
>> Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
>> Signed-off-by: David Wang <dwang2@cisco.com>
>> Signed-off-by: Christian Benvenuti <benve@cisco.com>
>
> Why?
>
> If some new request types get added, this max value will increase and
> we don't want that to happen for things exposed to userspace.
>
> Userspace should really not depend upon how many requests there are.
O ok. Did not know the reason why its was not there. Point taken. Pls
ignore. Thanks.
^ permalink raw reply
* Re: Network performance with small packets - continued
From: Rick Jones @ 2011-03-10 2:30 UTC (permalink / raw)
To: Shirley Ma
Cc: Michael S. Tsirkin, Tom Lendacky, Rusty Russell, Krishna Kumar2,
David Miller, kvm, netdev, steved
In-Reply-To: <1299718745.25664.200.camel@localhost.localdomain>
On Wed, 2011-03-09 at 16:59 -0800, Shirley Ma wrote:
> In theory, for lots of TCP_RR streams, the guest should be able to keep
> sending xmit skbs to send vq, so vhost should be able to disable
> notification most of the time, then number of guest exits should be
> significantly reduced? Why we saw lots of guest exits here still? Is it
> worth to try 256 (send queue size) TCP_RRs?
If these are single-transaction-at-a-time TCP_RRs rather than "burst
mode" then the number may be something other than send queue size to
keep it constantly active given the RTTs. In the "bare iron" world at
least, that is one of the reasons I added the "burst mode" to the _RR
test - because it could take a Very Large Number of concurrent netperfs
to take a link to saturation, at which point it might have been just as
much a context switching benchmark as anything else :)
happy benchmarking,
rick jones
^ permalink raw reply
* Re: [PATCH 03/18] ipvs: zero percpu stats
From: David Miller @ 2011-03-10 2:53 UTC (permalink / raw)
To: horms; +Cc: ja, eric.dumazet, netdev, netfilter-devel, netfilter, lvs-devel,
hans
In-Reply-To: <20110310013442.GD3028@verge.net.au>
From: Simon Horman <horms@verge.net.au>
Date: Thu, 10 Mar 2011 10:34:42 +0900
> On Sun, Mar 06, 2011 at 02:18:35PM +0200, Julian Anastasov wrote:
>
> [ snip ]
>
>> Zero the new percpu stats because we copy from there.
>> Use the stats spin lock to synchronize the percpu zeroing with
>> the percpu reading, both in user context and not in a hot path.
>>
>> Signed-off-by: Julian Anastasov <ja@ssi.bg>
>
> Eric, do you have any thoughts on this?
> It seems clean to me.
Eric is away until this weekend, so don't be alarmed by a
late response :-)
^ permalink raw reply
* [PATCH 7/7] tg3: Remove 5750 PCI code
From: Matt Carlson @ 2011-03-10 2:58 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson, stable
The 5750 ASIC rev was never released as a PCI device. It only exists as
a PCIe device. This patch removes the code that supports the former
configuration.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/tg3.c | 15 +++++----------
1 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 2c67cc9..ebec888 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -8193,10 +8193,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
RDMAC_MODE_MBUF_RBD_CRPT_ENAB |
RDMAC_MODE_MBUF_SBD_CRPT_ENAB;
- /* If statement applies to 5705 and 5750 PCI devices only */
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
- tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) ||
- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
+ tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE &&
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128;
@@ -8369,17 +8367,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB |
WDMAC_MODE_LNGREAD_ENAB);
- /* If statement applies to 5705 and 5750 PCI devices only */
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
- tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
+ tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
if ((tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
(tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 ||
tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) {
/* nothing */
} else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) &&
- !(tp->tg3_flags2 & TG3_FLG2_IS_5788) &&
- !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
+ !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) {
val |= WDMAC_MODE_RX_ACCEL;
}
}
--
1.7.3.4
^ permalink raw reply related
* [PATCH 4/7] tg3: cleanup pci device table vars
From: Matt Carlson @ 2011-03-10 2:58 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson, stable
Commit 895950c2a6565d9eefda4a38b00fa28537e39fcb, entitled
"tg3: Use DEFINE_PCI_DEVICE_TABLE" moved two pci device tables into the
global address space, but didn't declare them static and didn't prefix
them with "tg3_". This patch fixes those problems.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/tg3.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index ffb0979..73eacbd 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -13115,7 +13115,7 @@ static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp)
return 512;
}
-DEFINE_PCI_DEVICE_TABLE(write_reorder_chipsets) = {
+static DEFINE_PCI_DEVICE_TABLE(tg3_write_reorder_chipsets) = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE) },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8385_0) },
@@ -13469,7 +13469,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
* every mailbox register write to force the writes to be
* posted to the chip in order.
*/
- if (pci_dev_present(write_reorder_chipsets) &&
+ if (pci_dev_present(tg3_write_reorder_chipsets) &&
!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
@@ -14225,7 +14225,7 @@ static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dm
#define TEST_BUFFER_SIZE 0x2000
-DEFINE_PCI_DEVICE_TABLE(dma_wait_state_chipsets) = {
+static DEFINE_PCI_DEVICE_TABLE(tg3_dma_wait_state_chipsets) = {
{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_PCI15) },
{ },
};
@@ -14404,7 +14404,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
* now look for chipsets that are known to expose the
* DMA bug without failing the test.
*/
- if (pci_dev_present(dma_wait_state_chipsets)) {
+ if (pci_dev_present(tg3_dma_wait_state_chipsets)) {
tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK;
tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16;
} else {
--
1.7.3.4
^ permalink raw reply related
* [PATCH 6/7] tg3: Move tg3_init_link_config to tg3_phy_probe
From: Matt Carlson @ 2011-03-10 2:58 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson, stable
This patch moves the function that initializes the link configuration
closer to the place where the rest of the phy code is initialized.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/tg3.c | 69 +++++++++++++++++++++++++++--------------------------
1 files changed, 35 insertions(+), 34 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 159eb23..2c67cc9 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -12557,12 +12557,45 @@ static u32 __devinit tg3_read_otp_phycfg(struct tg3 *tp)
return ((thalf_otp & 0x0000ffff) << 16) | (bhalf_otp >> 16);
}
+static void __devinit tg3_phy_init_link_config(struct tg3 *tp)
+{
+ u32 adv = ADVERTISED_Autoneg |
+ ADVERTISED_Pause;
+
+ if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY))
+ adv |= ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full;
+
+ if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES))
+ adv |= ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_TP;
+ else
+ adv |= ADVERTISED_FIBRE;
+
+ tp->link_config.advertising = adv;
+ tp->link_config.speed = SPEED_INVALID;
+ tp->link_config.duplex = DUPLEX_INVALID;
+ tp->link_config.autoneg = AUTONEG_ENABLE;
+ tp->link_config.active_speed = SPEED_INVALID;
+ tp->link_config.active_duplex = DUPLEX_INVALID;
+ tp->link_config.orig_speed = SPEED_INVALID;
+ tp->link_config.orig_duplex = DUPLEX_INVALID;
+ tp->link_config.orig_autoneg = AUTONEG_INVALID;
+}
+
static int __devinit tg3_phy_probe(struct tg3 *tp)
{
u32 hw_phy_id_1, hw_phy_id_2;
u32 hw_phy_id, hw_phy_id_masked;
int err;
+ /* flow control autonegotiation is default behavior */
+ tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+ tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
+
if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
return tg3_phy_init(tp);
@@ -12624,6 +12657,8 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
tp->pci_chip_rev_id != CHIPREV_ID_57765_A0)))
tp->phy_flags |= TG3_PHYFLG_EEE_CAP;
+ tg3_phy_init_link_config(tp);
+
if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) &&
!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
@@ -12679,17 +12714,6 @@ skip_phy_reset:
err = tg3_init_5401phy_dsp(tp);
}
- if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES)
- tp->link_config.advertising =
- (ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full |
- ADVERTISED_Autoneg |
- ADVERTISED_FIBRE);
- if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
- tp->link_config.advertising &=
- ~(ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full);
-
return err;
}
@@ -14422,23 +14446,6 @@ out_nofree:
return ret;
}
-static void __devinit tg3_init_link_config(struct tg3 *tp)
-{
- tp->link_config.advertising =
- (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
- ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full |
- ADVERTISED_Autoneg | ADVERTISED_MII);
- tp->link_config.speed = SPEED_INVALID;
- tp->link_config.duplex = DUPLEX_INVALID;
- tp->link_config.autoneg = AUTONEG_ENABLE;
- tp->link_config.active_speed = SPEED_INVALID;
- tp->link_config.active_duplex = DUPLEX_INVALID;
- tp->link_config.orig_speed = SPEED_INVALID;
- tp->link_config.orig_duplex = DUPLEX_INVALID;
- tp->link_config.orig_autoneg = AUTONEG_INVALID;
-}
-
static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
{
if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
@@ -14742,8 +14749,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
goto err_out_free_dev;
}
- tg3_init_link_config(tp);
-
tp->rx_pending = TG3_DEF_RX_RING_PENDING;
tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
@@ -14891,10 +14896,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
goto err_out_apeunmap;
}
- /* flow control autonegotiation is default behavior */
- tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
- tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
-
intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
--
1.7.3.4
^ permalink raw reply related
* [PATCH 3/7] tg3: Add code to verify RODATA checksum of VPD
From: Matt Carlson @ 2011-03-10 2:58 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson, stable
This patch adds code to verify the checksum stored in the "RV" info
keyword of the RODATA VPD section.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/tg3.c | 35 +++++++++++++++++++++++++++++++++++
include/linux/pci.h | 1 +
2 files changed, 36 insertions(+), 0 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8f71608..ffb0979 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10499,6 +10499,41 @@ static int tg3_test_nvram(struct tg3 *tp)
if (csum != le32_to_cpu(buf[0xfc/4]))
goto out;
+ for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
+ /* The data is in little-endian format in NVRAM.
+ * Use the big-endian read routines to preserve
+ * the byte order as it exists in NVRAM.
+ */
+ if (tg3_nvram_read_be32(tp, TG3_NVM_VPD_OFF + i, &buf[i/4]))
+ goto out;
+ }
+
+ i = pci_vpd_find_tag((u8 *)buf, 0, TG3_NVM_VPD_LEN,
+ PCI_VPD_LRDT_RO_DATA);
+ if (i > 0) {
+ j = pci_vpd_lrdt_size(&((u8 *)buf)[i]);
+ if (j < 0)
+ goto out;
+
+ if (i + PCI_VPD_LRDT_TAG_SIZE + j > TG3_NVM_VPD_LEN)
+ goto out;
+
+ i += PCI_VPD_LRDT_TAG_SIZE;
+ j = pci_vpd_find_info_keyword((u8 *)buf, i, j,
+ PCI_VPD_RO_KEYWORD_CHKSUM);
+ if (j > 0) {
+ u8 csum8 = 0;
+
+ j += PCI_VPD_INFO_FLD_HDR_SIZE;
+
+ for (i = 0; i <= j; i++)
+ csum8 += ((u8 *)buf)[i];
+
+ if (csum8)
+ goto out;
+ }
+ }
+
err = 0;
out:
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 559d028..ff5bccb 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1479,6 +1479,7 @@ void pci_request_acs(void);
#define PCI_VPD_RO_KEYWORD_PARTNO "PN"
#define PCI_VPD_RO_KEYWORD_MFR_ID "MN"
#define PCI_VPD_RO_KEYWORD_VENDOR0 "V0"
+#define PCI_VPD_RO_KEYWORD_CHKSUM "RV"
/**
* pci_vpd_lrdt_size - Extracts the Large Resource Data Type length
--
1.7.3.4
^ permalink raw reply related
* [PATCH net-next 0/7] tg3: Cleanups
From: Matt Carlson @ 2011-03-10 2:58 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson, stable
This patchset adds a 5719 workaround, VPD RODATA checksum verification,
and some code cleanups
^ permalink raw reply
* [PATCH 1/7] tg3: Add missed 5719 workaround change
From: Matt Carlson @ 2011-03-10 2:58 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson, stable
Commit 2866d956fe0ad8fc8d8a7c54104ccc879b49406d, entitled
"tg3: Expand 5719 workaround" extended a 5719 A0 workaround to all
revisions of the chip. There was a change that should have been a
part of that patch that was missed. This patch adds the missing
piece.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/tg3.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 6be4185..6fd5cf0 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -8103,7 +8103,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
/* Program the jumbo buffer descriptor ring control
* blocks on those devices that have them.
*/
- if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 ||
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))) {
/* Setup replenish threshold. */
--
1.7.3.4
^ permalink raw reply related
* [PATCH 2/7] tg3: Fix NVRAM selftest
From: Matt Carlson @ 2011-03-10 2:58 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson, stable
The tg3 NVRAM selftest actually fails when validating the checksum of
the legacy NVRAM format. However, the test still reported success
because the last update of the return code was a success from the NVRAM
reads. This patch fixes the code so that the error return code defaults
to a failure status. Then the patch fixes the reason why the checsum
validation failed.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/tg3.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 6fd5cf0..8f71608 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10487,14 +10487,16 @@ static int tg3_test_nvram(struct tg3 *tp)
goto out;
}
+ err = -EIO;
+
/* Bootstrap checksum at offset 0x10 */
csum = calc_crc((unsigned char *) buf, 0x10);
- if (csum != be32_to_cpu(buf[0x10/4]))
+ if (csum != le32_to_cpu(buf[0x10/4]))
goto out;
/* Manufacturing block starts at offset 0x74, checksum at 0xfc */
csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88);
- if (csum != be32_to_cpu(buf[0xfc/4]))
+ if (csum != le32_to_cpu(buf[0xfc/4]))
goto out;
err = 0;
--
1.7.3.4
^ permalink raw reply related
* [PATCH 5/7] tg3: Refine VAux decision process
From: Matt Carlson @ 2011-03-10 2:58 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson, stable
In the near future, the VAux switching decision process is going to get
more complicated. This patch refines and consolidates the existing
algorithm in anticipation of the new scheme.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/tg3.c | 41 +++++++++++++++++++++--------------------
1 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 73eacbd..159eb23 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -2120,7 +2120,7 @@ out:
static void tg3_frob_aux_power(struct tg3 *tp)
{
- struct tg3 *tp_peer = tp;
+ bool need_vaux = false;
/* The GPIOs do something completely different on 57765. */
if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0 ||
@@ -2128,23 +2128,32 @@ static void tg3_frob_aux_power(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
return;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) &&
+ tp->pdev_peer != tp->pdev) {
struct net_device *dev_peer;
dev_peer = pci_get_drvdata(tp->pdev_peer);
+
/* remove_one() may have been run on the peer. */
- if (!dev_peer)
- tp_peer = tp;
- else
- tp_peer = netdev_priv(dev_peer);
+ if (dev_peer) {
+ struct tg3 *tp_peer = netdev_priv(dev_peer);
+
+ if (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE)
+ return;
+
+ if ((tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) ||
+ (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ need_vaux = true;
+ }
}
- if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 ||
- (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 ||
- (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 ||
- (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
+ if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) ||
+ (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ need_vaux = true;
+
+ if (need_vaux) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
@@ -2174,10 +2183,6 @@ static void tg3_frob_aux_power(struct tg3 *tp)
u32 no_gpio2;
u32 grc_local_ctrl = 0;
- if (tp_peer != tp &&
- (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0)
- return;
-
/* Workaround to prevent overdrawing Amps. */
if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
ASIC_REV_5714) {
@@ -2216,10 +2221,6 @@ static void tg3_frob_aux_power(struct tg3 *tp)
} else {
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
- if (tp_peer != tp &&
- (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0)
- return;
-
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
(GRC_LCLCTRL_GPIO_OE1 |
GRC_LCLCTRL_GPIO_OUTPUT1), 100);
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH net-next 0/7] tg3: Cleanups
From: Matt Carlson @ 2011-03-10 3:01 UTC (permalink / raw)
To: Matt Carlson
Cc: davem@davemloft.net, netdev@vger.kernel.org, stable@kernel.org
In-Reply-To: <1299725905-8498-1-git-send-email-mcarlson@broadcom.com>
To stable, please disregard. That email address was appended by
mistake.
On Wed, Mar 09, 2011 at 06:58:18PM -0800, Matt Carlson wrote:
> This patchset adds a 5719 workaround, VPD RODATA checksum verification,
> and some code cleanups
>
^ permalink raw reply
* Re: [Bugme-new] [Bug 29252] New: IPv6 doesn't work in a kvm guest.
From: David Miller @ 2011-03-10 3:20 UTC (permalink / raw)
To: akpm; +Cc: netdev, bugzilla-daemon, bugme-daemon, slash, ernstp
In-Reply-To: <20110309.155818.212679516.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Wed, 09 Mar 2011 15:58:18 -0800 (PST)
> Ok, the following should address both bugs, #29252 and #30462, please
> give it some testing.
>
> --------------------
> ipv6: Don't create clones of nonexthop routes forever.
Nevermind, this patch has problems, I'm still debugging and trying to
come up with a proper fix.
Thanks in advance for your patience.
^ permalink raw reply
* Re: [Bugme-new] [Bug 29252] New: IPv6 doesn't work in a kvm guest.
From: David Miller @ 2011-03-10 4:04 UTC (permalink / raw)
To: akpm; +Cc: netdev, bugzilla-daemon, bugme-daemon, slash, ernstp
In-Reply-To: <20110309.192012.193710171.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Wed, 09 Mar 2011 19:20:12 -0800 (PST)
> From: David Miller <davem@davemloft.net>
> Date: Wed, 09 Mar 2011 15:58:18 -0800 (PST)
>
>> Ok, the following should address both bugs, #29252 and #30462, please
>> give it some testing.
>>
>> --------------------
>> ipv6: Don't create clones of nonexthop routes forever.
>
> Nevermind, this patch has problems, I'm still debugging and trying to
> come up with a proper fix.
>
> Thanks in advance for your patience.
Ok, I'm more confident in this version of the fix. It passes all of
my tests, and I've added instrumentation to make sure various cases
are performing the operations the way I expect them to.
--------------------
ipv6: Don't create clones of host routes.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Addresses https://bugzilla.kernel.org/show_bug.cgi?id=29252
Addresses https://bugzilla.kernel.org/show_bug.cgi?id=30462
In commit d80bc0fd262ef840ed4e82593ad6416fa1ba3fc4 ("ipv6: Always
clone offlink routes.") we forced the kernel to always clone offlink
routes.
The reason we do that is to make sure we never bind an inetpeer to a
prefixed route.
The logic turned on here has existed in the tree for many years,
but was always off due to a protecting CPP define. So perhaps
it's no surprise that there is a logic bug here.
The problem is that we canot clone a route that is already a
host route (ie. has DST_HOST set). Because if we do, an identical
entry already exists in the routing tree and therefore the
ip6_rt_ins() call is going to fail.
This sets off a series of failures and high cpu usage, because when
ip6_rt_ins() fails we loop retrying this operation a few times in
order to handle a race between two threads trying to clone and insert
the same host route at the same time.
Fix this by simply using the route as-is when DST_HOST is set.
Reported-by: slash@ac.auone-net.jp
Reported-by: Ernst Sjöstrand <ernstp@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv6/route.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 904312e..e7db701 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -739,8 +739,10 @@ restart:
if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src);
- else
+ else if (!(rt->dst.flags & DST_HOST))
nrt = rt6_alloc_clone(rt, &fl->fl6_dst);
+ else
+ goto out2;
dst_release(&rt->dst);
rt = nrt ? : net->ipv6.ip6_null_entry;
--
1.7.4.1
^ permalink raw reply related
* Re: [PATCH 03/18] ipvs: zero percpu stats
From: Simon Horman @ 2011-03-10 4:27 UTC (permalink / raw)
To: David Miller
Cc: ja, eric.dumazet, netdev, netfilter-devel, netfilter, lvs-devel,
hans
In-Reply-To: <20110309.185344.193704334.davem@davemloft.net>
On Wed, Mar 09, 2011 at 06:53:44PM -0800, David Miller wrote:
> From: Simon Horman <horms@verge.net.au>
> Date: Thu, 10 Mar 2011 10:34:42 +0900
>
> > On Sun, Mar 06, 2011 at 02:18:35PM +0200, Julian Anastasov wrote:
> >
> > [ snip ]
> >
> >> Zero the new percpu stats because we copy from there.
> >> Use the stats spin lock to synchronize the percpu zeroing with
> >> the percpu reading, both in user context and not in a hot path.
> >>
> >> Signed-off-by: Julian Anastasov <ja@ssi.bg>
> >
> > Eric, do you have any thoughts on this?
> > It seems clean to me.
>
> Eric is away until this weekend, so don't be alarmed by a
> late response :-)
Thanks, I'll wait longer :-)
^ permalink raw reply
* [PATCH] ipv4: Optimize flow initialization in input route lookup.
From: David Miller @ 2011-03-10 4:42 UTC (permalink / raw)
To: netdev
Like in commit 44713b67db10c774f14280c129b0d5fd13c70cf2
("ipv4: Optimize flow initialization in output route lookup."
we can optimize the on-stack flow setup to only initialize
the members which are actually used.
Otherwise we bzero the entire structure, then initialize
explicitly the first half of it.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv4/route.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 92a24ea..ac32d8f 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2081,12 +2081,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
{
struct fib_result res;
struct in_device *in_dev = __in_dev_get_rcu(dev);
- struct flowi fl = { .fl4_dst = daddr,
- .fl4_src = saddr,
- .fl4_tos = tos,
- .fl4_scope = RT_SCOPE_UNIVERSE,
- .mark = skb->mark,
- .iif = dev->ifindex };
+ struct flowi fl;
unsigned flags = 0;
u32 itag = 0;
struct rtable * rth;
@@ -2123,6 +2118,13 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
/*
* Now we are ready to route packet.
*/
+ fl.oif = 0;
+ fl.iif = dev->ifindex;
+ fl.mark = skb->mark;
+ fl.fl4_dst = daddr;
+ fl.fl4_src = saddr;
+ fl.fl4_tos = tos;
+ fl.fl4_scope = RT_SCOPE_UNIVERSE;
err = fib_lookup(net, &fl, &res);
if (err != 0) {
if (!IN_DEV_FORWARD(in_dev))
--
1.7.4.1
^ permalink raw reply related
* [PATCH] ipv4: Optimize flow initialization in fib_validate_source().
From: David Miller @ 2011-03-10 4:58 UTC (permalink / raw)
To: netdev
Like in commit 44713b67db10c774f14280c129b0d5fd13c70cf2
("ipv4: Optimize flow initialization in output route lookup."
we can optimize the on-stack flow setup to only initialize
the members which are actually used.
Otherwise we bzero the entire structure, then initialize
explicitly the first half of it.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv4/fib_frontend.c | 16 +++++++++-------
1 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 1d2233c..fe10bcd 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -193,19 +193,21 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
u32 *itag, u32 mark)
{
struct in_device *in_dev;
- struct flowi fl = {
- .fl4_dst = src,
- .fl4_src = dst,
- .fl4_tos = tos,
- .mark = mark,
- .iif = oif
- };
+ struct flowi fl;
struct fib_result res;
int no_addr, rpf, accept_local;
bool dev_match;
int ret;
struct net *net;
+ fl.oif = 0;
+ fl.iif = oif;
+ fl.mark = mark;
+ fl.fl4_dst = src;
+ fl.fl4_src = dst;
+ fl.fl4_tos = tos;
+ fl.fl4_scope = RT_SCOPE_UNIVERSE;
+
no_addr = rpf = accept_local = 0;
in_dev = __in_dev_get_rcu(dev);
if (in_dev) {
--
1.7.4.1
^ permalink raw reply related
* Re: [PATCH] Make CUBIC Hystart more robust to RTT variations
From: Bill Fink @ 2011-03-10 5:24 UTC (permalink / raw)
To: Lucas Nussbaum
Cc: Injong Rhee, Stephen Hemminger, David Miller, xiyou.wangcong,
netdev, sangtae.ha
In-Reply-To: <20110309065319.GA23740@xanadu.blop.info>
On Wed, 9 Mar 2011, Lucas Nussbaum wrote:
> On 08/03/11 at 20:30 -0500, Injong Rhee wrote:
> > Now, both tools can be wrong. But that is not catastrophic since
> > congestion avoidance can kick in to save the day. In a pipe where no
> > other flows are competing, then exiting slow start too early can
> > slow things down as the window can be still too small. But that is
> > in fact when delays are most reliable. So those tests that say bad
> > performance with hystart are in fact, where hystart is supposed to
> > perform well.
>
> Hi,
>
> In my setup, there is no congestion at all (except the buffer bloat).
> Without Hystart, transferring 8 Gb of data takes 9s, with CUBIC exiting
> slow start at ~2000 packets.
> With Hystart, transferring 8 Gb of data takes 19s, with CUBIC exiting
> slow start at ~20 packets.
> I don't think that this is "hystart performing well". We could just as
> well remove slow start completely, and only do congestion avoidance,
> then.
>
> While I see the value in Hystart, it's clear that there are some flaws
> in the current implementation. It probably makes sense to disable
> hystart by default until those problems are fixed.
Here are some tests I performed across real networks, where
congestion is generally not an issue, with a 2.6.35 kernel on
the transmit side.
8 GB transfer across an 18 ms RTT path with autotuning and hystart:
i7test7% nuttcp -n8g -i1 192.168.1.23
517.9375 MB / 1.00 sec = 4344.6096 Mbps 0 retrans
688.4375 MB / 1.00 sec = 5775.1998 Mbps 0 retrans
692.9375 MB / 1.00 sec = 5812.7462 Mbps 0 retrans
698.0625 MB / 1.00 sec = 5855.8078 Mbps 0 retrans
699.8750 MB / 1.00 sec = 5871.0123 Mbps 0 retrans
710.5625 MB / 1.00 sec = 5960.5707 Mbps 0 retrans
728.8125 MB / 1.00 sec = 6113.7652 Mbps 0 retrans
751.3750 MB / 1.00 sec = 6302.9210 Mbps 0 retrans
783.8750 MB / 1.00 sec = 6575.6201 Mbps 0 retrans
825.1875 MB / 1.00 sec = 6921.8145 Mbps 0 retrans
875.4375 MB / 1.00 sec = 7343.9811 Mbps 0 retrans
8192.0000 MB / 11.26 sec = 6102.4718 Mbps 11 %TX 28 %RX 0 retrans 18.92 msRTT
Ramps up quickly to a little under 6 Gbps, then increases more
slowly to 7+ Gbps, with no TCP retransmissions.
8 GB transfer across an 18 ms RTT path with 40 MB socket buffer and hystart:
i7test7% nuttcp -n8g -w40m -i1 192.168.1.23
970.0625 MB / 1.00 sec = 8136.8475 Mbps 0 retrans
1181.1875 MB / 1.00 sec = 9909.0045 Mbps 0 retrans
1181.2500 MB / 1.00 sec = 9908.6369 Mbps 0 retrans
1181.3125 MB / 1.00 sec = 9909.8747 Mbps 0 retrans
1181.2500 MB / 1.00 sec = 9909.0531 Mbps 0 retrans
1181.2500 MB / 1.00 sec = 9908.8153 Mbps 0 retrans
1181.2500 MB / 1.00 sec = 9909.0729 Mbps 0 retrans
8192.0000 MB / 7.13 sec = 9633.5814 Mbps 17 %TX 42 %RX 0 retrans 18.91 msRTT
Quickly ramps up to full 10-GigE line rate, with no TCP retrans.
8 GB transfer across an 18 ms RTT path with autotuning and no hystart:
i7test7% nuttcp -n8g -i1 192.168.1.23
845.4375 MB / 1.00 sec = 7091.5828 Mbps 0 retrans
1181.3125 MB / 1.00 sec = 9910.0134 Mbps 0 retrans
1181.0625 MB / 1.00 sec = 9907.1830 Mbps 0 retrans
1181.4375 MB / 1.00 sec = 9910.8936 Mbps 0 retrans
1181.1875 MB / 1.00 sec = 9908.1721 Mbps 0 retrans
1181.3125 MB / 1.00 sec = 9909.5774 Mbps 0 retrans
1181.1875 MB / 1.00 sec = 9908.6874 Mbps 0 retrans
8192.0000 MB / 7.25 sec = 9484.4524 Mbps 18 %TX 41 %RX 0 retrans 18.92 msRTT
Also quickly ramps up to full 10-GigE line rate, with no TCP retrans.
8 GB transfer across an 18 ms RTT path with 40 MB socket buffer and no hystart:
i7test7% nuttcp -n8g -w40m -i1 192.168.1.23
969.8750 MB / 1.00 sec = 8135.6571 Mbps 0 retrans
1181.3125 MB / 1.00 sec = 9909.3990 Mbps 0 retrans
1181.2500 MB / 1.00 sec = 9908.9342 Mbps 0 retrans
1181.2500 MB / 1.00 sec = 9909.4098 Mbps 0 retrans
1181.2500 MB / 1.00 sec = 9908.8252 Mbps 0 retrans
1181.2500 MB / 1.00 sec = 9909.0630 Mbps 0 retrans
1181.2500 MB / 1.00 sec = 9909.3504 Mbps 0 retrans
8192.0000 MB / 7.15 sec = 9611.8053 Mbps 18 %TX 42 %RX 0 retrans 18.95 msRTT
Basically the same as the case with 40 MB socket buffer and hystart enabled.
Now trying the same type of tests across an 80 ms RTT path.
8 GB transfer across an 80 ms RTT path with autotuning and hystart:
i7test7% nuttcp -n8g -i1 192.168.1.18
11.3125 MB / 1.00 sec = 94.8954 Mbps 0 retrans
441.5625 MB / 1.00 sec = 3704.1021 Mbps 0 retrans
687.3750 MB / 1.00 sec = 5765.8657 Mbps 0 retrans
715.5625 MB / 1.00 sec = 6002.6273 Mbps 0 retrans
709.9375 MB / 1.00 sec = 5955.5958 Mbps 0 retrans
691.3125 MB / 1.00 sec = 5799.0626 Mbps 0 retrans
718.6250 MB / 1.00 sec = 6028.3538 Mbps 0 retrans
718.0000 MB / 1.00 sec = 6023.0205 Mbps 0 retrans
704.0000 MB / 1.00 sec = 5905.5387 Mbps 0 retrans
733.3125 MB / 1.00 sec = 6151.4096 Mbps 0 retrans
738.8750 MB / 1.00 sec = 6198.2381 Mbps 0 retrans
731.8750 MB / 1.00 sec = 6139.3695 Mbps 0 retrans
8192.0000 MB / 12.85 sec = 5348.9677 Mbps 10 %TX 23 %RX 0 retrans 80.81 msRTT
Similar to the 20 ms RTT path, but achieving somewhat lower
performance levels, presumably due to the larger RTT. Ramps
up fairly quickly to a little under 6 Gbps, then increases
more slowly to 6+ Gbps, with no TCP retransmissions.
8 GB transfer across an 80 ms RTT path with 100 MB socket buffer and hystart:
i7test7% nuttcp -n8g -w100m -i1 192.168.1.18
103.9375 MB / 1.00 sec = 871.8378 Mbps 0 retrans
1086.5625 MB / 1.00 sec = 9114.6102 Mbps 0 retrans
1106.6875 MB / 1.00 sec = 9283.5583 Mbps 0 retrans
1109.3125 MB / 1.00 sec = 9305.5226 Mbps 0 retrans
1111.1875 MB / 1.00 sec = 9321.9596 Mbps 0 retrans
1112.8125 MB / 1.00 sec = 9334.8452 Mbps 0 retrans
1113.6875 MB / 1.00 sec = 9341.6620 Mbps 0 retrans
1120.2500 MB / 1.00 sec = 9398.0054 Mbps 0 retrans
8192.0000 MB / 8.37 sec = 8207.2049 Mbps 16 %TX 38 %RX 0 retrans 80.81 msRTT
Quickly ramps up to 9+ Gbps and then slowly increases further,
with no TCP retrans.
8 GB transfer across an 80 ms RTT path with autotuning and no hystart:
i7test7% nuttcp -n8g -i1 192.168.1.18
11.2500 MB / 1.00 sec = 94.3703 Mbps 0 retrans
519.0625 MB / 1.00 sec = 4354.1596 Mbps 0 retrans
861.2500 MB / 1.00 sec = 7224.7970 Mbps 0 retrans
871.0000 MB / 1.00 sec = 7306.4191 Mbps 0 retrans
860.7500 MB / 1.00 sec = 7220.4438 Mbps 0 retrans
869.0625 MB / 1.00 sec = 7290.3340 Mbps 0 retrans
863.4375 MB / 1.00 sec = 7242.7707 Mbps 0 retrans
860.4375 MB / 1.00 sec = 7218.0606 Mbps 0 retrans
875.5000 MB / 1.00 sec = 7344.3071 Mbps 0 retrans
863.1875 MB / 1.00 sec = 7240.8257 Mbps 0 retrans
8192.0000 MB / 10.98 sec = 6259.4379 Mbps 12 %TX 27 %RX 0 retrans 80.81 msRTT
Ramps up quickly to 7+ Gbps, then appears to stabilize at that
level, with no TCP retransmissions. Performance is somewhat
better than with autotuning enabled, but less than using a
manually set 100 MB socket buffer.
8 GB transfer across an 80 ms RTT path with 100 MB socket buffer and no hystart:
i7test7% nuttcp -n8g -w100m -i1 192.168.1.18
102.8750 MB / 1.00 sec = 862.9487 Mbps 0 retrans
522.8750 MB / 1.00 sec = 4386.2811 Mbps 414 retrans
881.5625 MB / 1.00 sec = 7394.6534 Mbps 0 retrans
1164.3125 MB / 1.00 sec = 9766.6682 Mbps 0 retrans
1170.5625 MB / 1.00 sec = 9819.7042 Mbps 0 retrans
1166.8125 MB / 1.00 sec = 9788.2067 Mbps 0 retrans
1159.8750 MB / 1.00 sec = 9729.1530 Mbps 0 retrans
811.1250 MB / 1.00 sec = 6804.8017 Mbps 21 retrans
73.2500 MB / 1.00 sec = 614.4674 Mbps 0 retrans
884.6250 MB / 1.00 sec = 7420.2900 Mbps 0 retrans
8192.0000 MB / 10.34 sec = 6647.9394 Mbps 13 %TX 31 %RX 435 retrans 80.81 msRTT
Disabling hystart on a large RTT path does not seem to play nice with
a manually specified socket buffer, resulting in TCP retransmissions
that limit the effective network performance.
This is a repeatable but extremely variable phenomenon.
i7test7% nuttcp -n8g -w100m -i1 192.168.1.18
103.7500 MB / 1.00 sec = 870.3015 Mbps 0 retrans
1146.3750 MB / 1.00 sec = 9616.4520 Mbps 0 retrans
1175.9375 MB / 1.00 sec = 9864.6070 Mbps 0 retrans
615.6875 MB / 1.00 sec = 5164.7353 Mbps 21 retrans
139.2500 MB / 1.00 sec = 1168.1253 Mbps 0 retrans
1090.0625 MB / 1.00 sec = 9143.8053 Mbps 0 retrans
1170.4375 MB / 1.00 sec = 9818.6654 Mbps 0 retrans
1174.5625 MB / 1.00 sec = 9852.8754 Mbps 0 retrans
1174.8750 MB / 1.00 sec = 9855.6052 Mbps 0 retrans
8192.0000 MB / 9.42 sec = 7292.9879 Mbps 14 %TX 34 %RX 21 retrans 80.81 msRTT
And:
i7test7% nuttcp -n8g -w100m -i1 192.168.1.18
102.8125 MB / 1.00 sec = 862.4227 Mbps 0 retrans
1148.4375 MB / 1.00 sec = 9633.6860 Mbps 0 retrans
1177.4375 MB / 1.00 sec = 9877.3086 Mbps 0 retrans
1168.1250 MB / 1.00 sec = 9798.9133 Mbps 11 retrans
133.1250 MB / 1.00 sec = 1116.7457 Mbps 0 retrans
479.8750 MB / 1.00 sec = 4025.4631 Mbps 0 retrans
1150.6875 MB / 1.00 sec = 9652.4830 Mbps 0 retrans
1177.3125 MB / 1.00 sec = 9876.0624 Mbps 0 retrans
1177.3750 MB / 1.00 sec = 9876.0139 Mbps 0 retrans
320.2500 MB / 1.00 sec = 2686.6452 Mbps 19 retrans
64.9375 MB / 1.00 sec = 544.7363 Mbps 0 retrans
73.6250 MB / 1.00 sec = 617.6113 Mbps 0 retrans
8192.0000 MB / 12.39 sec = 5545.7570 Mbps 12 %TX 26 %RX 30 retrans 80.80 msRTT
Re-enabling hystart immediately gives a clean test with no TCP retrans.
i7test7% nuttcp -n8g -w100m -i1 192.168.1.18
103.8750 MB / 1.00 sec = 871.3353 Mbps 0 retrans
1086.7500 MB / 1.00 sec = 9116.4474 Mbps 0 retrans
1105.8125 MB / 1.00 sec = 9276.2276 Mbps 0 retrans
1109.4375 MB / 1.00 sec = 9306.5339 Mbps 0 retrans
1111.3125 MB / 1.00 sec = 9322.5327 Mbps 0 retrans
1111.3750 MB / 1.00 sec = 9322.8053 Mbps 0 retrans
1113.7500 MB / 1.00 sec = 9342.8962 Mbps 0 retrans
1120.3125 MB / 1.00 sec = 9397.5711 Mbps 0 retrans
8192.0000 MB / 8.38 sec = 8204.8394 Mbps 16 %TX 39 %RX 0 retrans 80.80 msRTT
-Bill
^ permalink raw reply
* [PATCH net-next-2.6] ipv4: Fix PMTU update.
From: Hiroaki SHIMODA @ 2011-03-10 6:09 UTC (permalink / raw)
To: davem; +Cc: netdev
On current net-next-2.6, when Linux receives ICMP Type: 3, Code: 4
(Destination unreachable (Fragmentation needed)),
icmp_unreach
-> ip_rt_frag_needed
(peer->pmtu_expires is set here)
-> tcp_v4_err
-> do_pmtu_discovery
-> ip_rt_update_pmtu
(peer->pmtu_expires is already set,
so check_peer_pmtu is skipped.)
-> check_peer_pmtu
check_peer_pmtu is skipped and MTU is not updated.
To fix this, let check_peer_pmtu execute unconditionally.
And some minor fixes
1) Avoid potential peer->pmtu_expires set to be zero.
2) In check_peer_pmtu, argument of time_before is reversed.
3) check_peer_pmtu expects peer->pmtu_orig is initialized as zero,
but not initialized.
Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
---
net/ipv4/inetpeer.c | 1 +
net/ipv4/route.c | 22 +++++++++++++++++-----
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 6442c35..86b1d08 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -511,6 +511,7 @@ struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create)
p->rate_tokens = 0;
p->rate_last = 0;
p->pmtu_expires = 0;
+ p->pmtu_orig = 0;
memset(&p->redirect_learned, 0, sizeof(p->redirect_learned));
INIT_LIST_HEAD(&p->unused);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 92a24ea..3cf8001 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1533,9 +1533,15 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
if (mtu < ip_rt_min_pmtu)
mtu = ip_rt_min_pmtu;
if (!peer->pmtu_expires || mtu < peer->pmtu_learned) {
+ unsigned long pmtu_expires;
+
+ pmtu_expires = jiffies + ip_rt_mtu_expires;
+ if (!pmtu_expires)
+ pmtu_expires = 1UL;
+
est_mtu = mtu;
peer->pmtu_learned = mtu;
- peer->pmtu_expires = jiffies + ip_rt_mtu_expires;
+ peer->pmtu_expires = pmtu_expires;
}
inet_putpeer(peer);
@@ -1549,7 +1555,7 @@ static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer)
{
unsigned long expires = peer->pmtu_expires;
- if (time_before(expires, jiffies)) {
+ if (time_before(jiffies, expires)) {
u32 orig_dst_mtu = dst_mtu(dst);
if (peer->pmtu_learned < orig_dst_mtu) {
if (!peer->pmtu_orig)
@@ -1574,14 +1580,20 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
if (mtu < ip_rt_min_pmtu)
mtu = ip_rt_min_pmtu;
if (!peer->pmtu_expires || mtu < peer->pmtu_learned) {
+ unsigned long pmtu_expires;
+
+ pmtu_expires = jiffies + ip_rt_mtu_expires;
+ if (!pmtu_expires)
+ pmtu_expires = 1UL;
+
peer->pmtu_learned = mtu;
- peer->pmtu_expires = jiffies + ip_rt_mtu_expires;
+ peer->pmtu_expires = pmtu_expires;
atomic_inc(&__rt_peer_genid);
rt->rt_peer_genid = rt_peer_genid();
-
- check_peer_pmtu(dst, peer);
}
+ check_peer_pmtu(dst, peer);
+
inet_putpeer(peer);
}
}
^ permalink raw reply related
* Re: [PATCH] Make CUBIC Hystart more robust to RTT variations
From: Stephen Hemminger @ 2011-03-10 6:17 UTC (permalink / raw)
To: Bill Fink
Cc: Injong Rhee, David Miller, xiyou wangcong, netdev, sangtae ha,
Lucas Nussbaum
In-Reply-To: <20110310002458.5a94f563.billfink@mindspring.com>
Bill what is the HZ in your kernel config.
I am concerned hystart doesn't work well with HZ=100
^ permalink raw reply
* Re: [patch net-next-2.6] net: reinject arps into bonding slave instead of master
From: Jiri Pirko @ 2011-03-10 6:48 UTC (permalink / raw)
To: Nicolas de Pesloüan
Cc: Andy Gospodarek, netdev, davem, shemminger, kaber, fubar,
eric.dumazet
In-Reply-To: <4D77FCC1.5050904@gmail.com>
>But for all others setups, where there exist some net_devices before
>the "untagging" one, you would face some troubles. For example, with
>eth0+eth1 -> br0 -> br0.100, you cannot untag before entering
>__netif_receive_skb. If you do so, the bridge would receive untagged
>frame and if the frame is not for the local host, the bridge would
>forward an untagged frame while it is expected to forward a tagged
>one. Even if the bridge is in a position to know the frame *was*
>tagged, we cannot expect the bridge to do special processing to
>handle this situation. Doing so would break layering.
I disagree.
eth0 -> untag on early __netif_receive_skb (sets up skb->vlan_tci)
->rx_handler of bridge
->br0 -> tag is detected by vlan_tx_tag_present()
-> reinject to __netif_receive_skb with skb->dev == br0.100
This way the flow would be very similar to vlan-hw-accel, am I right?
I have following patch in mind. Note it's raw DRAFT.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
include/linux/if_vlan.h | 5 ++
net/8021q/vlan.c | 8 --
net/8021q/vlan_core.c | 106 +++++++++++++++++++++++++++++
net/8021q/vlan_dev.c | 172 -----------------------------------------------
net/core/dev.c | 18 ++++-
5 files changed, 125 insertions(+), 184 deletions(-)
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 635e1fa..dd914e2 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -133,6 +133,7 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev);
extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
u16 vlan_tci, int polling);
extern bool vlan_hwaccel_do_receive(struct sk_buff **skb);
+extern void vlan_emulate_hwaccel(struct sk_buff **skbp);
extern gro_result_t
vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
unsigned int vlan_tci, struct sk_buff *skb);
@@ -173,6 +174,10 @@ static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb)
return false;
}
+void vlan_emulate_hwaccel(struct sk_buff **skbp)
+{
+}
+
static inline gro_result_t
vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
unsigned int vlan_tci, struct sk_buff *skb)
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 7850412..59f0a9d 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -49,11 +49,6 @@ const char vlan_version[] = DRV_VERSION;
static const char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
static const char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";
-static struct packet_type vlan_packet_type __read_mostly = {
- .type = cpu_to_be16(ETH_P_8021Q),
- .func = vlan_skb_recv, /* VLAN receive method */
-};
-
/* End of global variables definitions. */
static void vlan_group_free(struct vlan_group *grp)
@@ -688,7 +683,6 @@ static int __init vlan_proto_init(void)
if (err < 0)
goto err4;
- dev_add_pack(&vlan_packet_type);
vlan_ioctl_set(vlan_ioctl_handler);
return 0;
@@ -709,8 +703,6 @@ static void __exit vlan_cleanup_module(void)
unregister_netdevice_notifier(&vlan_notifier_block);
- dev_remove_pack(&vlan_packet_type);
-
unregister_pernet_subsys(&vlan_net_ops);
rcu_barrier(); /* Wait for completion of call_rcu()'s */
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index ce8e3ab..c324e4d 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -88,3 +88,109 @@ gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
return napi_gro_frags(napi);
}
EXPORT_SYMBOL(vlan_gro_frags);
+
+static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
+{
+ if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) {
+ if (skb_cow(skb, skb_headroom(skb)) < 0)
+ skb = NULL;
+ if (skb) {
+ /* Lifted from Gleb's VLAN code... */
+ memmove(skb->data - ETH_HLEN,
+ skb->data - VLAN_ETH_HLEN, 12);
+ skb->mac_header += VLAN_HLEN;
+ }
+ }
+
+ return skb;
+}
+
+static inline void vlan_set_encap_proto(struct sk_buff *skb,
+ struct vlan_hdr *vhdr)
+{
+ __be16 proto;
+ unsigned char *rawp;
+
+ /*
+ * Was a VLAN packet, grab the encapsulated protocol, which the layer
+ * three protocols care about.
+ */
+
+ proto = vhdr->h_vlan_encapsulated_proto;
+ if (ntohs(proto) >= 1536) {
+ skb->protocol = proto;
+ return;
+ }
+
+ rawp = skb->data;
+ if (*(unsigned short *)rawp == 0xFFFF)
+ /*
+ * This is a magic hack to spot IPX packets. Older Novell
+ * breaks the protocol design and runs IPX over 802.3 without
+ * an 802.2 LLC layer. We look for FFFF which isn't a used
+ * 802.2 SSAP/DSAP. This won't work for fault tolerant netware
+ * but does for the rest.
+ */
+ skb->protocol = htons(ETH_P_802_3);
+ else
+ /*
+ * Real 802.2 LLC
+ */
+ skb->protocol = htons(ETH_P_802_2);
+}
+
+/*
+ * Determine the packet's protocol ID. The rule here is that we
+ * assume 802.3 if the type field is short enough to be a length.
+ * This is normal practice and works for any 'now in use' protocol.
+ *
+ * Also, at this point we assume that we ARE dealing exclusively with
+ * VLAN packets, or packets that should be made into VLAN packets based
+ * on a default VLAN ID.
+ *
+ * NOTE: Should be similar to ethernet/eth.c.
+ *
+ * SANITY NOTE: This method is called when a packet is moving up the stack
+ * towards userland. To get here, it would have already passed
+ * through the ethernet/eth.c eth_type_trans() method.
+ * SANITY NOTE 2: We are referencing to the VLAN_HDR frields, which MAY be
+ * stored UNALIGNED in the memory. RISC systems don't like
+ * such cases very much...
+ * SANITY NOTE 2a: According to Dave Miller & Alexey, it will always be
+ * aligned, so there doesn't need to be any of the unaligned
+ * stuff. It has been commented out now... --Ben
+ *
+ */
+void vlan_emulate_hwaccel(struct sk_buff **skbp)
+{
+ struct sk_buff *skb = *skbp;
+ struct vlan_hdr *vhdr;
+ u16 vlan_tci;
+
+ *skbp = skb = skb_share_check(skb, GFP_ATOMIC);
+ if (unlikely(!skb))
+ goto err_free;
+
+ if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
+ goto err_free;
+
+ vhdr = (struct vlan_hdr *) skb->data;
+ vlan_tci = ntohs(vhdr->h_vlan_TCI);
+ __vlan_hwaccel_put_tag(skb, vlan_tci);
+
+ skb_pull_rcsum(skb, VLAN_HLEN);
+ vlan_set_encap_proto(skb, vhdr);
+
+ skb = vlan_check_reorder_header(skb);
+ if (unlikely(!skb)) {
+ goto err_free;
+ }
+
+ return;
+
+err_free:
+ kfree_skb(skb);
+ *skbp = NULL;
+ return;
+}
+
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index ae610f0..57d2f40 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -65,178 +65,6 @@ static int vlan_dev_rebuild_header(struct sk_buff *skb)
return 0;
}
-static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
-{
- if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) {
- if (skb_cow(skb, skb_headroom(skb)) < 0)
- skb = NULL;
- if (skb) {
- /* Lifted from Gleb's VLAN code... */
- memmove(skb->data - ETH_HLEN,
- skb->data - VLAN_ETH_HLEN, 12);
- skb->mac_header += VLAN_HLEN;
- }
- }
-
- return skb;
-}
-
-static inline void vlan_set_encap_proto(struct sk_buff *skb,
- struct vlan_hdr *vhdr)
-{
- __be16 proto;
- unsigned char *rawp;
-
- /*
- * Was a VLAN packet, grab the encapsulated protocol, which the layer
- * three protocols care about.
- */
-
- proto = vhdr->h_vlan_encapsulated_proto;
- if (ntohs(proto) >= 1536) {
- skb->protocol = proto;
- return;
- }
-
- rawp = skb->data;
- if (*(unsigned short *)rawp == 0xFFFF)
- /*
- * This is a magic hack to spot IPX packets. Older Novell
- * breaks the protocol design and runs IPX over 802.3 without
- * an 802.2 LLC layer. We look for FFFF which isn't a used
- * 802.2 SSAP/DSAP. This won't work for fault tolerant netware
- * but does for the rest.
- */
- skb->protocol = htons(ETH_P_802_3);
- else
- /*
- * Real 802.2 LLC
- */
- skb->protocol = htons(ETH_P_802_2);
-}
-
-/*
- * Determine the packet's protocol ID. The rule here is that we
- * assume 802.3 if the type field is short enough to be a length.
- * This is normal practice and works for any 'now in use' protocol.
- *
- * Also, at this point we assume that we ARE dealing exclusively with
- * VLAN packets, or packets that should be made into VLAN packets based
- * on a default VLAN ID.
- *
- * NOTE: Should be similar to ethernet/eth.c.
- *
- * SANITY NOTE: This method is called when a packet is moving up the stack
- * towards userland. To get here, it would have already passed
- * through the ethernet/eth.c eth_type_trans() method.
- * SANITY NOTE 2: We are referencing to the VLAN_HDR frields, which MAY be
- * stored UNALIGNED in the memory. RISC systems don't like
- * such cases very much...
- * SANITY NOTE 2a: According to Dave Miller & Alexey, it will always be
- * aligned, so there doesn't need to be any of the unaligned
- * stuff. It has been commented out now... --Ben
- *
- */
-int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *ptype, struct net_device *orig_dev)
-{
- struct vlan_hdr *vhdr;
- struct vlan_pcpu_stats *rx_stats;
- struct net_device *vlan_dev;
- u16 vlan_id;
- u16 vlan_tci;
-
- skb = skb_share_check(skb, GFP_ATOMIC);
- if (skb == NULL)
- goto err_free;
-
- if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
- goto err_free;
-
- vhdr = (struct vlan_hdr *)skb->data;
- vlan_tci = ntohs(vhdr->h_vlan_TCI);
- vlan_id = vlan_tci & VLAN_VID_MASK;
-
- rcu_read_lock();
- vlan_dev = vlan_find_dev(dev, vlan_id);
-
- /* If the VLAN device is defined, we use it.
- * If not, and the VID is 0, it is a 802.1p packet (not
- * really a VLAN), so we will just netif_rx it later to the
- * original interface, but with the skb->proto set to the
- * wrapped proto: we do nothing here.
- */
-
- if (!vlan_dev) {
- if (vlan_id) {
- pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n",
- __func__, vlan_id, dev->name);
- goto err_unlock;
- }
- rx_stats = NULL;
- } else {
- skb->dev = vlan_dev;
-
- rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_pcpu_stats);
-
- u64_stats_update_begin(&rx_stats->syncp);
- rx_stats->rx_packets++;
- rx_stats->rx_bytes += skb->len;
-
- skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tci);
-
- pr_debug("%s: priority: %u for TCI: %hu\n",
- __func__, skb->priority, vlan_tci);
-
- switch (skb->pkt_type) {
- case PACKET_BROADCAST:
- /* Yeah, stats collect these together.. */
- /* stats->broadcast ++; // no such counter :-( */
- break;
-
- case PACKET_MULTICAST:
- rx_stats->rx_multicast++;
- break;
-
- case PACKET_OTHERHOST:
- /* Our lower layer thinks this is not local, let's make
- * sure.
- * This allows the VLAN to have a different MAC than the
- * underlying device, and still route correctly.
- */
- if (!compare_ether_addr(eth_hdr(skb)->h_dest,
- skb->dev->dev_addr))
- skb->pkt_type = PACKET_HOST;
- break;
- default:
- break;
- }
- u64_stats_update_end(&rx_stats->syncp);
- }
-
- skb_pull_rcsum(skb, VLAN_HLEN);
- vlan_set_encap_proto(skb, vhdr);
-
- if (vlan_dev) {
- skb = vlan_check_reorder_header(skb);
- if (!skb) {
- rx_stats->rx_errors++;
- goto err_unlock;
- }
- }
-
- netif_rx(skb);
-
- rcu_read_unlock();
- return NET_RX_SUCCESS;
-
-err_unlock:
- rcu_read_unlock();
-err_free:
- atomic_long_inc(&dev->rx_dropped);
- kfree_skb(skb);
- return NET_RX_DROP;
-}
static inline u16
vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb)
diff --git a/net/core/dev.c b/net/core/dev.c
index 9f66de9..f3315ef 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3133,10 +3133,6 @@ static int __netif_receive_skb(struct sk_buff *skb)
if (netpoll_receive_skb(skb))
return NET_RX_DROP;
- if (!skb->skb_iif)
- skb->skb_iif = skb->dev->ifindex;
- orig_dev = skb->dev;
-
skb_reset_network_header(skb);
skb_reset_transport_header(skb);
skb->mac_len = skb->network_header - skb->mac_header;
@@ -3145,6 +3141,20 @@ static int __netif_receive_skb(struct sk_buff *skb)
rcu_read_lock();
+ if (!skb->skb_iif) {
+ skb->skb_iif = skb->dev->ifindex;
+ /*
+ * frame is here for the first time so lets check if it's vlan
+ * one and emulate vlan hwaccel in that case
+ */
+ if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
+ vlan_emulate_hwaccel(&skb);
+ if (!skb)
+ goto out;
+ }
+ }
+ orig_dev = skb->dev;
+
another_round:
__this_cpu_inc(softnet_data.processed);
--
1.7.4
^ permalink raw reply related
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