* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: David Miller @ 2012-07-26 22:53 UTC (permalink / raw)
To: alexander.duyck; +Cc: eric.dumazet, netdev
In-Reply-To: <CAKgT0Ue4mRUpEmKA7SNpTv8D7BKcxYQ65PGoOUkxB27sLuT1Rw@mail.gmail.com>
From: Alexander Duyck <alexander.duyck@gmail.com>
Date: Thu, 26 Jul 2012 15:03:39 -0700
> Here is the latest perf results with all of these patches in place.
> As you predicted your patch essentially cut the lookup overhead in
> half:
Ok good.
That patch is hard to make legitimate, I'd have to do a bit or work
before we could realize that change.
We can only combine the LOCAL and MAIN tables like that so long as
there are no overlaps in the routes covered by the two tables. We'd
also have to be sure to report the routes properly in dumps too.
I really wish we had never segregated these two tables, it's
completely pointless and hurts performance. But now we have to
accomodate this legacy.
^ permalink raw reply
* Re: [PATCH] ipv4: Fix input route performance regression.
From: David Miller @ 2012-07-26 22:53 UTC (permalink / raw)
To: eric.dumazet; +Cc: alexander.duyck, netdev
In-Reply-To: <1343340989.2626.12087.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 27 Jul 2012 00:16:29 +0200
> On Thu, 2012-07-26 at 14:14 -0700, David Miller wrote:
>> With the routing cache removal we lost the "noref" code paths on
>> input, and this can kill some routing workloads.
>>
>> Reinstate the noref path when we hit a cached route in the FIB
>> nexthops.
>>
>> With help from Eric Dumazet.
>>
>> Reported-by: Alexander Duyck <alexander.duyck@gmail.com>
>> Signed-off-by: David S. Miller <davem@davemloft.net>
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Thanks for reviewing.
^ permalink raw reply
* Re: [PATCH v2] ipv6: Early TCP socket demux
From: David Miller @ 2012-07-26 22:53 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1343341091.2626.12092.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 27 Jul 2012 00:18:11 +0200
> From: Eric Dumazet <edumazet@google.com>
>
> This is the IPv6 missing bits for infrastructure added in commit
> 41063e9dd1195 (ipv4: Early TCP socket demux.)
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied, thanks Eric.
^ permalink raw reply
* anyone know of a bug which causes dev->qdisc to be noop_qdisc for a working interface?
From: Chris Friesen @ 2012-07-26 23:30 UTC (permalink / raw)
To: netdev
Hi all,
I've been asked to help debug an issue we've had in the field where
after a month or so of uptime for a server the router it was connected
to was rebooted and one of the eth links stopped transmitting packets.
Downing and upping the link doesn't fix it. An ethtool offline selftest
doesn't fix it. Only known fix is a reboot of the server.
The server is running 2.6.14, which makes things interesting.
Luckily we had kprobes enabled and I tracked down the source code, and
I've been able to isolate the source of the problem. It seems that for
the problematic eth device (which is up and is receiving packets)
dev->qdisc is set to noop_qdisc, which ends up silently dropping all
outgoing packets on the floor. dev->qdisc_sleeping is pfifo_fast as
expected.
Does anyone have any ideas how this might have happened? Does anyone
remember a bug in this area from that long ago?
Thanks,
Chris
--
Chris Friesen
Software Designer
3500 Carling Avenue
Ottawa, Ontario K2H 8E9
www.genband.com
^ permalink raw reply
* Computations in tc_red.c
From: Dragos Ilie @ 2012-07-26 23:38 UTC (permalink / raw)
To: netdev
Hello,
I have a couple of questions about the function tc_red_eval_idle_damping() in iproute2/tc/tc_red.c. Originally, I sent the questions to Alexey Kuznetsov (for several months ago) since he is listed as the author, but did not receive a reply from him. Hence, I am directing my questions to the netdev mailing list.
My understanding is that the tc_red_eval_idle_damping() function pre-computes a set of values in the range 0-31. These values are later used by the kernel function red_calc_qavg_from_idle_time() in include/net/red.h to calculate the average queue size during idle time. The values represent the number of shifts applied to the current average queue size, which is a scaling factor of the form 2^(-n).
In tc_red_eval_idle_damping() the lW constant is defined as
double lW = -log(1.0 - 1.0/(1<<Wlog))/xmit_time
This is equivalent to -log(1.0 - W)/xmit_time, where W is scaled by a
negative power of two (Wlog is computed in tc_red_eval_ ewma()). The
constant is used to choose a time scaling factor called clog. The
condition used in choosing clog is
maxtime/1<<clog < 512
where maxtime = 31/lW. What is the reason for choosing 512 as upper bound?
My second question is about the average queue length computed in kernel function red_calc_qavg_from_idle_time() in include/net/red.h. According to the comment in that
function, the average queue length v->qavg should be adjusted as
v->qavg *= (1-W)^m
The code approximates this function by scaling v->qavg with 2^(-n),
where n was precomputed in c_red_eval_idle_damping(). I have trouble
seeing the connection between the log() function used to compute the
constant lW and the approximation used. I am hoping you can shed some
light on it.
Best regards,
Dragos Ilie
^ permalink raw reply
* [GIT] Networking
From: David Miller @ 2012-07-26 23:58 UTC (permalink / raw)
To: torvalds; +Cc: akpm, netdev, linux-kernel
1) Reinstate the no-ref optimization for input route lookups in ipv4
to fix some routing cache removal perf regressions.
2) Make TCP socket pre-demux work on ipv6 side too, from Eric Dumazet.
3) Get RX hash value from correct place in be2net driver, from
Sarveshwar Bandi.
4) Validation of FIB cached routes missing critical check, from Eric
Dumazet.
5) EEH support in mlx4 driver, from Kleber Sacilotto de Souza.
Please pull, thanks a lot!
The following changes since commit 3c4cfadef6a1665d9cd02a543782d03d3e6740c6:
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next (2012-07-24 10:01:50 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git master
for you to fetch changes up to c7109986db3c945f50ceed884a30e0fd8af3b89b:
ipv6: Early TCP socket demux (2012-07-26 15:50:39 -0700)
----------------------------------------------------------------
Alan Cox (2):
caif: fix NULL pointer check
wanmain: comparing array with NULL
Amir Vadai (1):
net/mlx4_en: Limit the RFS filter IDs to be < RPS_NO_FILTER
Andy Cress (3):
pch_gbe: fix transmit watchdog timeout
pch_gbe: add extra clean tx
pch_gbe: vlan skb len fix
Anton Blanchard (1):
be2net: Missing byteswap in be_get_fw_log_level causes oops on PowerPC
Dan Williams (1):
cdc-ncm: tag Ericsson WWAN devices (eg F5521gw) with FLAG_WWAN
David S. Miller (1):
ipv4: Fix input route performance regression.
Emil Tantilov (1):
ixgbe: fix panic while dumping packets on Tx hang with IOMMU
Eric Dumazet (3):
tcp: early_demux fixes
ipv4: rt_cache_valid must check expired routes
ipv6: Early TCP socket demux
Haiyang Zhang (2):
hyperv: Add a check for ring_size value
hyperv: Add error handling to rndis_filter_device_add()
Jiri Pirko (1):
team: init error value to 0 in team_netpoll_setup()
Kleber Sacilotto de Souza (1):
mlx4: Add support for EEH error recovery
Sarveshwar Bandi (1):
be2net: Fix to parse RSS hash from Receive completions correctly.
Wei Yang (1):
net/pch_gpe: Cannot disable ethernet autonegation
Yuval Mintz (1):
bnx2x: Correct EEE statistics gathering
frank.blaschka@de.ibm.com (3):
net: wiznet add missing HAS_IOMEM dependency
netiucv: cleanup attribute usage
qeth: repair crash in qeth_l3_vlan_rx_kill_vid()
drivers/net/caif/caif_serial.c | 3 ++
drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 4 +++
drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | 8 +++--
drivers/net/ethernet/emulex/benet/be_ethtool.c | 5 ++--
drivers/net/ethernet/emulex/benet/be_main.c | 6 ++--
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 11 +++----
drivers/net/ethernet/mellanox/mlx4/catas.c | 25 +++++++++++-----
drivers/net/ethernet/mellanox/mlx4/cmd.c | 49 +++++++++++++++++++++++++++++--
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +-
drivers/net/ethernet/mellanox/mlx4/main.c | 30 ++++++++++++++++++-
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c | 1 -
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 70 ++++++++++++++++++++++++++++++--------------
drivers/net/ethernet/wiznet/Kconfig | 1 +
drivers/net/hyperv/netvsc_drv.c | 7 ++++-
drivers/net/hyperv/rndis_filter.c | 11 +++----
drivers/net/team/team.c | 2 +-
drivers/net/usb/cdc_ncm.c | 68 +++++++++++++++++++++++++++---------------
drivers/s390/net/netiucv.c | 34 ++++-----------------
drivers/s390/net/qeth_l3_main.c | 4 +++
include/net/inet6_hashtables.h | 13 ++++----
include/net/protocol.h | 2 ++
include/net/route.h | 19 ++++++++++--
net/ipv4/arp.c | 2 +-
net/ipv4/fib_semantics.c | 4 +--
net/ipv4/ip_fragment.c | 4 +--
net/ipv4/ip_input.c | 10 +++++--
net/ipv4/route.c | 56 +++++++++++++++++------------------
net/ipv4/tcp_ipv4.c | 9 ++----
net/ipv4/xfrm4_input.c | 4 +--
net/ipv6/ip6_input.c | 13 ++++++--
net/ipv6/tcp_ipv6.c | 38 ++++++++++++++++++++++++
net/wanrouter/wanmain.c | 51 +++++++++++++++-----------------
32 files changed, 374 insertions(+), 192 deletions(-)
^ permalink raw reply
* Re: [PATCH iproute2] ss: report SK_MEMINFO_BACKLOG
From: Vijay Subramanian @ 2012-07-27 0:29 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Stephen Hemminger, netdev
In-Reply-To: <1343294420.2626.11264.camel@edumazet-glaptop>
On 26 July 2012 02:20, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> linux-3.6-rc1 supports SK_MEMINFO_BACKLOG with commit d594e987c6f54
> (sock_diag: add SK_MEMINFO_BACKLOG)
>
> ss command can display it if provided by the kernel.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Vijay Subramanian <subramanian.vijay@gmail.com>
Thanks Eric. I see now how you fixed this.
Tested-by: Vijay Subramanian <subramanian.vijay@gmail.com>
Vijay
^ permalink raw reply
* Your webmail quota has exceeded
From: webmaster @ 2012-07-27 0:26 UTC (permalink / raw)
--
Your webmail quota has exceeded the set quota which is 2GB. you are
currently running on 2.3GB.To re-activate and increase your webmail
quota please verify and update your webmail Account
In order re-activate and increase your webmail quota click the link
below.
https://docs.google.com/spreadsheet/viewform?formkey=dGNMaWg1R1BKU2lWXzB0VlpEMnJYclE6MQ
Failure to do so may result in the cancellation of your webmail
account.
Thanks, and sorry for the inconvenience
Admin/ Webmaster/ Local host
^ permalink raw reply
* Your webmail quota has exceeded
From: webmaster @ 2012-07-27 0:27 UTC (permalink / raw)
--
Your webmail quota has exceeded the set quota which is 2GB. you are
currently running on 2.3GB.To re-activate and increase your webmail
quota please verify and update your webmail Account
In order re-activate and increase your webmail quota click the link
below.
https://docs.google.com/spreadsheet/viewform?formkey=dGNMaWg1R1BKU2lWXzB0VlpEMnJYclE6MQ
Failure to do so may result in the cancellation of your webmail
account.
Thanks, and sorry for the inconvenience
Admin/ Webmaster/ Local host
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Alexander Duyck @ 2012-07-27 2:14 UTC (permalink / raw)
To: David Miller; +Cc: eric.dumazet, netdev
In-Reply-To: <20120726.155327.947597248143903676.davem@davemloft.net>
On Thu, Jul 26, 2012 at 3:53 PM, David Miller <davem@davemloft.net> wrote:
> From: Alexander Duyck <alexander.duyck@gmail.com>
> Date: Thu, 26 Jul 2012 15:03:39 -0700
>
>> Here is the latest perf results with all of these patches in place.
>> As you predicted your patch essentially cut the lookup overhead in
>> half:
>
> Ok good.
>
> That patch is hard to make legitimate, I'd have to do a bit or work
> before we could realize that change.
>
> We can only combine the LOCAL and MAIN tables like that so long as
> there are no overlaps in the routes covered by the two tables. We'd
> also have to be sure to report the routes properly in dumps too.
>
> I really wish we had never segregated these two tables, it's
> completely pointless and hurts performance. But now we have to
> accomodate this legacy.
Any idea why these look-ups are so expensive in the first place? When
I dump fib_trie it doesn't look like I have much there. I would have
thought the table would be pretty static with just 8 flows all going
to the same destination address, but it seems like I was getting hit
with cache misses for some reason.
Thanks,
Alex
^ permalink raw reply
* [RESEND][XFRM][PATCH v4] Fix unexpected SA hard expiration after setting new date
From: Fan Du @ 2012-07-27 2:39 UTC (permalink / raw)
To: davem, herbert; +Cc: netdev
Hi, Dave
It has been more than one month since my last post of this patch.
Previous posting receives no objection from you and Herbert, so I
rebase it with latest linux-3.5, then it can be easily picked up.
I'm wondering could you please take a look at this patch ?
Any comments are really welcome!
Thanks
Changelog:
v1->v2
1) use xflags instead of creating new flags(suggested by Steffen Klassert)
v2->v3
1) fix email problem, and remove cc to myself(requested by David Miller)
v3->v4
1) fix typo when clearing XFRM_SOFT_EXPIRE(thanks for David Miller)
2) fix email problem, and remove cc to myself AGAIN!!!
*Background*:
Once IPsec SAs are created between two peers, kernel setup a timer to monitor
two events: soft/hard expiration. However the timer handler use xtime to
caculate whether it's soft or hard expiration event.
normal code flow(hard expire time:100s, soft expire time:82s)
a) When new SAs created, xfrm_timer_handler is called one second
after its creation. At this point, calculate soft expire
interval(81s), setup the timer;
b) soft expire occur, rearm the timer with hard expire interval(18s)
then notify racoon2 about soft expire event. racoon2 will create
new SAs.
c) hard expire happen, notify racoon2 about it. racoon2 will delete
the old SAs.
*Scenario*:
Setting a new date before b),and after a) could result c) happens first,
As a result, old SAs is deleted before new ones are created. Normally
new SAs will be created by the next time networking traffic, but there
is a small time being when networking connection is down, this could
result in upper layer connections failed in tel comm area, thus it's
better to keep it strict in sequence.
*Workaround*:
set new time could happen:
1) before a), then SAs is updated with new time.
2) before b),and after a)
2a) When new SAs created, xfrm_timer_handler is called one second
after its creation. At this point, calculate soft expire
interval(81s), setup the timer;(set flag to mark next time should
be soft time expire)
<<---- new date comes
2b) soft expire occur, the calculation results in a hard time expire
event, but flag is set, so catch ya. Sync the addtime, and rearm
the timer with hard expire interval(18s), then notify racoon2
about soft expire event;
2c) hard expire happen, notify racoon2 about it;
so everything is in order.
3) after b), hard expire always happened anyway.
^ permalink raw reply
* [PATCH] [XFRM] Fix unexpected SA hard expiration after changing date
From: Fan Du @ 2012-07-27 2:39 UTC (permalink / raw)
To: davem, herbert; +Cc: netdev
In-Reply-To: <1343356759-24767-1-git-send-email-fdu@windriver.com>
After SA is setup, one timer is armed to detect soft/hard expiration,
however the timer handler uses xtime to do the math. This makes hard
expiration occurs first before soft expiration after setting new date
with big interval. As a result new child SA is deleted before rekeying
the new one.
Signed-off-by: Fan Du <fdu@windriver.com>
---
include/net/xfrm.h | 4 ++++
net/xfrm/xfrm_state.c | 22 ++++++++++++++++++----
2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index d9509eb..62b619e 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -213,6 +213,9 @@ struct xfrm_state {
struct xfrm_lifetime_cur curlft;
struct tasklet_hrtimer mtimer;
+ /* used to fix curlft->add_time when changing date */
+ long saved_tmo;
+
/* Last used time */
unsigned long lastused;
@@ -238,6 +241,7 @@ static inline struct net *xs_net(struct xfrm_state *x)
/* xflags - make enum if more show up */
#define XFRM_TIME_DEFER 1
+#define XFRM_SOFT_EXPIRE 2
enum {
XFRM_STATE_VOID,
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 5b228f9..fb64dc6 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -415,8 +415,18 @@ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer * me)
if (x->lft.hard_add_expires_seconds) {
long tmo = x->lft.hard_add_expires_seconds +
x->curlft.add_time - now;
- if (tmo <= 0)
- goto expired;
+ if (tmo <= 0) {
+ if (x->xflags & XFRM_SOFT_EXPIRE) {
+ /* enter hard expire without soft expire first?!
+ * setting a new date could trigger this.
+ * workarbound: fix x->curflt.add_time by below:
+ */
+ x->curlft.add_time = now - x->saved_tmo - 1;
+ tmo = x->lft.hard_add_expires_seconds - x->saved_tmo;
+
+ } else
+ goto expired;
+ }
if (tmo < next)
next = tmo;
}
@@ -433,10 +443,14 @@ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer * me)
if (x->lft.soft_add_expires_seconds) {
long tmo = x->lft.soft_add_expires_seconds +
x->curlft.add_time - now;
- if (tmo <= 0)
+ if (tmo <= 0) {
warn = 1;
- else if (tmo < next)
+ x->xflags &= ~XFRM_SOFT_EXPIRE;
+ } else if (tmo < next) {
next = tmo;
+ x->xflags |= XFRM_SOFT_EXPIRE;
+ x->saved_tmo = tmo;
+ }
}
if (x->lft.soft_use_expires_seconds) {
long tmo = x->lft.soft_use_expires_seconds +
--
1.7.1
^ permalink raw reply related
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: David Miller @ 2012-07-27 3:08 UTC (permalink / raw)
To: alexander.duyck; +Cc: eric.dumazet, netdev
In-Reply-To: <CAKgT0UdhqDQSFZkWw9w8L2qsCS+MM_DLQE+Vq0mKcYZmxhs=8Q@mail.gmail.com>
From: Alexander Duyck <alexander.duyck@gmail.com>
Date: Thu, 26 Jul 2012 19:14:55 -0700
> Any idea why these look-ups are so expensive in the first place? When
> I dump fib_trie it doesn't look like I have much there. I would have
> thought the table would be pretty static with just 8 flows all going
> to the same destination address, but it seems like I was getting hit
> with cache misses for some reason.
A lot of the overhead comes from write traffic that results from
filling in the "fib_result" structure onto the callers stack.
The return value from a fib_lookup() has far too many components. But
simplifying things is not easy.
^ permalink raw reply
* Re: [PATCH] r8169: revert "add byte queue limit support".
From: Stefan Lippers-Hollmann @ 2012-07-27 3:36 UTC (permalink / raw)
To: Francois Romieu
Cc: Eric Dumazet, David Miller, hayeswang, netdev,
Alex Villacís Lasso, Josh Boyer, Tom Herbert
In-Reply-To: <20120724053811.GA12053@electric-eye.fr.zoreil.com>
Hi
On Tuesday 24 July 2012, Francois Romieu wrote:
> Eric Dumazet <eric.dumazet@gmail.com> :
> > On Mon, 2012-07-23 at 22:55 +0200, Francois Romieu wrote:
> > > This reverts commit 036dafa28da1e2565a8529de2ae663c37b7a0060.
> [...]
> > bisection is not always the right way to qualify a problem.
>
> I know. At some point I switch from "I could search more" to "users situation
> will improve in a definite timeframe".
>
> > BQL in itself had some fixes coming _after_ commit 036dafa28da1e2565
>
> Thanks.
>
> They are in stable as of 3.4.5:
[…]
> I have obviously not directed users at them and I do not see any
> of the victims using a non -stable / -vendor or recent enough
> kernel to test this patch since the issue has been reported.
>
> They are both worth testing.
[…]
3.4.x up to and including 3.4.4 exposed the problem on these cards[1]:
r8169 0000:04:00.0: eth0: RTL8168d/8111d at 0xffffc90000c72000, 00:24:1d:72:7c:75, XID 081000c0 IRQ 44
r8169 0000:05:00.0: eth1: RTL8168d/8111d at 0xffffc90000c70000, 00:24:1d:72:7c:77, XID 081000c0 IRQ 45
while it is stable with "add byte queue limit support" reverted; 3.4.5+
was only tested with 036dafa28da1e2565a8529de2ae663c37b7a0060 reverted.
Now testing plain 3.5.0, which still includes it, has been reliable for
almost 3 days - while the issue usually triggered within one hour (3
hours at most) in 3.4.[0-4]. It might be a little too early to give a
definitive answer, but so far r8169/ 3.5.0 looks positive.
Regards
Stefan Lippers-Hollmann
[1] Message-Id: <201206290131.49150.s.L-H@gmx.de>
http://lkml.kernel.org/r/<201206290131.49150.s.L-H@gmx.de>
^ permalink raw reply
* Re: [PATCH] iproute: Add route showdump command
From: Pavel Emelyanov @ 2012-07-27 4:14 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Dan Smith, Linux Netdev List
In-Reply-To: <20120726090315.4a566a46@nehalam.linuxnetplumber.net>
On 07/26/2012 08:03 PM, Stephen Hemminger wrote:
> On Thu, 26 Jul 2012 12:53:39 +0400
> Pavel Emelyanov <xemul@parallels.com> wrote:
>
>> Some time ago the save+restore commands were added to ip route (git
>> id f4ff11e3, Add ip route save/restore). These two save the raw rtnl
>> stream into a file and restore one (reading it from stdin).
>>
>> The problem is that there's no way to get the contents of the dump
>> file in a human readable form. How about adding a command that reads
>> the rtnl stream from stdin and prints the data in a way the usual
>> "ip route list" does?
>>
>> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
>
> Being able to decode a dump is great idea.
> Are the user's smart enough not to try it out at the command prompt
> and get totally lost? Maybe another isatty() check is needed.
>
> Another solution would be to put a small header on the save file with
> a magic number that could be checked. This would mean changing save/restore/showdump
> and ideally updating the magic file in distributions.
> .
Hm... The idea with magic looks reasonable.
I will look at what can be done here, thanks!
^ permalink raw reply
* Re: [PATCH RESEND net-next V2] IB/ipoib: break linkage to neighbouring system
From: Or Gerlitz @ 2012-07-27 4:42 UTC (permalink / raw)
To: Roland Dreier; +Cc: David Miller, ogerlitz, netdev, eric.dumazet, cl, shlomop
In-Reply-To: <CAG4TOxNrywFPj_91RzkPikPoWP4hwe+2oninuF7zkrBFo6Q3Kg@mail.gmail.com>
On Wed, Jul 25, 2012 at 10:52 AM, Roland Dreier <roland@kernel.org> wrote:
> On Tue, Jul 24, 2012 at 2:00 PM, David Miller <davem@davemloft.net> wrote:
>> Looks good, Roland you got this?
> Yes, I'll read it over and pick it up, thanks.
Hi Roland,
Just to make sure, you are picking this for 3.6, correct?
I'd like to make sure that the merge of this patch through the
infiniband tree will not introduce dependancy with the review/merge of
the Ethernet IPoIB driver that runs through netdev. If this patch
lands in 3.6-rcX, Dave will eventually pick it into net-next and we're
ok, if not, things get complicated without any real reason, makes
sense?
Or.
^ permalink raw reply
* [PATCH 1/2] iproute: Add magic cookie to route dump file
From: Pavel Emelyanov @ 2012-07-27 4:55 UTC (permalink / raw)
To: Stephen Hemminger, Linux Netdev List
In order to somehow verify that a blob contains route dump a
4-bytes magic is put at the head of the data and is checked
on restore.
Magic digits are taken from Portland (OR) coordinates :) Is
there any more reliable way of generating such?
Signed-of-by: Pavel Emelyanov <xemul@parallels.com>
---
ip/iproute.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 47 insertions(+), 7 deletions(-)
diff --git a/ip/iproute.c b/ip/iproute.c
index 5cd313e..bbb3923 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -1064,6 +1064,8 @@ static int iproute_flush_cache(void)
return 0;
}
+static __u32 route_dump_magic = 0x45311224;
+
int save_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
int ret;
@@ -1072,11 +1074,6 @@ int save_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
struct rtattr *tb[RTA_MAX+1];
int host_len = -1;
- if (isatty(STDOUT_FILENO)) {
- fprintf(stderr, "Not sending binary stream to stdout\n");
- return -1;
- }
-
host_len = calc_host_len(r);
len -= NLMSG_LENGTH(sizeof(*r));
parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
@@ -1093,6 +1090,24 @@ int save_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
return ret == n->nlmsg_len ? 0 : ret;
}
+static int save_route_prep(void)
+{
+ int ret;
+
+ if (isatty(STDOUT_FILENO)) {
+ fprintf(stderr, "Not sending binary stream to stdout\n");
+ return -1;
+ }
+
+ ret = write(STDOUT_FILENO, &route_dump_magic, sizeof(route_dump_magic));
+ if (ret != sizeof(route_dump_magic)) {
+ fprintf(stderr, "Can't write magic to dump file\n");
+ return -1;
+ }
+
+ return 0;
+}
+
static int iproute_list_flush_or_save(int argc, char **argv, int action)
{
int do_ipv6 = preferred_family;
@@ -1101,9 +1116,12 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action)
unsigned int mark = 0;
rtnl_filter_t filter_fn;
- if (action == IPROUTE_SAVE)
+ if (action == IPROUTE_SAVE) {
+ if (save_route_prep())
+ return -1;
+
filter_fn = save_route;
- else
+ } else
filter_fn = print_route;
iproute_reset_filter();
@@ -1521,8 +1539,30 @@ int restore_handler(const struct sockaddr_nl *nl, struct nlmsghdr *n, void *arg)
return ret;
}
+static int route_dump_check_magic(void)
+{
+ int ret;
+ __u32 magic = 0;
+
+ if (isatty(STDIN_FILENO)) {
+ fprintf(stderr, "Can't restore route dump from a terminal\n");
+ return -1;
+ }
+
+ ret = fread(&magic, sizeof(magic), 1, stdin);
+ if (magic != route_dump_magic) {
+ fprintf(stderr, "Magic mismatch (%d elems, %x magic)\n", ret, magic);
+ return -1;
+ }
+
+ return 0;
+}
+
int iproute_restore(void)
{
+ if (route_dump_check_magic())
+ exit(-1);
+
exit(rtnl_from_file(stdin, &restore_handler, NULL));
}
--
1.5.5.6
^ permalink raw reply related
* [PATCH 2/2] iproute: Add route showdump command (v2)
From: Pavel Emelyanov @ 2012-07-27 4:57 UTC (permalink / raw)
To: Stephen Hemminger, Linux Netdev List
In-Reply-To: <50121F4D.8090606@parallels.com>
Some time ago the save+restore commands were added to ip route (git
id f4ff11e3, Add ip route save/restore). These two save the raw rtnl
stream into a file and restore one (reading it from stdin).
The problem is that there's no way to get the contents of the dump
file in a human readable form. The proposal is to add a command that
reads the rtnl stream from stdin and prints the data in a way the
usual "ip route list" does?
changes since v1:
* Take the magic at the beginning of the dump file into account
* Check for stdin (the dump is taken from) is not a tty
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
---
ip/iproute.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/ip/iproute.c b/ip/iproute.c
index bbb3923..572e2e8 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -60,6 +60,7 @@ static void usage(void)
fprintf(stderr, "Usage: ip route { list | flush } SELECTOR\n");
fprintf(stderr, " ip route save SELECTOR\n");
fprintf(stderr, " ip route restore\n");
+ fprintf(stderr, " ip route showdump\n");
fprintf(stderr, " ip route get ADDRESS [ from ADDRESS iif STRING ]\n");
fprintf(stderr, " [ oif STRING ] [ tos TOS ]\n");
fprintf(stderr, " [ mark NUMBER ]\n");
@@ -1566,6 +1567,20 @@ int iproute_restore(void)
exit(rtnl_from_file(stdin, &restore_handler, NULL));
}
+static int show_handler(const struct sockaddr_nl *nl, struct nlmsghdr *n, void *arg)
+{
+ print_route(nl, n, stdout);
+ return 0;
+}
+
+static int iproute_showdump(void)
+{
+ if (route_dump_check_magic())
+ exit(-1);
+
+ exit(rtnl_from_file(stdin, &show_handler, NULL));
+}
+
void iproute_reset_filter()
{
memset(&filter, 0, sizeof(filter));
@@ -1610,6 +1625,8 @@ int do_iproute(int argc, char **argv)
return iproute_list_flush_or_save(argc-1, argv+1, IPROUTE_SAVE);
if (matches(*argv, "restore") == 0)
return iproute_restore();
+ if (matches(*argv, "showdump") == 0)
+ return iproute_showdump();
if (matches(*argv, "help") == 0)
usage();
fprintf(stderr, "Command \"%s\" is unknown, try \"ip route help\".\n", *argv);
--
1.5.5.6
^ permalink raw reply related
* Re: [PATCH 2/2] iproute: Add route showdump command (v2)
From: Pavel Emelyanov @ 2012-07-27 5:03 UTC (permalink / raw)
To: Stephen Hemminger, Linux Netdev List
In-Reply-To: <50121FB0.6060200@parallels.com>
Stephen, I have a question regarding the save and restore in iproute tool.
As you know, the save/restore pair for routes works in a very simple and
elegant manner -- on save the raw kernel rtnl stream is just put into a
file, on restore the _very_ _same_ messages are pushed back to the kernel.
Is the same trick possible to save and restore the addresses (the ip
addr command) as well? Or the RTM_GETADDR messages cannot be just read
from and written back to the network stack in a generic case?
Thanks,
Pavel
^ permalink raw reply
* Re: [PATCH] r8169: revert "add byte queue limit support".
From: Eric Dumazet @ 2012-07-27 5:27 UTC (permalink / raw)
To: Stefan Lippers-Hollmann
Cc: Francois Romieu, David Miller, hayeswang, netdev,
Alex Villacís Lasso, Josh Boyer, Tom Herbert
In-Reply-To: <201207270536.50292.s.L-H@gmx.de>
On Fri, 2012-07-27 at 05:36 +0200, Stefan Lippers-Hollmann wrote:
> Hi
>
> On Tuesday 24 July 2012, Francois Romieu wrote:
> > Eric Dumazet <eric.dumazet@gmail.com> :
> > > On Mon, 2012-07-23 at 22:55 +0200, Francois Romieu wrote:
> > > > This reverts commit 036dafa28da1e2565a8529de2ae663c37b7a0060.
> > [...]
> > > bisection is not always the right way to qualify a problem.
> >
> > I know. At some point I switch from "I could search more" to "users situation
> > will improve in a definite timeframe".
> >
> > > BQL in itself had some fixes coming _after_ commit 036dafa28da1e2565
> >
> > Thanks.
> >
> > They are in stable as of 3.4.5:
> […]
> > I have obviously not directed users at them and I do not see any
> > of the victims using a non -stable / -vendor or recent enough
> > kernel to test this patch since the issue has been reported.
> >
> > They are both worth testing.
> […]
>
> 3.4.x up to and including 3.4.4 exposed the problem on these cards[1]:
>
> r8169 0000:04:00.0: eth0: RTL8168d/8111d at 0xffffc90000c72000, 00:24:1d:72:7c:75, XID 081000c0 IRQ 44
> r8169 0000:05:00.0: eth1: RTL8168d/8111d at 0xffffc90000c70000, 00:24:1d:72:7c:77, XID 081000c0 IRQ 45
>
> while it is stable with "add byte queue limit support" reverted; 3.4.5+
> was only tested with 036dafa28da1e2565a8529de2ae663c37b7a0060 reverted.
>
> Now testing plain 3.5.0, which still includes it, has been reliable for
> almost 3 days - while the issue usually triggered within one hour (3
> hours at most) in 3.4.[0-4]. It might be a little too early to give a
> definitive answer, but so far r8169/ 3.5.0 looks positive.
>
> Regards
> Stefan Lippers-Hollmann
>
> [1] Message-Id: <201206290131.49150.s.L-H@gmx.de>
> http://lkml.kernel.org/r/<201206290131.49150.s.L-H@gmx.de>
Thats real good news, thanks !
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: David Miller @ 2012-07-27 6:02 UTC (permalink / raw)
To: alexander.duyck; +Cc: eric.dumazet, netdev
In-Reply-To: <20120726.200846.66786272076299783.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Thu, 26 Jul 2012 20:08:46 -0700 (PDT)
> A lot of the overhead comes from write traffic that results from
> filling in the "fib_result" structure onto the callers stack.
Here's the longer analysis of how things are now.
There are several components to a route lookup result, and struct
fib_result tries to encapsulate all of this.
Another aspect is that our route tables are broken up into different
datas tructures which reference each other, in order to save space.
So the actual objects in the FIB trie are fib_alias structures, and
those point to fib_info. There is a many to one relationship between
FIB trie nodes and fib_info objects.
The idea is that many routes have the same set of nexthops, metrics,
preferred source address, etc.
So one thing we return in the fib_result is a pointer to the fib_info
and an index into the nexthop array (nh_sel). That's why we have all
of these funny accessor's FIB_RES_X(res) which essentially provide
res.fi->fib_nh[res.nh_sel].X
Therefore one area of simplification would be to just return a pointer
to the FIB nexthop, rather than the fib_info pointer and the nexthop
index. We can get to the fib_info, if we need to, via the nh_parent
pointer of the nexthop.
It seems also that the res->scope value can be cribbed from the
fib_info as well.
res->type is embedded in the fib_alias we select hanging off of the
FIB trie node. And the res->prefixlen is taken from the FIB trie
node.
res->tclassid is problematic, because it comes from the FIB rules
tables rather than the FIB trie. We used to store a full FIB rules
pointer in the fib_result, but I reduced it down to just the u32
tclassid.
This whole area, as well as the FIB trie lookup itself, is an area
ripe for a large number of small micro-optimizations that in the end
make it's overhead much more reasonable.
Another thing I haven't mentioned is that another part of FIB trie's
overhead is that it does backtracking. The shorter prefixes sit at
the top of the trie, so when it traverses down it does so until it
can't get a match, then it walks back up to the root until it does
have a match.
^ permalink raw reply
* Re: [PATCH 2/2] iproute: Add route showdump command (v2)
From: Pavel Emelyanov @ 2012-07-27 6:06 UTC (permalink / raw)
To: Stephen Hemminger, Linux Netdev List
In-Reply-To: <5012211A.4040307@parallels.com>
On 07/27/2012 09:03 AM, Pavel Emelyanov wrote:
> As you know, the save/restore pair for routes works in a very simple and
> elegant manner -- on save the raw kernel rtnl stream is just put into a
> file, on restore the _very_ _same_ messages are pushed back to the kernel.
>
> Is the same trick possible to save and restore the addresses (the ip
> addr command) as well? Or the RTM_GETADDR messages cannot be just read
> from and written back to the network stack in a generic case?
I mean something like the below, just put the RTM_GETADDR stream into a
file and push it back into the kernel as is. It worked for me in trivial
cases, but is this approach correct generically?
Log:
iproute: Add ability to save, restore and show the interfaces' addresses
Implementation is similar to the ip route {save|restore|showdump} one.
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
---
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 37deda5..6788544 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -34,6 +34,11 @@
#include "ll_map.h"
#include "ip_common.h"
+enum {
+ IPADD_LIST,
+ IPADD_FLUSH,
+ IPADD_SAVE,
+};
static struct
{
@@ -65,8 +70,9 @@ static void usage(void)
fprintf(stderr, "Usage: ip addr {add|change|replace} IFADDR dev STRING [ LIFETIME ]\n");
fprintf(stderr, " [ CONFFLAG-LIST ]\n");
fprintf(stderr, " ip addr del IFADDR dev STRING\n");
- fprintf(stderr, " ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
+ fprintf(stderr, " ip addr {show|save|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
fprintf(stderr, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n");
+ fprintf(stderr, " ip addr {showdump|restore}\n");
fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n");
fprintf(stderr, " [ broadcast ADDR ] [ anycast ADDR ]\n");
fprintf(stderr, " [ label STRING ] [ scope SCOPE-ID ]\n");
@@ -768,6 +774,99 @@ static int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
return 0;
}
+static __u32 ipadd_dump_magic = 0x47361222;
+
+static int ipadd_save_prep(void)
+{
+ int ret;
+
+ if (isatty(STDOUT_FILENO)) {
+ fprintf(stderr, "Not sending binary stream to stdout\n");
+ return -1;
+ }
+
+ ret = write(STDOUT_FILENO, &ipadd_dump_magic, sizeof(ipadd_dump_magic));
+ if (ret != sizeof(ipadd_dump_magic)) {
+ fprintf(stderr, "Can't write magic to dump file\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int ipadd_dump_check_magic(void)
+{
+ int ret;
+ __u32 magic = 0;
+
+ if (isatty(STDIN_FILENO)) {
+ fprintf(stderr, "Can't restore addr dump from a terminal\n");
+ return -1;
+ }
+
+ ret = fread(&magic, sizeof(magic), 1, stdin);
+ if (magic != ipadd_dump_magic) {
+ fprintf(stderr, "Magic mismatch (%d elems, %x magic)\n", ret, magic);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int save_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
+ void *arg)
+{
+ int ret;
+
+ ret = write(STDOUT_FILENO, n, n->nlmsg_len);
+ if ((ret > 0) && (ret != n->nlmsg_len)) {
+ fprintf(stderr, "Short write while saving nlmsg\n");
+ ret = -EIO;
+ }
+
+ return ret == n->nlmsg_len ? 0 : ret;
+}
+
+static int show_handler(const struct sockaddr_nl *nl, struct nlmsghdr *n, void *arg)
+{
+ struct ifaddrmsg *ifa = NLMSG_DATA(n);
+
+ printf("if%d:\n", ifa->ifa_index);
+ print_addrinfo(NULL, n, stdout);
+ return 0;
+}
+
+static int ipaddr_showdump(void)
+{
+ if (ipadd_dump_check_magic())
+ exit(-1);
+
+ exit(rtnl_from_file(stdin, &show_handler, NULL));
+}
+
+static int restore_handler(const struct sockaddr_nl *nl, struct nlmsghdr *n, void *arg)
+{
+ int ret;
+
+ n->nlmsg_flags |= NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
+
+ ll_init_map(&rth);
+
+ ret = rtnl_talk(&rth, n, 0, 0, n);
+ if ((ret < 0) && (errno == EEXIST))
+ ret = 0;
+
+ return ret;
+}
+
+static int ipaddr_restore(void)
+{
+ if (ipadd_dump_check_magic())
+ exit(-1);
+
+ exit(rtnl_from_file(stdin, &restore_handler, NULL));
+}
+
static void free_nlmsg_chain(struct nlmsg_chain *info)
{
struct nlmsg_list *l, *n;
@@ -902,7 +1001,7 @@ static int ipaddr_flush(void)
return 1;
}
-static int ipaddr_list_or_flush(int argc, char **argv, int flush)
+static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
{
struct nlmsg_chain linfo = { NULL, NULL};
struct nlmsg_chain ainfo = { NULL, NULL};
@@ -918,7 +1017,7 @@ static int ipaddr_list_or_flush(int argc, char **argv, int flush)
filter.group = INIT_NETDEV_GROUP;
- if (flush) {
+ if (action == IPADD_FLUSH) {
if (argc <= 0) {
fprintf(stderr, "Flush requires arguments.\n");
@@ -1005,9 +1104,26 @@ static int ipaddr_list_or_flush(int argc, char **argv, int flush)
}
}
- if (flush)
+ if (action == IPADD_FLUSH)
return ipaddr_flush();
+ if (action == IPADD_SAVE) {
+ if (ipadd_save_prep())
+ exit(1);
+
+ if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETADDR) < 0) {
+ perror("Cannot send dump request");
+ exit(1);
+ }
+
+ if (rtnl_dump_filter(&rth, save_nlmsg, stdout) < 0) {
+ fprintf(stderr, "Save terminated\n");
+ exit(1);
+ }
+
+ exit(0);
+ }
+
if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) {
perror("Cannot send dump request");
exit(1);
@@ -1055,7 +1171,7 @@ int ipaddr_list_link(int argc, char **argv)
{
preferred_family = AF_PACKET;
do_link = 1;
- return ipaddr_list_or_flush(argc, argv, 0);
+ return ipaddr_list_flush_or_save(argc, argv, IPADD_LIST);
}
void ipaddr_reset_filter(int oneline)
@@ -1271,7 +1387,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
int do_ipaddr(int argc, char **argv)
{
if (argc < 1)
- return ipaddr_list_or_flush(0, NULL, 0);
+ return ipaddr_list_flush_or_save(0, NULL, IPADD_LIST);
if (matches(*argv, "add") == 0)
return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1);
if (matches(*argv, "change") == 0 ||
@@ -1283,9 +1399,15 @@ int do_ipaddr(int argc, char **argv)
return ipaddr_modify(RTM_DELADDR, 0, argc-1, argv+1);
if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
|| matches(*argv, "lst") == 0)
- return ipaddr_list_or_flush(argc-1, argv+1, 0);
+ return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_LIST);
if (matches(*argv, "flush") == 0)
- return ipaddr_list_or_flush(argc-1, argv+1, 1);
+ return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_FLUSH);
+ if (matches(*argv, "save") == 0)
+ return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_SAVE);
+ if (matches(*argv, "showdump") == 0)
+ return ipaddr_showdump();
+ if (matches(*argv, "restore") == 0)
+ return ipaddr_restore();
if (matches(*argv, "help") == 0)
usage();
fprintf(stderr, "Command \"%s\" is unknown, try \"ip addr help\".\n", *argv);
^ permalink raw reply related
* [PATCH] tcp: Add TCP_USER_TIMEOUT negative value check
From: Hangbin Liu @ 2012-07-27 8:52 UTC (permalink / raw)
To: netdev; +Cc: hkchu, Hangbin Liu
TCP_USER_TIMEOUT is a TCP level socket option that takes an unsigned int. But
patch "tcp: Add TCP_USER_TIMEOUT socket option"(dca43c75) didn't check the negative
values. If a user assign -1 to it, the socket will set successfully and wait
for 4294967295 miliseconds. This patch add a negative value check to avoid
this issue.
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
---
net/ipv4/tcp.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 581ecf0..e7e6eea 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2681,7 +2681,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
/* Cap the max timeout in ms TCP will retry/retrans
* before giving up and aborting (ETIMEDOUT) a connection.
*/
- icsk->icsk_user_timeout = msecs_to_jiffies(val);
+ if (val < 0)
+ err = -EINVAL;
+ else
+ icsk->icsk_user_timeout = msecs_to_jiffies(val);
break;
default:
err = -ENOPROTOOPT;
--
1.7.7.6
^ permalink raw reply related
* Re: r8169, 3.5.0, does't work at all
From: Francois Romieu @ 2012-07-27 9:13 UTC (permalink / raw)
To: Denys Fedoryshchenko; +Cc: netdev
In-Reply-To: <e9e38770b95bc3664fdc642fdfb65a13@visp.net.lb>
Denys Fedoryshchenko <denys@visp.net.lb> :
[...]
> and i can search for more machines with similar cards.
Thanks.
There seems to be a more recent bios for this motherboard. Is the second
8168b an add-on or is it a dual-port DH61HO ?
You are using x86 32 with PAE and slub where I use x86 64 with slab.
I am building a x86 32 bits test configuration for a 8168b right now.
Let's see what happened during the 3.4 .. 3.5 cycle in the r8169 driver:
- You may revert 7dbb491878a2c51d372a8890fa45a8ff80358af1 ("r8169: avoid NAPI
scheduling delay.")
I can see a napi rtl8169_poll failing to schedule rtl_slow_event_work
when it is already scheduled on a different cpu, said rtl_slow_event_work
running while rtl8169_poll is delayed and rtl8169_poll stomping on the
IntrMask after rtl_slow_event_work did.
It does not tell why the device does not recover after the netdev watchdog
but it could be worth trying.
- You may revert 851e60221926a53344b4227879858bef841b0477 ("r8169: Config1 is
read-only on 8168c and later.") as well.
It changes the PMEEnable write ordering for the 8168b (RTL_GIGA_MAC_VER_17)
and a few others chipset.
--
Ueimor
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Eric Dumazet @ 2012-07-27 10:01 UTC (permalink / raw)
To: David Miller; +Cc: alexander.duyck, netdev
In-Reply-To: <20120726.230246.219188476590178857.davem@davemloft.net>
From: Eric Dumazet <edumazet@google.com>
On Thu, 2012-07-26 at 23:02 -0700, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Thu, 26 Jul 2012 20:08:46 -0700 (PDT)
>
> > A lot of the overhead comes from write traffic that results from
> > filling in the "fib_result" structure onto the callers stack.
>
> Here's the longer analysis of how things are now.
>
> There are several components to a route lookup result, and struct
> fib_result tries to encapsulate all of this.
>
> Another aspect is that our route tables are broken up into different
> datas tructures which reference each other, in order to save space.
>
> So the actual objects in the FIB trie are fib_alias structures, and
> those point to fib_info. There is a many to one relationship between
> FIB trie nodes and fib_info objects.
>
> The idea is that many routes have the same set of nexthops, metrics,
> preferred source address, etc.
>
> So one thing we return in the fib_result is a pointer to the fib_info
> and an index into the nexthop array (nh_sel). That's why we have all
> of these funny accessor's FIB_RES_X(res) which essentially provide
> res.fi->fib_nh[res.nh_sel].X
>
> Therefore one area of simplification would be to just return a pointer
> to the FIB nexthop, rather than the fib_info pointer and the nexthop
> index. We can get to the fib_info, if we need to, via the nh_parent
> pointer of the nexthop.
>
> It seems also that the res->scope value can be cribbed from the
> fib_info as well.
>
> res->type is embedded in the fib_alias we select hanging off of the
> FIB trie node. And the res->prefixlen is taken from the FIB trie
> node.
>
> res->tclassid is problematic, because it comes from the FIB rules
> tables rather than the FIB trie. We used to store a full FIB rules
> pointer in the fib_result, but I reduced it down to just the u32
> tclassid.
>
> This whole area, as well as the FIB trie lookup itself, is an area
> ripe for a large number of small micro-optimizations that in the end
> make it's overhead much more reasonable.
>
> Another thing I haven't mentioned is that another part of FIB trie's
> overhead is that it does backtracking. The shorter prefixes sit at
> the top of the trie, so when it traverses down it does so until it
> can't get a match, then it walks back up to the root until it does
> have a match.
We also have cache line misses in this code, and we shouldn't have them
at all.
Following patch helps a lot in my case.
Thanks
[PATCH] ipv4: fib: avoid false sharing
Now IP route cache is removed, we should make sure fib structures
cant share cache lines with possibly often dirtied objects.
On x86, kmalloc-96 cache can be source of such problems.
Problem spotted with perf ... -e cache-misses ... while doing
a forwarding benchmark.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/ip_fib.h | 6 ++++++
net/ipv4/fib_frontend.c | 5 +----
net/ipv4/fib_semantics.c | 15 ++++++++-------
net/ipv4/fib_trie.c | 26 +++++++++-----------------
4 files changed, 24 insertions(+), 28 deletions(-)
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index e69c3a4..5b6a9b3 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -295,6 +295,12 @@ extern void fib_select_multipath(struct fib_result *res);
/* Exported by fib_trie.c */
extern void fib_trie_init(void);
extern struct fib_table *fib_trie_table(u32 id);
+static inline void *fib_zalloc(size_t size)
+{
+ /* We want to avoid possible false sharing */
+ return kzalloc(max_t(size_t, 128, size), GFP_KERNEL);
+}
+
static inline void fib_combine_itag(u32 *itag, const struct fib_result *res)
{
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 8732cc7..a3d0285 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1089,10 +1089,7 @@ static int __net_init ip_fib_net_init(struct net *net)
int err;
size_t size = sizeof(struct hlist_head) * FIB_TABLE_HASHSZ;
- /* Avoid false sharing : Use at least a full cache line */
- size = max_t(size_t, size, L1_CACHE_BYTES);
-
- net->ipv4.fib_table_hash = kzalloc(size, GFP_KERNEL);
+ net->ipv4.fib_table_hash = fib_zalloc(size);
if (net->ipv4.fib_table_hash == NULL)
return -ENOMEM;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index da0cc2e..a9f5e87 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -651,17 +651,17 @@ static inline unsigned int fib_laddr_hashfn(__be32 val)
((__force u32)val >> 14)) & mask;
}
-static struct hlist_head *fib_info_hash_alloc(int bytes)
+static struct hlist_head *fib_info_hash_alloc(size_t bytes)
{
if (bytes <= PAGE_SIZE)
- return kzalloc(bytes, GFP_KERNEL);
+ return fib_zalloc(bytes);
else
return (struct hlist_head *)
__get_free_pages(GFP_KERNEL | __GFP_ZERO,
get_order(bytes));
}
-static void fib_info_hash_free(struct hlist_head *hash, int bytes)
+static void fib_info_hash_free(struct hlist_head *hash, size_t bytes)
{
if (!hash)
return;
@@ -678,7 +678,8 @@ static void fib_info_hash_move(struct hlist_head *new_info_hash,
{
struct hlist_head *old_info_hash, *old_laddrhash;
unsigned int old_size = fib_info_hash_size;
- unsigned int i, bytes;
+ unsigned int i;
+ size_t bytes;
spin_lock_bh(&fib_info_lock);
old_info_hash = fib_info_hash;
@@ -766,10 +767,10 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
unsigned int new_size = fib_info_hash_size << 1;
struct hlist_head *new_info_hash;
struct hlist_head *new_laddrhash;
- unsigned int bytes;
+ size_t bytes;
if (!new_size)
- new_size = 1;
+ new_size = 16;
bytes = new_size * sizeof(struct hlist_head *);
new_info_hash = fib_info_hash_alloc(bytes);
new_laddrhash = fib_info_hash_alloc(bytes);
@@ -783,7 +784,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
goto failure;
}
- fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
+ fi = fib_zalloc(sizeof(*fi) + nhs*sizeof(struct fib_nh));
if (fi == NULL)
goto failure;
if (cfg->fc_mx) {
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 18cbc15..664152c 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -379,7 +379,7 @@ static inline void free_leaf_info(struct leaf_info *leaf)
static struct tnode *tnode_alloc(size_t size)
{
if (size <= PAGE_SIZE)
- return kzalloc(size, GFP_KERNEL);
+ return fib_zalloc(size);
else
return vzalloc(size);
}
@@ -449,7 +449,7 @@ static struct leaf *leaf_new(void)
static struct leaf_info *leaf_info_new(int plen)
{
- struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL);
+ struct leaf_info *li = fib_zalloc(sizeof(struct leaf_info));
if (li) {
li->plen = plen;
li->mask_plen = ntohl(inet_make_mask(plen));
@@ -1969,32 +1969,24 @@ void __init fib_trie_init(void)
{
fn_alias_kmem = kmem_cache_create("ip_fib_alias",
sizeof(struct fib_alias),
- 0, SLAB_PANIC, NULL);
+ 0, SLAB_PANIC | SLAB_HWCACHE_ALIGN, NULL);
trie_leaf_kmem = kmem_cache_create("ip_fib_trie",
max(sizeof(struct leaf),
sizeof(struct leaf_info)),
- 0, SLAB_PANIC, NULL);
+ 0, SLAB_PANIC | SLAB_HWCACHE_ALIGN, NULL);
}
struct fib_table *fib_trie_table(u32 id)
{
struct fib_table *tb;
- struct trie *t;
-
- tb = kmalloc(sizeof(struct fib_table) + sizeof(struct trie),
- GFP_KERNEL);
- if (tb == NULL)
- return NULL;
-
- tb->tb_id = id;
- tb->tb_default = -1;
- tb->tb_num_default = 0;
-
- t = (struct trie *) tb->tb_data;
- memset(t, 0, sizeof(*t));
+ tb = fib_zalloc(sizeof(struct fib_table) + sizeof(struct trie));
+ if (tb) {
+ tb->tb_id = id;
+ tb->tb_default = -1;
+ }
return tb;
}
^ 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