* Re: [PATCH net-next 2/8] ipv6: a bit more typesafety
From: YOSHIFUJI Hideaki @ 2014-09-21 2:13 UTC (permalink / raw)
To: Hannes Frederic Sowa, netdev
Cc: eric.dumazet, vyasevich, nicolas.dichtel, kafai,
YOSHIFUJI Hideaki
In-Reply-To: <fab79c190ca6d2b728a2bacb30c234c0f054e76b.1411249633.git.hannes@stressinduktion.org>
Hannes Frederic Sowa wrote:
> Convert bool to bool and fib6_walker_t.state to the already existing enum.
Do you mean "boolean" variable (or member/type) to bool?
--yoshfuji
^ permalink raw reply
* Re: [PATCH net-next 1/8] ipv6: support for fib6_clean_* to update fn_sernum
From: YOSHIFUJI Hideaki @ 2014-09-21 2:07 UTC (permalink / raw)
To: Hannes Frederic Sowa, netdev
Cc: eric.dumazet, vyasevich, nicolas.dichtel, kafai,
YOSHIFUJI Hideaki
In-Reply-To: <d63a1ee6a3dee0d2a08f38e1e8a11a120b6ce3f5.1411249633.git.hannes@stressinduktion.org>
Hi,
Hannes Frederic Sowa wrote:
> @@ -71,7 +72,8 @@ static DEFINE_RWLOCK(fib6_walker_lock);
> #define FWS_INIT FWS_L
> #endif
>
> -static void fib6_prune_clones(struct net *net, struct fib6_node *fn);
> +static void fib6_prune_clones(struct net *net, struct fib6_node *fn,
> + u32 sernum);
> static struct rt6_info *fib6_find_prefix(struct net *net, struct fib6_node *fn);
> static struct fib6_node *fib6_repair_tree(struct net *net, struct fib6_node *fn);
> static int fib6_walk(struct fib6_walker_t *w);
> @@ -84,7 +86,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w);
> * result of redirects, path MTU changes, etc.
> */
>
> -static __u32 rt_sernum;
> +static u32 rt_sernum;
>
> static void fib6_gc_timer_cb(unsigned long arg);
>
I don't think you do really convert __u32 to u32
in this series.
--yoshfuji
^ permalink raw reply
* Re: [PATCH net-next 5/8] ipv6: new function fib6_flush_trees and use it instead of bumping removed rt6_genid
From: YOSHIFUJI Hideaki @ 2014-09-21 2:21 UTC (permalink / raw)
To: Hannes Frederic Sowa, netdev
Cc: eric.dumazet, vyasevich, nicolas.dichtel, kafai
In-Reply-To: <c0a1543fe7608640f2dd1f37f8fe5978f30536d1.1411249633.git.hannes@stressinduktion.org>
Hannes Frederic Sowa wrote:
> fib6_flush_trees is still a very costly operation but now is only called
> by xfrm code when a policy changes or ipv6 addresses are added/removed.
>
> fib6_flush_tree must walk all ipv6 routing tables and modify fn_sernum,
> so all sockets relookup their dst_entries. Use a NULL callback, so we
> only walk the nodes without looking at the rt6_infos.
>
> Cc: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Vlad Yasevich <vyasevich@gmail.com>
> Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
> Cc: Martin Lau <kafai@fb.com>
> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> ---
> include/net/net_namespace.h | 14 +++-----------
> include/net/netns/ipv6.h | 1 -
> net/ipv6/addrconf_core.c | 6 ++++++
> net/ipv6/af_inet6.c | 1 -
> net/ipv6/ip6_fib.c | 21 +++++++++++++++++----
> net/ipv6/route.c | 4 ----
> 6 files changed, 26 insertions(+), 21 deletions(-)
>
> diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
> index 361d260..61aad36 100644
> --- a/include/net/net_namespace.h
> +++ b/include/net/net_namespace.h
> @@ -353,21 +353,13 @@ static inline void rt_genid_bump_ipv4(struct net *net)
> }
>
> #if IS_ENABLED(CONFIG_IPV6)
> -static inline int rt_genid_ipv6(struct net *net)
> -{
> - return atomic_read(&net->ipv6.rt_genid);
> -}
> -
> +extern void (*__fib6_flush_trees)(struct net *);
> static inline void rt_genid_bump_ipv6(struct net *net)
> {
> - atomic_inc(&net->ipv6.rt_genid);
> + if (__fib6_flush_trees)
> + __fib6_flush_trees(net);
> }
> #else
Now it does not "bump" the genid anymore. Why not to change the
function name to reflect the fact?
--yoshfuji
^ permalink raw reply
* ipv4 dead route delete notification on netdev down
From: Roopa Prabhu @ 2014-09-21 4:02 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Stephen Hemminger, nicolas.dichtel, Thomas Graf
Hi,
The kernel does not send notification for deleted dead ipv4 routes on
netdev down.
This has been brought up before and patches for the fix have been rejected.
The reason for rejection is that the routing daemons are expected to
purge their
routing tables on netdev down notifications.
http://www.spinics.net/lists/netdev/msg215161.html
http://lists.openwall.net/netdev/2013/10/17/55
This issue keeps coming back. We run into this too. Wanted to send this
email out to see if opinions have changed.
There are multiple problems:
1) inconsistency in kernel notification behavior between ipv4 and ipv6
for dead routes
2) Its not just the routing daemons, its also the userspace netlink
caches like libnl. In abcense of a direct notification,
these will have to purge the routes on link down too.
Thanks,
Roopa
^ permalink raw reply
* Re: ipv4 dead route delete notification on netdev down
From: David Miller @ 2014-09-21 4:08 UTC (permalink / raw)
To: roopa; +Cc: netdev, stephen, nicolas.dichtel, tgraf
In-Reply-To: <541E4DD4.1050609@cumulusnetworks.com>
From: Roopa Prabhu <roopa@cumulusnetworks.com>
Date: Sat, 20 Sep 2014 21:02:28 -0700
> This issue keeps coming back. We run into this too. Wanted to send
> this email out to see if opinions have changed.
My opinion has not changed.
^ permalink raw reply
* Re: [PATCH net-next 2/8] ipv6: a bit more typesafety
From: Hannes Frederic Sowa @ 2014-09-21 10:08 UTC (permalink / raw)
To: YOSHIFUJI Hideaki, netdev
Cc: eric.dumazet, vyasevich, nicolas.dichtel, kafai,
YOSHIFUJI Hideaki
In-Reply-To: <541E344E.4040500@yoshifuji.org>
On Sun, Sep 21, 2014, at 04:13, YOSHIFUJI Hideaki wrote:
> Hannes Frederic Sowa wrote:
> > Convert bool to bool and fib6_walker_t.state to the already existing enum.
>
> Do you mean "boolean" variable (or member/type) to bool?
I meant to say I convert the prune member/argument type to bool. Will
fix it up.
Thanks,
Hannes
^ permalink raw reply
* Re: [PATCH net-next 1/8] ipv6: support for fib6_clean_* to update fn_sernum
From: Hannes Frederic Sowa @ 2014-09-21 10:09 UTC (permalink / raw)
To: YOSHIFUJI Hideaki, netdev
Cc: eric.dumazet, vyasevich, nicolas.dichtel, kafai,
YOSHIFUJI Hideaki
In-Reply-To: <541E32E9.2040409@yoshifuji.org>
On Sun, Sep 21, 2014, at 04:07, YOSHIFUJI Hideaki wrote:
> Hi,
>
> Hannes Frederic Sowa wrote:
>
> > @@ -71,7 +72,8 @@ static DEFINE_RWLOCK(fib6_walker_lock);
> > #define FWS_INIT FWS_L
> > #endif
> >
> > -static void fib6_prune_clones(struct net *net, struct fib6_node *fn);
> > +static void fib6_prune_clones(struct net *net, struct fib6_node *fn,
> > + u32 sernum);
> > static struct rt6_info *fib6_find_prefix(struct net *net, struct fib6_node *fn);
> > static struct fib6_node *fib6_repair_tree(struct net *net, struct fib6_node *fn);
> > static int fib6_walk(struct fib6_walker_t *w);
> > @@ -84,7 +86,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w);
> > * result of redirects, path MTU changes, etc.
> > */
> >
> > -static __u32 rt_sernum;
> > +static u32 rt_sernum;
> >
> > static void fib6_gc_timer_cb(unsigned long arg);
> >
>
> I don't think you do really convert __u32 to u32
> in this series.
You're right there are some places left. I'll fix that up and resend. In
the end I'll convert the fn_sernum over to int to align with atomic_t.
Thanks,
Hannes
^ permalink raw reply
* Re: [PATCH net-next 5/8] ipv6: new function fib6_flush_trees and use it instead of bumping removed rt6_genid
From: Hannes Frederic Sowa @ 2014-09-21 10:11 UTC (permalink / raw)
To: YOSHIFUJI Hideaki, netdev; +Cc: eric.dumazet, vyasevich, nicolas.dichtel, kafai
In-Reply-To: <541E3640.6020907@yoshifuji.org>
On Sun, Sep 21, 2014, at 04:21, YOSHIFUJI Hideaki wrote:
> Now it does not "bump" the genid anymore. Why not to change the
> function name to reflect the fact?
I first named the new function fib6_flush_trees but then realized this
function itself gets called by rt_genid_bump_all, so I left the name.
I'll append a patch to generalize those names, because it should not
matter for ipv4 or ipv6 how it is ensured that sockets drop their cached
dst_entries.
Thanks,
Hannes
^ permalink raw reply
* Re: [PATCH net-next v4 2/2] bonding: Simplify the xmit function for modes that use xmit_hash
From: Nikolay Aleksandrov @ 2014-09-21 11:07 UTC (permalink / raw)
To: Mahesh Bandewar
Cc: Jay Vosburgh, Veaceslav Falico, Andy Gospodarek, David Miller,
netdev, Eric Dumazet, Maciej Zenczykowski
In-Reply-To: <CAF2d9jg7HDJt-2imR1P4ks5dvSo_91AVkN4aJL2Xix2tWpESoA@mail.gmail.com>
On 09/20/2014 10:04 PM, Mahesh Bandewar wrote:
> On Sat, Sep 20, 2014 at 3:19 AM, Nikolay Aleksandrov <nikolay@redhat.com> wrote:
>> On 09/20/2014 02:09 AM, Mahesh Bandewar wrote:
>>> On Fri, Sep 19, 2014 at 4:06 AM, Nikolay Aleksandrov <nikolay@redhat.com> wrote:
>>>>
>>>> On 09/19/2014 12:00 PM, Nikolay Aleksandrov wrote:
>>>>> On 09/18/2014 11:53 PM, Mahesh Bandewar wrote:
>>>>>> Earlier change to use usable slave array for TLB mode had an additional
>>>>>> performance advantage. So extending the same logic to all other modes
>>>>>> that use xmit-hash for slave selection (viz 802.3AD, and XOR modes).
>>>>>> Also consolidating this with the earlier TLB change.
>>>>>>
>>>>>> The main idea is to build the usable slaves array in the control path
>>>>>> and use that array for slave selection during xmit operation.
>>>>>>
>>>>>> Measured performance in a setup with a bond of 4x1G NICs with 200
>>>>>> instances of netperf for the modes involved (3ad, xor, tlb)
>>>>>> cmd: netperf -t TCP_RR -H <TargetHost> -l 60 -s 5
>>>>>>
>>>>>> Mode TPS-Before TPS-After
>>>>>>
>>>>>> 802.3ad : 468,694 493,101
>>>>>> TLB (lb=0): 392,583 392,965
>>>>>> XOR : 475,696 484,517
>>>>>>
>>>>>> Signed-off-by: Mahesh Bandewar <maheshb@google.com>
>>>>>> ---
>>>>>> v1:
>>>>>> (a) If bond_update_slave_arr() fails to allocate memory, it will overwrite
>>>>>> the slave that need to be removed.
>>>>>> (b) Freeing of array will assign NULL (to handle bond->down to bond->up
>>>>>> transition gracefully.
>>>>>> (c) Change from pr_debug() to pr_err() if bond_update_slave_arr() returns
>>>>>> failure.
>>>>>> (d) XOR: bond_update_slave_arr() will consider mii-mon, arp-mon cases and
>>>>>> will populate the array even if these parameters are not used.
>>>>>> (e) 3AD: Should handle the ad_agg_selection_logic correctly.
>>>>>> v2:
>>>>>> (a) Removed rcu_read_{un}lock() calls from array manipulation code.
>>>>>> (b) Slave link-events now refresh array for all these modes.
>>>>>> (c) Moved free-array call from bond_close() to bond_uninit().
>>>>>> v3:
>>>>>> (a) Fixed null pointer dereference.
>>>>>> (b) Removed bond->lock lockdep dependency.
>>>>>> v4:
>>>>>> (a) Made to changes to comply with Nikolay's locking changes
>>>>>> (b) Added a work-queue to refresh slave-array when RTNL is not held
>>>>>> (c) Array refresh happens ONLY with RTNL now.
>>>>>> (d) alloc changed from GFP_ATOMIC to GFP_KERNEL
>>>>>>
>>>> <<<snip>>>
>>>>>> @@ -3839,6 +4003,7 @@ static void bond_uninit(struct net_device *bond_dev)
>>>>>> struct bonding *bond = netdev_priv(bond_dev);
>>>>>> struct list_head *iter;
>>>>>> struct slave *slave;
>>>>>> + struct bond_up_slave *arr;
>>>>>>
>>>>>> bond_netpoll_cleanup(bond_dev);
>>>>>>
>>>>>> @@ -3847,6 +4012,12 @@ static void bond_uninit(struct net_device *bond_dev)
>>>>>> __bond_release_one(bond_dev, slave->dev, true);
>>>>>> netdev_info(bond_dev, "Released all slaves\n");
>>>>>>
>>>> Sorry but I just spotted a major problem, bond_3ad_unbind_slave() (called
>>>> from __bond_release_one) calls ad_agg_selection_logic() which can re-arm
>>>> the slave_arr work after it's supposed to be stopped here (i.e. the bond
>>>> device has been closed so all works should've been stopped) so we might
>>>> leak memory and access freed memory after all since it'll keep
>>>> re-scheduling itself until it can acquire rtnl which is after the bond
>>>> device has been destroyed.
>>>>
>>> This should not be a problem. ndo_close (bond_close()) is called
>>> before ndo_uninit(bond_uninit()), so the work-queues get cancelled
>>> there so if rearm tries to schedule some work after queue gets
>>> cancelled, it can't do much and wont harm anything.
>>> Hence there wont be any arrays built once it's free-ed completely and
>>> therefore no memory leak. I addded some instrumentation and tried
>>> following sequence -
>>>
>>> # modprobe bonding mode=4
>>> # ip link set bond0 up
>>> # [Add ip]
>>> # [Add default route]
>>> # ifenslave bond0 eth0 eth1 eth2 eth3
>>> ....
>>> [Run some backgound traffic. I used netperf.]
>>>
>>> # ip link bond0 down
>>>
>>> I did not see anything "bad" happening. Did your trial produced
>>> something unpleasant?
>>>
>> The test you've done is irrelevant to the situation that I described
>> because ndo_uninit() is called when the device is being destroyed. Moreover
>> the case I told you about would require to have an active aggregator and an
>> inactive one (i.e. so agg selection logic will get called), here is the result:
>> [ 428.916586] bond1 (unregistering): Removing an active aggregator
>> [ 428.916589] Failed to build slave-array.
>> [ 428.916849] bond1 (unregistering): Releasing active interface eth1
>> [ 428.920342] bond1 (unregistering): Released all slaves
>> [ 428.923043] Failed to update slave array from WT
>> [ 428.924098] Failed to update slave array from WT
>> [ 428.925125] Failed to update slave array from WT
>> [ 428.926120] Failed to update slave array from WT
>> [ 428.927096] Failed to update slave array from WT
>> [ 428.928101] Failed to update slave array from WT
>> [ 428.929120] Failed to update slave array from WT
>> [ 428.930086] BUG: unable to handle kernel NULL pointer dereference at
>> (null)
>> [ 428.930644] IP: [<ffffffff810aa37b>] __queue_work+0x7b/0x350
>> [ 428.930946] PGD 0
>> [ 428.931053] Oops: 0000 [#1] SMP
>> [ 428.931053] Modules linked in: sfc ptp pps_core mdio i2c_algo_bit mtd
>> bonding(O) snd_hda_codec_generic joydev crct10dif_pclmul crc32_pclmul
>> i2c_piix4 ppdev crc32c_intel ghash_clmulni_intel parport_pc snd_hda_intel
>> snd_hda_controller snd_hda_codec snd_hwdep snd_pcm snd_timer 9pnet_virtio
>> snd 9pnet pcspkr parport i2ccore serio_raw virtio_console virtio_balloon
>> pvpanic soundcore virtio_blk virtio_net ata_generic floppy pata_acpi
>> virtio_pci virtio_ring virtio
>> [ 428.935022] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O
>> 3.17.0-rc4+ #30
>> [ 428.935022] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
>> [ 428.935022] task: ffffffff81c1b460 ti: ffffffff81c00000 task.ti:
>> ffffffff81c00000
>> [ 428.935022] RIP: 0010:[<ffffffff810aa37b>] [<ffffffff810aa37b>]
>> __queue_work+0x7b/0x350
>> [ 428.935022] RSP: 0018:ffff88005f003e28 EFLAGS: 00010086
>> [ 428.935022] RAX: ffff88005c05c800 RBX: 0000000000000000 RCX:
>> 0000000000000000
>> [ 428.935022] RDX: 0000000000000000 RSI: 0000000000000006 RDI:
>> ffff88005a4fbd58
>> [ 428.935022] RBP: ffff88005f003e60 R08: 0000000000000046 R09:
>> ffffffff8225abc2
>> [ 428.935022] R10: 0000000000000004 R11: 0000000000000005 R12:
>> ffff88005a4fbd58
>> [ 428.935022] R13: 0000000000000008 R14: ffff88004b211800 R15:
>> 00000000000102f0
>> [ 428.935022] FS: 0000000000000000(0000) GS:ffff88005f000000(0000)
>> knlGS:0000000000000000
>> [ 428.935022] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> [ 428.935022] CR2: 0000000000000000 CR3: 000000004abde000 CR4:
>> 00000000000406f0
>> [ 428.935022] Stack:
>> [ 428.935022] 0a19522f72b12222 0000000081c1b460 ffffffff8225abc0
>> ffff88005a4fbd78
>> [ 428.935022] 0000000000000101 ffffffff810aa650 ffff88005a4fbd58
>> ffff88005f003e70
>> [ 428.935022] ffffffff810aa668 ffff88005f003ea8 ffffffff810f3536
>> ffffffff8225abc0
>> [ 428.935022] Call Trace:
>> [ 428.935022] <IRQ>
>> [ 428.935022]
>> [ 428.935022] [<ffffffff810aa650>] ? __queue_work+0x350/0x350
>> [ 428.935022] [<ffffffff810aa668>] delayed_work_timer_fn+0x18/0x20
>> [ 428.935022] [<ffffffff810f3536>] call_timer_fn+0x36/0x120
>> [ 428.935022] [<ffffffff810aa650>] ? __queue_work+0x350/0x350
>> [ 428.935022] [<ffffffff810f38f5>] run_timer_softirq+0x1a5/0x320
>> [ 428.935022] [<ffffffff81096dc5>] __do_softirq+0xf5/0x2b0
>> [ 428.935022] [<ffffffff810971fd>] irq_exit+0xbd/0xd0
>> [ 428.935022] [<ffffffff8173b715>] smp_apic_timer_interrupt+0x45/0x60
>> [ 428.935022] [<ffffffff8173981d>] apic_timer_interrupt+0x6d/0x80
>> [ 428.935022] <EOI>
>> [ 428.935022]
>> [ 428.935022] [<ffffffff810581c6>] ? native_safe_halt+0x6/0x10
>> [ 428.935022] [<ffffffff8101f36f>] default_idle+0x1f/0xe0
>> [ 428.935022] [<ffffffff8101fd8f>] arch_cpu_idle+0xf/0x20
>> [ 428.935022] [<ffffffff810d25dd>] cpu_startup_entry+0x38d/0x3c0
>> [ 428.935022] [<ffffffff81722927>] rest_init+0x87/0x90
>> [ 428.935022] [<ffffffff81d3510e>] start_kernel+0x482/0x4a3
>> [ 428.935022] [<ffffffff81d34a85>] ? set_init_arg+0x53/0x53
>> [ 428.935022] [<ffffffff81d34120>] ? early_idt_handlers+0x120/0x120
>> [ 428.935022] [<ffffffff81d345ee>] x86_64_start_reservations+0x2a/0x2c
>> [ 428.935022] [<ffffffff81d3473d>] x86_64_start_kernel+0x14d/0x170
>> [ 428.935022] Code: 84 bb 01 00 00 a8 02 0f 85 eb 00 00 00 48 63 45 d4 49
>> 8b 9e 08 01 00 00 48 03 1c c5 60 fa d0 81 4c 89 e7 e8 18 f5 ff ff 48 85 c0
>> <48> 8b 3b 0f 84 7c 01 00 00 48 39 c7 0f 84 73 01 00 00 48 89 c7
>> [ 428.935022] RIP [<ffffffff810aa37b>] __queue_work+0x7b/0x350
>> [ 428.935022] RSP <ffff88005f003e28>
>> [ 428.935022] CR2: 0000000000000000
>>
>> This is because it keeps trying to re-schedule even though the interface's
>> memory has been freed.
>>
> Hmm, how do we handle this?
>
This is tricky and what concerns me more is that people might make this
mistake again in the future. It's easy to unknowingly make use of a
function that re-schedules this from the wrong place.
What I just noticed is that for all 3ad cases you could pull the scheduling
in the bond_3ad_state_machine_handler() function.
The call sites of ad_agg_selection_logic() are:
- 3ad unbind slave (no need to schedule here as __bond_release_one would
rebuild the array anyhow)
- bond_3ad_state_machine_handler() <- here's where the schedule should
happen as this gets stopped first when the bond is closed and can't get
restarted unless it's opened again.
- ad_port_selection_logic() <- this is called from
bond_3ad_state_machine_handler() only, so this case will be handled as well.
The other 2 functions that you convert - ad_enable/disable_collecting are
used only from ad_mux_machine() which is only called in
bond_3ad_state_machine_handler().
So basically you can pull all rebuild schedules in their common caller -
bond_3ad_state_machine_handler(), just make a flag to note that a rebuild
is needed probably something similar to should_notify_rtnl.
This way you can remove the scheduling from the various 3ad functions that
may get used and will have it only in 1 place which is more easily controlled.
Of course, the alternative would be once again - convert
bond_3ad_state_machine_handler() to RTNL, but that has its own set of problems.
>> While testing this I spotted another issue as well - Failed to build
>> slave_arr message has been printed too many times because you print it in
>> 3ad mode when there's no active aggregator (bond_3ad_get_active_agg_info
>> check in bond_update_slave_arr) which leads to re-scheduling which also
>> lead to a deadlock.
>>
> I think this can be corrected with pr_ratelimited() call.
>
IMO it shouldn't print anything if it couldn't rebuild the array due to
missing active aggregator as that's not an error condition. It should
though probably clean out the slave array because transmission shouldn't be
possible without an active aggregator in 3ad.
^ permalink raw reply
* Re: action stats broken?
From: Jamal Hadi Salim @ 2014-09-21 12:33 UTC (permalink / raw)
To: John Fastabend; +Cc: john Fastabend, netdev@vger.kernel.org, Cong Wang
In-Reply-To: <541D9B78.8070505@gmail.com>
On 09/20/14 11:21, John Fastabend wrote:
> On 09/20/2014 06:17 AM, Jamal Hadi Salim wrote:
>
> I'm looking into it which classifier? A basic u32 classifier attached
> to the ingress qdisc seems to work. If your using u32 any hash tables,
> or 'filter change' commands before this?
>
Nothing that exciting.
> # tc actions add action drop index 4
>
> # tc filter add dev p3p1 parent ffff:0 protocol ip prio 100 \
> u32 match ip src 16.0.0.2 action gact index 4
>
> #tc -s actions ls action gact
>
> action order 0: gact action drop
> random type none pass val 0
> index 4 ref 2 bind 1 installed 142 sec used 0 sec
> Action statistics:
> Sent 840 bytes 10 pkt (dropped 10, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
>
Indeed that looks sane. What kernel version + iproute2?
I have time this morning - I will chase it to double check in case
my environment is messed up.
cheers,
jamal
>> cheers,
>> jamal
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
^ permalink raw reply
* [PATCH v2 net-next 0/9] ipv6: fib6: socket dst_entry improvments and cleanups
From: Hannes Frederic Sowa @ 2014-09-21 14:11 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, hideaki, vyasevich, nicolas.dichtel, kafai
Eric Dumazet noticed that rt6_nodes wich are neither RTF_NONEXTHOP nor
RTF_GATEWAY but DST_HOST ones cause major routing lookup churn because
their rt6_genid is never renewed, thus ip6_dst_check always considers
them outdated. This is a major problem, because these kind of routes
are normally used to in input handling.
Thus it does not make sense to use rt6i_genid anymore. This series
removes it.
The address deletion path is already covered and does not depend on
rt6i_genid. When we add a new address, we update the fn_sernums while
traversing the tree.
Because inet6_connect_socket depend on dst_check returning NULL also
for source address invalidation, we currently have to walk the whole
tree and update the fn_sernums manually when an address gets deleted.
This is a fairly expensive operation we currenlty have to do for
address deletion and xfrm policy changes. We currently do that for
interface mtu changes already.
I dropped the patch for updating the fn_sernum on deletion as it
showed some side effects with /proc/net/ipv6_route and we currently
don't need it. I stashed it away.
Thanks to Eric Dumazet for noticing the problem with rt6i_genid!
v2 (addressed YOSHIFUJI Hideaki's feedback, thanks!):
* fixed changelog in patch #2
* added patch to rename rt_genid_bump_ipv6 etc.
Regarding the __u32 to u32 conversion, I didn't see anything
problematic or left over, if I missed something there I am happy to
fix it up in a next version.
Hannes Frederic Sowa (9):
ipv6: support for fib6_clean_* to update fn_sernum
ipv6: a bit more typesafety
ipv6: only generate one new serial number during fib6_add()
ipv6: if no function for cleaner is specified only visit fib6_nodes
ipv6: new function fib6_flush_trees and use it instead of bumping
removed rt6_genid
ipv6: no need to bump rt_genid_ipv6 on address addition
ipv6: keep rt_sernum per namespace to reduce number of flushes
ipv6: switch rt_sernum to atomic_t and clean up types
ipv6: rename rt_genid_bump_ipv6 to rt6_inval_dst_caches
include/net/ip6_fib.h | 16 ++++++--
include/net/net_namespace.h | 22 ++++------
include/net/netns/ipv6.h | 2 +-
net/ipv6/addrconf.c | 3 +-
net/ipv6/addrconf_core.c | 6 +++
net/ipv6/af_inet6.c | 2 +-
net/ipv6/ip6_fib.c | 90 +++++++++++++++++++++++++----------------
net/ipv6/route.c | 4 --
net/xfrm/xfrm_policy.c | 2 +-
security/selinux/include/xfrm.h | 2 +-
10 files changed, 87 insertions(+), 62 deletions(-)
--
1.9.3
^ permalink raw reply
* [PATCH v2 net-next 1/9] ipv6: support for fib6_clean_* to update fn_sernum
From: Hannes Frederic Sowa @ 2014-09-21 14:11 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, hideaki, vyasevich, nicolas.dichtel, kafai
In-Reply-To: <cover.1411308211.git.hannes@stressinduktion.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: YOSHIFUJI Hideaki <hideaki@yoshifuji.org>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Cc: Martin Lau <kafai@fb.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
include/net/ip6_fib.h | 2 +-
net/ipv6/ip6_fib.c | 31 ++++++++++++++++++++-----------
2 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 9bcb220..1cdd46e 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -64,7 +64,7 @@ struct fib6_node {
__u16 fn_bit; /* bit key */
__u16 fn_flags;
- __u32 fn_sernum;
+ u32 fn_sernum;
struct rt6_info *rr_ptr;
};
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 76b7f5e..900254e 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -60,6 +60,7 @@ struct fib6_cleaner_t {
struct fib6_walker_t w;
struct net *net;
int (*func)(struct rt6_info *, void *arg);
+ u32 sernum;
void *arg;
};
@@ -71,7 +72,8 @@ static DEFINE_RWLOCK(fib6_walker_lock);
#define FWS_INIT FWS_L
#endif
-static void fib6_prune_clones(struct net *net, struct fib6_node *fn);
+static void fib6_prune_clones(struct net *net, struct fib6_node *fn,
+ u32 sernum);
static struct rt6_info *fib6_find_prefix(struct net *net, struct fib6_node *fn);
static struct fib6_node *fib6_repair_tree(struct net *net, struct fib6_node *fn);
static int fib6_walk(struct fib6_walker_t *w);
@@ -84,7 +86,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w);
* result of redirects, path MTU changes, etc.
*/
-static __u32 rt_sernum;
+static u32 rt_sernum;
static void fib6_gc_timer_cb(unsigned long arg);
@@ -107,11 +109,13 @@ static inline void fib6_walker_unlink(struct fib6_walker_t *w)
static __inline__ u32 fib6_new_sernum(void)
{
u32 n = ++rt_sernum;
- if ((__s32)n <= 0)
+ if ((s32)n <= 0)
rt_sernum = n = 1;
return n;
}
+#define FIB6_NO_SERNUM_CHANGE (0U)
+
/*
* Auxiliary address test functions for the radix tree.
*
@@ -430,7 +434,7 @@ static struct fib6_node *fib6_add_1(struct fib6_node *root,
struct rt6key *key;
int bit;
__be32 dir = 0;
- __u32 sernum = fib6_new_sernum();
+ u32 sernum = fib6_new_sernum();
RT6_TRACE("fib6_add_1\n");
@@ -940,7 +944,8 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
if (!err) {
fib6_start_gc(info->nl_net, rt);
if (!(rt->rt6i_flags & RTF_CACHE))
- fib6_prune_clones(info->nl_net, pn);
+ fib6_prune_clones(info->nl_net, pn,
+ FIB6_NO_SERNUM_CHANGE);
}
out:
@@ -1374,7 +1379,7 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info)
pn = pn->parent;
}
#endif
- fib6_prune_clones(info->nl_net, pn);
+ fib6_prune_clones(info->nl_net, pn, FIB6_NO_SERNUM_CHANGE);
}
/*
@@ -1521,6 +1526,9 @@ static int fib6_clean_node(struct fib6_walker_t *w)
.nl_net = c->net,
};
+ if (c->sernum != FIB6_NO_SERNUM_CHANGE)
+ c->w.node->fn_sernum = c->sernum;
+
for (rt = w->leaf; rt; rt = rt->dst.rt6_next) {
res = c->func(rt, c->arg);
if (res < 0) {
@@ -1554,7 +1562,7 @@ static int fib6_clean_node(struct fib6_walker_t *w)
static void fib6_clean_tree(struct net *net, struct fib6_node *root,
int (*func)(struct rt6_info *, void *arg),
- int prune, void *arg)
+ int prune, u32 sernum, void *arg)
{
struct fib6_cleaner_t c;
@@ -1564,6 +1572,7 @@ static void fib6_clean_tree(struct net *net, struct fib6_node *root,
c.w.count = 0;
c.w.skip = 0;
c.func = func;
+ c.sernum = sernum;
c.arg = arg;
c.net = net;
@@ -1583,7 +1592,7 @@ void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
hlist_for_each_entry_rcu(table, head, tb6_hlist) {
write_lock_bh(&table->tb6_lock);
fib6_clean_tree(net, &table->tb6_root,
- func, 0, arg);
+ func, 0, FIB6_NO_SERNUM_CHANGE, arg);
write_unlock_bh(&table->tb6_lock);
}
}
@@ -1600,9 +1609,9 @@ static int fib6_prune_clone(struct rt6_info *rt, void *arg)
return 0;
}
-static void fib6_prune_clones(struct net *net, struct fib6_node *fn)
+static void fib6_prune_clones(struct net *net, struct fib6_node *fn, u32 sernum)
{
- fib6_clean_tree(net, fn, fib6_prune_clone, 1, NULL);
+ fib6_clean_tree(net, fn, fib6_prune_clone, 1, sernum, NULL);
}
/*
@@ -1811,7 +1820,7 @@ struct ipv6_route_iter {
struct fib6_walker_t w;
loff_t skip;
struct fib6_table *tbl;
- __u32 sernum;
+ u32 sernum;
};
static int ipv6_route_seq_show(struct seq_file *seq, void *v)
--
1.9.3
^ permalink raw reply related
* [PATCH v2 net-next 2/9] ipv6: a bit more typesafety
From: Hannes Frederic Sowa @ 2014-09-21 14:11 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, hideaki, vyasevich, nicolas.dichtel, kafai
In-Reply-To: <cover.1411308211.git.hannes@stressinduktion.org>
Convert prune argument/struct member to bool and fib6_walker_t.state to
the already existing enum.
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: YOSHIFUJI Hideaki <hideaki@yoshifuji.org>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Cc: Martin Lau <kafai@fb.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
include/net/ip6_fib.h | 14 ++++++++++++--
net/ipv6/ip6_fib.c | 17 ++++-------------
2 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 1cdd46e..a09e554 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -205,12 +205,22 @@ static inline void ip6_rt_put(struct rt6_info *rt)
dst_release(&rt->dst);
}
+enum fib_walk_state_t {
+#ifdef CONFIG_IPV6_SUBTREES
+ FWS_S,
+#endif
+ FWS_L,
+ FWS_R,
+ FWS_C,
+ FWS_U
+};
+
struct fib6_walker_t {
struct list_head lh;
struct fib6_node *root, *node;
struct rt6_info *leaf;
- unsigned char state;
- unsigned char prune;
+ enum fib_walk_state_t state;
+ bool prune;
unsigned int skip;
unsigned int count;
int (*func)(struct fib6_walker_t *);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 900254e..67599d8 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -46,16 +46,6 @@
static struct kmem_cache *fib6_node_kmem __read_mostly;
-enum fib_walk_state_t {
-#ifdef CONFIG_IPV6_SUBTREES
- FWS_S,
-#endif
- FWS_L,
- FWS_R,
- FWS_C,
- FWS_U
-};
-
struct fib6_cleaner_t {
struct fib6_walker_t w;
struct net *net;
@@ -1562,7 +1552,7 @@ static int fib6_clean_node(struct fib6_walker_t *w)
static void fib6_clean_tree(struct net *net, struct fib6_node *root,
int (*func)(struct rt6_info *, void *arg),
- int prune, u32 sernum, void *arg)
+ bool prune, u32 sernum, void *arg)
{
struct fib6_cleaner_t c;
@@ -1592,7 +1582,8 @@ void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
hlist_for_each_entry_rcu(table, head, tb6_hlist) {
write_lock_bh(&table->tb6_lock);
fib6_clean_tree(net, &table->tb6_root,
- func, 0, FIB6_NO_SERNUM_CHANGE, arg);
+ func, false, FIB6_NO_SERNUM_CHANGE,
+ arg);
write_unlock_bh(&table->tb6_lock);
}
}
@@ -1611,7 +1602,7 @@ static int fib6_prune_clone(struct rt6_info *rt, void *arg)
static void fib6_prune_clones(struct net *net, struct fib6_node *fn, u32 sernum)
{
- fib6_clean_tree(net, fn, fib6_prune_clone, 1, sernum, NULL);
+ fib6_clean_tree(net, fn, fib6_prune_clone, true, sernum, NULL);
}
/*
--
1.9.3
^ permalink raw reply related
* [PATCH v2 net-next 3/9] ipv6: only generate one new serial number during fib6_add()
From: Hannes Frederic Sowa @ 2014-09-21 14:11 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, hideaki, vyasevich, nicolas.dichtel, kafai
In-Reply-To: <cover.1411308211.git.hannes@stressinduktion.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: YOSHIFUJI Hideaki <hideaki@yoshifuji.org>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Cc: Martin Lau <kafai@fb.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
net/ipv6/ip6_fib.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 67599d8..d8f0af4 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -415,16 +415,15 @@ out:
*/
static struct fib6_node *fib6_add_1(struct fib6_node *root,
- struct in6_addr *addr, int plen,
- int offset, int allow_create,
- int replace_required)
+ struct in6_addr *addr, int plen,
+ int offset, int allow_create,
+ int replace_required, u32 sernum)
{
struct fib6_node *fn, *in, *ln;
struct fib6_node *pn = NULL;
struct rt6key *key;
int bit;
__be32 dir = 0;
- u32 sernum = fib6_new_sernum();
RT6_TRACE("fib6_add_1\n");
@@ -842,6 +841,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
int err = -ENOMEM;
int allow_create = 1;
int replace_required = 0;
+ u32 sernum = fib6_new_sernum();
if (info->nlh) {
if (!(info->nlh->nlmsg_flags & NLM_F_CREATE))
@@ -854,7 +854,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
fn = fib6_add_1(root, &rt->rt6i_dst.addr, rt->rt6i_dst.plen,
offsetof(struct rt6_info, rt6i_dst), allow_create,
- replace_required);
+ replace_required, sernum);
if (IS_ERR(fn)) {
err = PTR_ERR(fn);
fn = NULL;
@@ -888,14 +888,14 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
sfn->leaf = info->nl_net->ipv6.ip6_null_entry;
atomic_inc(&info->nl_net->ipv6.ip6_null_entry->rt6i_ref);
sfn->fn_flags = RTN_ROOT;
- sfn->fn_sernum = fib6_new_sernum();
+ sfn->fn_sernum = sernum;
/* Now add the first leaf node to new subtree */
sn = fib6_add_1(sfn, &rt->rt6i_src.addr,
rt->rt6i_src.plen,
offsetof(struct rt6_info, rt6i_src),
- allow_create, replace_required);
+ allow_create, replace_required, sernum);
if (IS_ERR(sn)) {
/* If it is failed, discard just allocated
@@ -914,7 +914,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr,
rt->rt6i_src.plen,
offsetof(struct rt6_info, rt6i_src),
- allow_create, replace_required);
+ allow_create, replace_required, sernum);
if (IS_ERR(sn)) {
err = PTR_ERR(sn);
@@ -934,8 +934,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
if (!err) {
fib6_start_gc(info->nl_net, rt);
if (!(rt->rt6i_flags & RTF_CACHE))
- fib6_prune_clones(info->nl_net, pn,
- FIB6_NO_SERNUM_CHANGE);
+ fib6_prune_clones(info->nl_net, pn, sernum);
}
out:
--
1.9.3
^ permalink raw reply related
* [PATCH v2 net-next 4/9] ipv6: if no function for cleaner is specified only visit fib6_nodes
From: Hannes Frederic Sowa @ 2014-09-21 14:11 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, hideaki, vyasevich, nicolas.dichtel, kafai
In-Reply-To: <cover.1411308211.git.hannes@stressinduktion.org>
We now allow NULL rt6_info walker functions to we only visit nodes.
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: YOSHIFUJI Hideaki <hideaki@yoshifuji.org>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Cc: Martin Lau <kafai@fb.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
net/ipv6/ip6_fib.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index d8f0af4..4dfadd4 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1518,6 +1518,12 @@ static int fib6_clean_node(struct fib6_walker_t *w)
if (c->sernum != FIB6_NO_SERNUM_CHANGE)
c->w.node->fn_sernum = c->sernum;
+ if (!c->func) {
+ WARN_ON_ONCE(c->sernum == FIB6_NO_SERNUM_CHANGE);
+ w->leaf = NULL;
+ return 0;
+ }
+
for (rt = w->leaf; rt; rt = rt->dst.rt6_next) {
res = c->func(rt, c->arg);
if (res < 0) {
--
1.9.3
^ permalink raw reply related
* [PATCH v2 net-next 5/9] ipv6: new function fib6_flush_trees and use it instead of bumping removed rt6_genid
From: Hannes Frederic Sowa @ 2014-09-21 14:11 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, hideaki, vyasevich, nicolas.dichtel, kafai
In-Reply-To: <cover.1411308211.git.hannes@stressinduktion.org>
fib6_flush_trees is still a very costly operation but now is only called
by xfrm code when a policy changes or ipv6 addresses are added/removed.
fib6_flush_tree must walk all ipv6 routing tables and modify fn_sernum,
so all sockets relookup their dst_entries. Use a NULL callback, so we
only walk the nodes without looking at the rt6_infos.
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: YOSHIFUJI Hideaki <hideaki@yoshifuji.org>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Cc: Martin Lau <kafai@fb.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
include/net/net_namespace.h | 14 +++-----------
include/net/netns/ipv6.h | 1 -
net/ipv6/addrconf_core.c | 6 ++++++
net/ipv6/af_inet6.c | 1 -
net/ipv6/ip6_fib.c | 21 +++++++++++++++++----
net/ipv6/route.c | 4 ----
6 files changed, 26 insertions(+), 21 deletions(-)
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 361d260..61aad36 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -353,21 +353,13 @@ static inline void rt_genid_bump_ipv4(struct net *net)
}
#if IS_ENABLED(CONFIG_IPV6)
-static inline int rt_genid_ipv6(struct net *net)
-{
- return atomic_read(&net->ipv6.rt_genid);
-}
-
+extern void (*__fib6_flush_trees)(struct net *);
static inline void rt_genid_bump_ipv6(struct net *net)
{
- atomic_inc(&net->ipv6.rt_genid);
+ if (__fib6_flush_trees)
+ __fib6_flush_trees(net);
}
#else
-static inline int rt_genid_ipv6(struct net *net)
-{
- return 0;
-}
-
static inline void rt_genid_bump_ipv6(struct net *net)
{
}
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index eade27a..3291ba6 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -76,7 +76,6 @@ struct netns_ipv6 {
#endif
#endif
atomic_t dev_addr_genid;
- atomic_t rt_genid;
};
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c
index e696045..8b2d99a 100644
--- a/net/ipv6/addrconf_core.c
+++ b/net/ipv6/addrconf_core.c
@@ -10,6 +10,12 @@
#define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16)
+/* if ipv6 module registers this function is used by xfrm to force
+ * all sockets to relookup their nodes - this is fairly expensive
+ */
+void (*__fib6_flush_trees)(struct net *);
+EXPORT_SYMBOL(__fib6_flush_trees);
+
static inline unsigned int ipv6_addr_scope2type(unsigned int scope)
{
switch (scope) {
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e4865a3..2189d2d 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -766,7 +766,6 @@ static int __net_init inet6_net_init(struct net *net)
net->ipv6.sysctl.icmpv6_time = 1*HZ;
net->ipv6.sysctl.flowlabel_consistency = 1;
net->ipv6.sysctl.auto_flowlabels = 0;
- atomic_set(&net->ipv6.rt_genid, 0);
err = ipv6_init_mibs(net);
if (err)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 4dfadd4..0a97216 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1574,8 +1574,9 @@ static void fib6_clean_tree(struct net *net, struct fib6_node *root,
fib6_walk(&c.w);
}
-void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
- void *arg)
+void __fib6_clean_all(struct net *net,
+ int (*func)(struct rt6_info *, void *arg),
+ u32 sernum, void *arg)
{
struct fib6_table *table;
struct hlist_head *head;
@@ -1587,14 +1588,24 @@ void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
hlist_for_each_entry_rcu(table, head, tb6_hlist) {
write_lock_bh(&table->tb6_lock);
fib6_clean_tree(net, &table->tb6_root,
- func, false, FIB6_NO_SERNUM_CHANGE,
- arg);
+ func, false, sernum, arg);
write_unlock_bh(&table->tb6_lock);
}
}
rcu_read_unlock();
}
+void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
+ void *arg)
+{
+ __fib6_clean_all(net, func, FIB6_NO_SERNUM_CHANGE, arg);
+}
+
+static void fib6_flush_trees(struct net *net)
+{
+ __fib6_clean_all(net, NULL, fib6_new_sernum(), NULL);
+}
+
static int fib6_prune_clone(struct rt6_info *rt, void *arg)
{
if (rt->rt6i_flags & RTF_CACHE) {
@@ -1793,6 +1804,8 @@ int __init fib6_init(void)
NULL);
if (ret)
goto out_unregister_subsys;
+
+ __fib6_flush_trees = fib6_flush_trees;
out:
return ret;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index f74b041..a318dd89 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -314,7 +314,6 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net,
memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
- rt->rt6i_genid = rt_genid_ipv6(net);
INIT_LIST_HEAD(&rt->rt6i_siblings);
}
return rt;
@@ -1096,9 +1095,6 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
* DST_OBSOLETE_FORCE_CHK which forces validation calls down
* into this function always.
*/
- if (rt->rt6i_genid != rt_genid_ipv6(dev_net(rt->dst.dev)))
- return NULL;
-
if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie))
return NULL;
--
1.9.3
^ permalink raw reply related
* [PATCH v2 net-next 6/9] ipv6: no need to bump rt_genid_ipv6 on address addition
From: Hannes Frederic Sowa @ 2014-09-21 14:11 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, hideaki, vyasevich, nicolas.dichtel, kafai
In-Reply-To: <cover.1411308211.git.hannes@stressinduktion.org>
fn_sernum takes care that on address insertion the sockets throw away
their cached dst_entries and do a relookup.
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: YOSHIFUJI Hideaki <hideaki@yoshifuji.org>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Cc: Martin Lau <kafai@fb.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
net/ipv6/addrconf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 39d3335..a2d2626 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4781,10 +4781,11 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
if (ip6_del_rt(ifp->rt))
dst_free(&ifp->rt->dst);
+
+ rt_genid_bump_ipv6(net);
break;
}
atomic_inc(&net->ipv6.dev_addr_genid);
- rt_genid_bump_ipv6(net);
}
static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
--
1.9.3
^ permalink raw reply related
* [PATCH v2 net-next 7/9] ipv6: keep rt_sernum per namespace to reduce number of flushes
From: Hannes Frederic Sowa @ 2014-09-21 14:11 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, hideaki, vyasevich, nicolas.dichtel, kafai
In-Reply-To: <cover.1411308211.git.hannes@stressinduktion.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: YOSHIFUJI Hideaki <hideaki@yoshifuji.org>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Cc: Martin Lau <kafai@fb.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
include/net/netns/ipv6.h | 1 +
net/ipv6/af_inet6.c | 1 +
net/ipv6/ip6_fib.c | 19 ++++++++++---------
3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 3291ba6..2319949 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -76,6 +76,7 @@ struct netns_ipv6 {
#endif
#endif
atomic_t dev_addr_genid;
+ u32 rt_sernum;
};
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 2189d2d..7ff8996 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -766,6 +766,7 @@ static int __net_init inet6_net_init(struct net *net)
net->ipv6.sysctl.icmpv6_time = 1*HZ;
net->ipv6.sysctl.flowlabel_consistency = 1;
net->ipv6.sysctl.auto_flowlabels = 0;
+ net->ipv6.rt_sernum = 1;
err = ipv6_init_mibs(net);
if (err)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 0a97216..9f973e4 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -76,8 +76,6 @@ static int fib6_walk_continue(struct fib6_walker_t *w);
* result of redirects, path MTU changes, etc.
*/
-static u32 rt_sernum;
-
static void fib6_gc_timer_cb(unsigned long arg);
static LIST_HEAD(fib6_walkers);
@@ -96,12 +94,15 @@ static inline void fib6_walker_unlink(struct fib6_walker_t *w)
list_del(&w->lh);
write_unlock_bh(&fib6_walker_lock);
}
-static __inline__ u32 fib6_new_sernum(void)
+
+static u32 fib6_new_sernum(struct net *net)
{
- u32 n = ++rt_sernum;
- if ((s32)n <= 0)
- rt_sernum = n = 1;
- return n;
+ int *n = &net->ipv6.rt_sernum;
+
+ ++*n;
+ if ((s32)*n <= 0)
+ *n = 1;
+ return *n;
}
#define FIB6_NO_SERNUM_CHANGE (0U)
@@ -841,7 +842,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
int err = -ENOMEM;
int allow_create = 1;
int replace_required = 0;
- u32 sernum = fib6_new_sernum();
+ u32 sernum = fib6_new_sernum(dev_net(rt->dst.dev));
if (info->nlh) {
if (!(info->nlh->nlmsg_flags & NLM_F_CREATE))
@@ -1603,7 +1604,7 @@ void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
static void fib6_flush_trees(struct net *net)
{
- __fib6_clean_all(net, NULL, fib6_new_sernum(), NULL);
+ __fib6_clean_all(net, NULL, fib6_new_sernum(net), NULL);
}
static int fib6_prune_clone(struct rt6_info *rt, void *arg)
--
1.9.3
^ permalink raw reply related
* [PATCH v2 net-next 8/9] ipv6: switch rt_sernum to atomic_t and clean up types
From: Hannes Frederic Sowa @ 2014-09-21 14:11 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, hideaki, vyasevich, nicolas.dichtel, kafai
In-Reply-To: <cover.1411308211.git.hannes@stressinduktion.org>
Switch rt_sernum to atomic_t, make it concurrency safe (the old scheme
looked broken to me) and switch from u32 to int types for the fn_sernum.
(fib6_new_sernum only gets used with table locks, but different tables
can get mutated at the same time.)
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: YOSHIFUJI Hideaki <hideaki@yoshifuji.org>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Cc: Martin Lau <kafai@fb.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
include/net/ip6_fib.h | 2 +-
include/net/netns/ipv6.h | 2 +-
net/ipv6/af_inet6.c | 2 +-
net/ipv6/ip6_fib.c | 29 +++++++++++++++--------------
4 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index a09e554..5440f99 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -64,7 +64,7 @@ struct fib6_node {
__u16 fn_bit; /* bit key */
__u16 fn_flags;
- u32 fn_sernum;
+ int fn_sernum;
struct rt6_info *rr_ptr;
};
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 2319949..7dee21b 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -76,7 +76,7 @@ struct netns_ipv6 {
#endif
#endif
atomic_t dev_addr_genid;
- u32 rt_sernum;
+ atomic_t rt_sernum;
};
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 7ff8996..6cde9b4 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -766,7 +766,7 @@ static int __net_init inet6_net_init(struct net *net)
net->ipv6.sysctl.icmpv6_time = 1*HZ;
net->ipv6.sysctl.flowlabel_consistency = 1;
net->ipv6.sysctl.auto_flowlabels = 0;
- net->ipv6.rt_sernum = 1;
+ atomic_set(&net->ipv6.rt_sernum, 1);
err = ipv6_init_mibs(net);
if (err)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 9f973e4..ae87d0c 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -50,7 +50,7 @@ struct fib6_cleaner_t {
struct fib6_walker_t w;
struct net *net;
int (*func)(struct rt6_info *, void *arg);
- u32 sernum;
+ int sernum;
void *arg;
};
@@ -63,7 +63,7 @@ static DEFINE_RWLOCK(fib6_walker_lock);
#endif
static void fib6_prune_clones(struct net *net, struct fib6_node *fn,
- u32 sernum);
+ int sernum);
static struct rt6_info *fib6_find_prefix(struct net *net, struct fib6_node *fn);
static struct fib6_node *fib6_repair_tree(struct net *net, struct fib6_node *fn);
static int fib6_walk(struct fib6_walker_t *w);
@@ -97,15 +97,16 @@ static inline void fib6_walker_unlink(struct fib6_walker_t *w)
static u32 fib6_new_sernum(struct net *net)
{
- int *n = &net->ipv6.rt_sernum;
+ int old, new;
- ++*n;
- if ((s32)*n <= 0)
- *n = 1;
- return *n;
+ do {
+ old = atomic_read(&net->ipv6.rt_sernum);
+ new = old < INT_MAX ? old + 1 : 1;
+ } while (atomic_cmpxchg(&net->ipv6.rt_sernum, old, new) != old);
+ return new;
}
-#define FIB6_NO_SERNUM_CHANGE (0U)
+#define FIB6_NO_SERNUM_CHANGE (0)
/*
* Auxiliary address test functions for the radix tree.
@@ -418,7 +419,7 @@ out:
static struct fib6_node *fib6_add_1(struct fib6_node *root,
struct in6_addr *addr, int plen,
int offset, int allow_create,
- int replace_required, u32 sernum)
+ int replace_required, int sernum)
{
struct fib6_node *fn, *in, *ln;
struct fib6_node *pn = NULL;
@@ -842,7 +843,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
int err = -ENOMEM;
int allow_create = 1;
int replace_required = 0;
- u32 sernum = fib6_new_sernum(dev_net(rt->dst.dev));
+ int sernum = fib6_new_sernum(dev_net(rt->dst.dev));
if (info->nlh) {
if (!(info->nlh->nlmsg_flags & NLM_F_CREATE))
@@ -1558,7 +1559,7 @@ static int fib6_clean_node(struct fib6_walker_t *w)
static void fib6_clean_tree(struct net *net, struct fib6_node *root,
int (*func)(struct rt6_info *, void *arg),
- bool prune, u32 sernum, void *arg)
+ bool prune, int sernum, void *arg)
{
struct fib6_cleaner_t c;
@@ -1577,7 +1578,7 @@ static void fib6_clean_tree(struct net *net, struct fib6_node *root,
void __fib6_clean_all(struct net *net,
int (*func)(struct rt6_info *, void *arg),
- u32 sernum, void *arg)
+ int sernum, void *arg)
{
struct fib6_table *table;
struct hlist_head *head;
@@ -1617,7 +1618,7 @@ static int fib6_prune_clone(struct rt6_info *rt, void *arg)
return 0;
}
-static void fib6_prune_clones(struct net *net, struct fib6_node *fn, u32 sernum)
+static void fib6_prune_clones(struct net *net, struct fib6_node *fn, int sernum)
{
fib6_clean_tree(net, fn, fib6_prune_clone, true, sernum, NULL);
}
@@ -1830,7 +1831,7 @@ struct ipv6_route_iter {
struct fib6_walker_t w;
loff_t skip;
struct fib6_table *tbl;
- u32 sernum;
+ int sernum;
};
static int ipv6_route_seq_show(struct seq_file *seq, void *v)
--
1.9.3
^ permalink raw reply related
* [PATCH v2 net-next 9/9] ipv6: rename rt_genid_bump_ipv6 to rt6_inval_dst_caches
From: Hannes Frederic Sowa @ 2014-09-21 14:11 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, hideaki, vyasevich, nicolas.dichtel, kafai
In-Reply-To: <cover.1411308211.git.hannes@stressinduktion.org>
Also rename ipv4 and ipv6 agnostic rt_genid_bump_all to
rt_inval_dst_caches as we don't care how the flushing is implemented in
the protocols.
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: YOSHIFUJI Hideaki <hideaki@yoshifuji.org>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Cc: Martin Lau <kafai@fb.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
include/net/net_namespace.h | 8 ++++----
net/ipv6/addrconf.c | 2 +-
net/xfrm/xfrm_policy.c | 2 +-
security/selinux/include/xfrm.h | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 61aad36..e73b80f 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -354,13 +354,13 @@ static inline void rt_genid_bump_ipv4(struct net *net)
#if IS_ENABLED(CONFIG_IPV6)
extern void (*__fib6_flush_trees)(struct net *);
-static inline void rt_genid_bump_ipv6(struct net *net)
+static inline void rt6_dst_inval_caches(struct net *net)
{
if (__fib6_flush_trees)
__fib6_flush_trees(net);
}
#else
-static inline void rt_genid_bump_ipv6(struct net *net)
+static inline void rt6_dst_inval_caches(struct net *net)
{
}
#endif
@@ -374,10 +374,10 @@ net_ieee802154_lowpan(struct net *net)
#endif
/* For callers who don't really care about whether it's IPv4 or IPv6 */
-static inline void rt_genid_bump_all(struct net *net)
+static inline void dst_inval_caches(struct net *net)
{
rt_genid_bump_ipv4(net);
- rt_genid_bump_ipv6(net);
+ rt6_dst_inval_caches(net);
}
static inline int fnhe_genid(struct net *net)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a2d2626..0c2aade 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4782,7 +4782,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
if (ip6_del_rt(ifp->rt))
dst_free(&ifp->rt->dst);
- rt_genid_bump_ipv6(net);
+ rt6_dst_inval_caches(net);
break;
}
atomic_inc(&net->ipv6.dev_addr_genid);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index beeed60..6d09195 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -665,7 +665,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
if (policy->family == AF_INET)
rt_genid_bump_ipv4(net);
else
- rt_genid_bump_ipv6(net);
+ rt6_dst_inval_caches(net);
if (delpol) {
xfrm_policy_requeue(delpol, policy);
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 1450f85..a1c5f97 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -49,7 +49,7 @@ static inline void selinux_xfrm_notify_policyload(void)
rtnl_lock();
for_each_net(net) {
atomic_inc(&net->xfrm.flow_cache_genid);
- rt_genid_bump_all(net);
+ dst_inval_caches(net);
}
rtnl_unlock();
}
--
1.9.3
^ permalink raw reply related
* Re: action stats broken?
From: Jamal Hadi Salim @ 2014-09-21 14:21 UTC (permalink / raw)
To: John Fastabend; +Cc: john Fastabend, netdev@vger.kernel.org, Cong Wang
In-Reply-To: <541EC5A4.9040600@mojatatu.com>
On 09/21/14 08:33, Jamal Hadi Salim wrote:
> On 09/20/14 11:21, John Fastabend wrote:
>
> I have time this morning - I will chase it to double check in case
> my environment is messed up.
>
There is something wrong for sure.
Ruling out kernel regression at this point.
It is definetely passing the stats.
Zoning on iproute2.
cheers,
jamal
^ permalink raw reply
* Re: action stats broken?
From: John Fastabend @ 2014-09-21 14:50 UTC (permalink / raw)
To: Jamal Hadi Salim; +Cc: john Fastabend, netdev@vger.kernel.org, Cong Wang
In-Reply-To: <541EDF03.1050307@mojatatu.com>
On 09/21/2014 07:21 AM, Jamal Hadi Salim wrote:
> On 09/21/14 08:33, Jamal Hadi Salim wrote:
>> On 09/20/14 11:21, John Fastabend wrote:
>>
>> I have time this morning - I will chase it to double check in case
>> my environment is messed up.
>>
>
> There is something wrong for sure.
> Ruling out kernel regression at this point.
> It is definetely passing the stats.
> Zoning on iproute2.
>
> cheers,
> jamal
>
>
I am using the latest iproute2 tip,
commit eb5d01ff38080935a1a528e4c99cab42bf93d762
Author: Stephen Hemminger <stephen@networkplumber.org>
Date: Sun Sep 14 20:40:37 2014 -0700
update dsfield file values
Update the rt_dsfield file to contain values defined in current RFC.
The days of TOS precedence are gone, even Cisco doesn't refer
to these in the documents.
I think you are right might need to bisect iproute2.
--
John Fastabend Intel Corporation
^ permalink raw reply
* Re: action stats broken?
From: Jamal Hadi Salim @ 2014-09-21 15:01 UTC (permalink / raw)
To: John Fastabend; +Cc: john Fastabend, netdev@vger.kernel.org, Cong Wang
In-Reply-To: <541EE5A9.4000207@gmail.com>
On 09/21/14 10:50, John Fastabend wrote:
> I think you are right might need to bisect iproute2.
I think i may have found it. Broken by a patch i sent
in May.
Working on a fix ..
cheers,
jamal
^ permalink raw reply
* Re: BCM4313 & brcmsmac & 3.12: only semi-working?
From: Michael Tokarev @ 2014-09-21 15:30 UTC (permalink / raw)
To: Arend van Spriel; +Cc: brcm80211-dev-list, linux-wireless, netdev
In-Reply-To: <54169D4F.2090607@broadcom.com>
15.09.2014 12:03, Arend van Spriel wrote:
> Hi Michael,
Hello again! I'm sorry for the long delay, I'll describe what happens
in a moment.
> Did you have any opportunity to create a log file. Got a question from
> someone else who got bad bcm4313 behaviour after a certain upgrade. Did
> you have the same experience?
No, I didn't have that opportunity. As I mentioned before, the second
laptop where I faced the same problem with brcm4313 wasn't mine, and I
had to return it back to its owner, so I had nothing to test things on
for quite some time.
However, a few days ago, after I was searching for a good notebook of my
own (obviously without broadcom parts ;), another friend of mine sent me
a gift - a new laptop. But this one has even worse wifi card (from linux
support PoV anyway) -- it is mediatek (formely ralink) MT7630e card.
After trying to build drivers for it for a while, I gave up, and an idea
come to me to swap this mediatek card with that broadcom 4313 card.
And surprizingly it worked - both laptops accepted the "new" cards and
I verified both works. So now the mediatek from my laptop works in
my friend's hp envy, and his brcm4313 works on my new asus.
So from now on I again have some playground for this stuff.
As I mentioned before, the card appears to work fine, at least at
first, I wasn't able to trigger any lockups/stalls before. Now
I can't trigger any stalls either, again, at least easily.
However, I found a 100%-reliable - so far - reproducer for the
initial behavour I described in the very first message in this
thread, which soon be one year old...
Namely, after resume, the card does not work. ARP works, ping and
DNS sometimes/somewhat work, inital TCP connection establisment
works, but eg http download does not work, it stalls almost
immediately.
Also during resume, I see the following kernel messages:
[ 202.607767] CPU: 2 PID: 2706 Comm: kworker/u9:0 Not tainted 3.16-amd64 #3.16.3
[ 202.607769] Hardware name: ASUSTeK COMPUTER INC. X200LA/X200LA, BIOS X200LA.204 06/16/2014
[ 202.607776] Workqueue: hci0 hci_power_on [bluetooth]
[ 202.607778] 0000000000000000 0000000000000009
[ 202.607780] Restarting tasks ... ffffffff814208bf 0000000000000000
[ 202.607783] ffffffff8104c926 ffff8800d5843d08 ffff8800d052f300 ffff8801189ea940
[ 202.607786] ffff8800d5843d00 0000000000000000 ffffffff8131c0d9 0000000000000000
[ 202.607790] Call Trace:
[ 202.607797] [<ffffffff814208bf>] ? dump_stack+0x41/0x51
[ 202.607802] [<ffffffff8104c926>] ? warn_slowpath_common+0x86/0xb0
[ 202.607807] [<ffffffff8131c0d9>] ? _request_firmware+0x439/0xa20
[ 202.607812] [<ffffffff8131c7a5>] ? request_firmware+0x35/0x60
[ 202.607816] [<ffffffffa0121780>] ? btusb_setup_bcm_patchram+0x70/0x3f0 [btusb]
[ 202.607823] [<ffffffffa0a0618d>] ? hci_dev_do_open+0x24d/0x8c0 [bluetooth]
[ 202.607829] [<ffffffff81082ade>] ? enqueue_task_fair+0x32e/0xce0
[ 202.607834] [<ffffffff8100bbb5>] ? sched_clock+0x5/0x10
[ 202.607839] [<ffffffff8107832b>] ? update_rq_clock+0x3b/0xd0
[ 202.607846] [<ffffffffa0a06818>] ? hci_power_on+0x18/0x120 [bluetooth]
[ 202.607877] [<ffffffff8106cad0>] ? kthread_freezable_should_stop+0x60/0x60
[ 202.607881] [<ffffffff81425dbc>] ? ret_from_fork+0x7c/0xb0
[ 202.607885] [<ffffffff8106cad0>] ? kthread_freezable_should_stop+0x60/0x60
[ 202.607887] ---[ end trace da2a7947839f7b1e ]---
[ 202.607891] bluetooth hci0: firmware: brcm/BCM20702A0-0a5c-21e3.hcd will not be loaded
[ 202.607894] Bluetooth: hci0: BCM: patch brcm/BCM20702A0-0a5c-21e3.hcd not found
I dunno how related these are -- bluetooth is another function of
this card.
http://www.corpit.ru/mjt/tmp/brcmsmac-4313-trace-20140921.dat.gz -- this
is a trace collected after resuming from suspend-to-disk, after the above
kernel message, and doing this:
stop network-manager
rmmod brcmsmac brcmutil
modpobe brcmsmac
trace-cmd record brcmsmac:* &
start network-manager
wget http://<ip-over-wifi>/some-random-file
<Ctrl+C>
wget did received some series of packets, with pauses in-between, but overal
the progress looks like it is stalled completely, there's almost no progress.
This is 3.16.3 kernel. Note that reloading module after resume is not
sufficient (I'll try reloading whole brcm stack).
Thank you for your interest!
/mjt
^ permalink raw reply
* [PATCH 1/1] iproute2 actions: BugFix action stats to display with -s
From: Jamal Hadi Salim @ 2014-09-21 16:29 UTC (permalink / raw)
To: stephen; +Cc: netdev, john.fastabend, Jamal Hadi Salim
From: Jamal Hadi Salim <jhs@mojatatu.com>
Was broken by commit 288abf513f5d11b98f09c6977d2019097afb7e9f
Lets not be too clever and have a separate call to print flushed
actions info.
Broken looks like:
root@moja-1:~# tc actions add action drop index 4
root@moja-1:~# tc -s actions ls action gact
action order 0: gact action drop
random type none pass val 0
index 4 ref 1 bind 0 installed 9 sec used 4 sec
The fixed version looks like:
action order 0: gact action drop
random type none pass val 0
index 4 ref 1 bind 0 installed 9 sec used 4 sec
Sent 108948 bytes 1297 pkts (dropped 1297, overlimits 0)
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
tc/m_action.c | 55 ++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 36 insertions(+), 19 deletions(-)
diff --git a/tc/m_action.c b/tc/m_action.c
index 7dbcf5b..486123e 100644
--- a/tc/m_action.c
+++ b/tc/m_action.c
@@ -249,38 +249,31 @@ static int
tc_print_one_action(FILE * f, struct rtattr *arg)
{
- struct rtattr *tb[TCA_MAX + 1];
+ struct rtattr *tb[TCA_ACT_MAX + 1];
int err = 0;
struct action_util *a = NULL;
if (arg == NULL)
return -1;
- parse_rtattr_nested(tb, TCA_MAX, arg);
- if (tb[TCA_KIND] == NULL) {
+ parse_rtattr_nested(tb, TCA_ACT_MAX, arg);
+
+ if (tb[TCA_ACT_KIND] == NULL) {
fprintf(stderr, "NULL Action!\n");
return -1;
}
- a = get_action_kind(RTA_DATA(tb[TCA_KIND]));
+ a = get_action_kind(RTA_DATA(tb[TCA_ACT_KIND]));
if (NULL == a)
return err;
- if (tab_flush) {
- __u32 *delete_count = RTA_DATA(tb[TCA_FCNT]);
- fprintf(f," %s (%d entries)\n", a->id, *delete_count);
- tab_flush = 0;
- return 0;
- }
-
- err = a->print_aopt(a,f,tb[TCA_OPTIONS]);
-
+ err = a->print_aopt(a, f, tb[TCA_ACT_OPTIONS]);
if (0 > err)
return err;
- if (show_stats && tb[TCA_STATS]) {
+ if (show_stats && tb[TCA_ACT_STATS]) {
fprintf(f, "\tAction statistics:\n");
print_tcstats2_attr(f, tb[TCA_ACT_STATS], "\t", NULL);
fprintf(f, "\n");
@@ -289,8 +282,34 @@ tc_print_one_action(FILE * f, struct rtattr *arg)
return 0;
}
+static int
+tc_print_action_flush(FILE *f, const struct rtattr *arg)
+{
+
+ struct rtattr *tb[TCA_MAX + 1];
+ int err = 0;
+ struct action_util *a = NULL;
+ __u32 *delete_count = 0;
+
+ parse_rtattr_nested(tb, TCA_MAX, arg);
+
+ if (tb[TCA_KIND] == NULL) {
+ fprintf(stderr, "NULL Action!\n");
+ return -1;
+ }
+
+ a = get_action_kind(RTA_DATA(tb[TCA_KIND]));
+ if (NULL == a)
+ return err;
+
+ delete_count = RTA_DATA(tb[TCA_FCNT]);
+ fprintf(f," %s (%d entries)\n", a->id, *delete_count);
+ tab_flush = 0;
+ return 0;
+}
+
int
-tc_print_action(FILE * f, const struct rtattr *arg)
+tc_print_action(FILE *f, const struct rtattr *arg)
{
int i;
@@ -301,10 +320,8 @@ tc_print_action(FILE * f, const struct rtattr *arg)
parse_rtattr_nested(tb, TCA_ACT_MAX_PRIO, arg);
- if (tab_flush && NULL != tb[0] && NULL == tb[1]) {
- int ret = tc_print_one_action(f, tb[0]);
- return ret;
- }
+ if (tab_flush && NULL != tb[0] && NULL == tb[1])
+ return tc_print_action_flush(f, tb[0]);
for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
if (tb[i]) {
--
1.7.9.5
^ 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