* Re: Deadlock in BPF JIT functions when running upowerd?
From: Darrick J. Wong @ 2013-10-24 6:52 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Eric Dumazet, David S. Miller, netdev, linux-kernel
In-Reply-To: <1382595913.7572.40.camel@edumazet-glaptop.roam.corp.google.com>
On Wed, Oct 23, 2013 at 11:25:13PM -0700, Eric Dumazet wrote:
> On Wed, 2013-10-23 at 18:17 -0700, Darrick J. Wong wrote:
> > Hi,
> >
> > I've been observing a softlockup with 3.11.6 and 3.12-rc6. It looks like
> > there's a deadlock occurring on purge_lock in __purge_vmap_area_lazy(). In
> > short, the BPF JIT code has been changed[1] to call set_memory_r[ow]() when
> > compiling and freeing JIT bytecode memory. It seems that it's possible for
> > upowerd to be compiling some BPF program and call __purge_vmap_area_lazy, then
> > the timer interrupt comes in (due to the IPI?) and a softirq calls
> > bpf_jit_free, which also calls __purge_vmap_area_lazy.
> >
> > I'm not really sure who's at fault here--is this a BPF bug?
> >
> > [1] 314beb9bcabfd6b4542ccbced2402af2c6f6142a
> > "x86: bpf_jit_comp: secure bpf jit against spraying attacks"
> >
> > --D
> >
> > Here's what 3.11.6 spits out; the 3.12-rc6 message has the same traceback.
> >
> > [ 52.370437] BUG: soft lockup - CPU#3 stuck for 22s! [upowerd:8359]
> > [ 52.370440] Modules linked in: ipt_MASQUERADE iptable_nat nf_nat_ipv4 xt_conntrack xt_CHECKSUM iptable_mangle fuse tun microcode nfsd nfs_acl exportfs auth_rpcgss nfs lockd sunrpc af_packet xt_physdev xt_hl ip6t_rt nf_conntrack_ipv6 nf_defrag_ipv6 ipt_REJECT xt_sctp xt_limit xt_tcpudp xt_addrtype nf_conntrack_ipv4 nf_defrag_ipv4 xt_state ip6table_filter ip6_tables nf_conntrack_netbios_ns nf_conntrack_broadcast nf_nat_ftp nf_nat nf_conntrack_ftp nf_conntrack iptable_filter ip_tables x_tables sch_fq_codel bridge stp llc lpc_ich mfd_core loop bcache dm_crypt zlib_deflate libcrc32c firewire_ohci firewire_core usb_storage mpt2sas scsi_transport_sas raid_class
> > [ 52.370471] CPU: 3 PID: 8359 Comm: upowerd Not tainted 3.11.6-60-flax #1
> > [ 52.370472] Hardware name: OEM OEM/131-GT-E767, BIOS 6.00 PG 08/25/2011
> > [ 52.370474] task: ffff8806621f9700 ti: ffff88064b6a0000 task.ti: ffff88064b6a0000
> > [ 52.370475] RIP: 0010:[<ffffffff816b5a22>] [<ffffffff816b5a22>] _raw_spin_lock+0x32/0x40
> > [ 52.370480] RSP: 0018:ffff88067fc63c10 EFLAGS: 00000297
> > [ 52.370481] RAX: 0000000000000061 RBX: ffff88065a318600 RCX: 0000000000000000
> > [ 52.370483] RDX: 0000000000000062 RSI: ffff88067fc63ce0 RDI: ffffffff81ea42bc
> > [ 52.370484] RBP: ffff88067fc63c10 R08: ffffffff81cdd608 R09: 0000000000000000
> > [ 52.370485] R10: ffff88067fc6d8e0 R11: 0000000000000000 R12: ffff88067fc63b88
> > [ 52.370486] R13: ffffffff816b7a47 R14: ffff88067fc63c10 R15: ffff88067fc63cd8
> > [ 52.370487] FS: 00007f55fff297c0(0000) GS:ffff88067fc60000(0000) knlGS:0000000000000000
> > [ 52.370488] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > [ 52.370489] CR2: 00007f55fff47000 CR3: 000000065dd10000 CR4: 00000000000007e0
> > [ 52.370490] Stack:
> > [ 52.370491] ffff88067fc63cb0 ffffffff811955fd 0000000000000096 0000000000000347
> > [ 52.370494] 00000000000003c1 0000000000000001 0000000000000000 0000000000000000
> > [ 52.370496] 0000000000000033 ffff88067fc63c58 ffff88067fc63c58 0000000000000001
> > [ 52.370499] Call Trace:
> > [ 52.370500] <IRQ>
> > [ 52.370501] [<ffffffff811955fd>] __purge_vmap_area_lazy+0x12d/0x4c0
> > [ 52.370507] [<ffffffff8119612c>] vm_unmap_aliases+0x17c/0x190
> > [ 52.370512] [<ffffffff81079814>] change_page_attr_set_clr+0xb4/0x4a0
> > [ 52.370516] [<ffffffff810a927e>] ? irq_exit+0x7e/0xb0
> > [ 52.370519] [<ffffffff81048e44>] ? smp_irq_work_interrupt+0x34/0x40
> > [ 52.370522] [<ffffffff81079d8f>] set_memory_rw+0x2f/0x40
> > [ 52.370525] [<ffffffff810a0a7c>] bpf_jit_free+0x2c/0x40
> > [ 52.370528] [<ffffffff815f48aa>] sk_filter_release_rcu+0x1a/0x30
> > [ 52.370532] [<ffffffff811262d2>] rcu_process_callbacks+0x1e2/0x5b0
> > [ 52.370535] [<ffffffff810c9999>] ? enqueue_hrtimer+0x39/0xf0
> > [ 52.370537] [<ffffffff810a8f20>] __do_softirq+0xe0/0x2f0
> > [ 52.370541] [<ffffffff816b851c>] call_softirq+0x1c/0x30
> > [ 52.370543] [<ffffffff81046155>] do_softirq+0x55/0x90
> > [ 52.370545] [<ffffffff810a928e>] irq_exit+0x8e/0xb0
> > [ 52.370547] [<ffffffff816b8b0a>] smp_apic_timer_interrupt+0x4a/0x60
> > [ 52.370549] [<ffffffff816b7a47>] apic_timer_interrupt+0x67/0x70
> > [ 52.370550] <EOI>
> > [ 52.370552] [<ffffffff8106eeb4>] ? default_send_IPI_mask_allbutself_phys+0xb4/0xe0
> > [ 52.370559] [<ffffffff81188af7>] ? handle_pte_fault+0x567/0x920
> > [ 52.370561] [<ffffffff8107cf30>] ? rbt_memtype_copy_nth_element+0xc0/0xc0
> > [ 52.370563] [<ffffffff81072057>] physflat_send_IPI_allbutself+0x17/0x20
> > [ 52.370566] [<ffffffff8106a992>] native_send_call_func_ipi+0x72/0x80
> > [ 52.370568] [<ffffffff8107cf30>] ? rbt_memtype_copy_nth_element+0xc0/0xc0
> > [ 52.370570] [<ffffffff81105834>] smp_call_function_many+0x1f4/0x290
> > [ 52.370572] [<ffffffff81105a8a>] smp_call_function+0x3a/0x60
> > [ 52.370574] [<ffffffff8107cf30>] ? rbt_memtype_copy_nth_element+0xc0/0xc0
> > [ 52.370576] [<ffffffff81105b18>] on_each_cpu+0x38/0x80
> > [ 52.370578] [<ffffffff8107d59d>] flush_tlb_kernel_range+0x6d/0x70
> > [ 52.370581] [<ffffffff81195916>] __purge_vmap_area_lazy+0x446/0x4c0
> > [ 52.370584] [<ffffffff81228e85>] ? ext4_file_open+0x75/0x1b0
> > [ 52.370586] [<ffffffff8119612c>] vm_unmap_aliases+0x17c/0x190
> > [ 52.370590] [<ffffffff81079814>] change_page_attr_set_clr+0xb4/0x4a0
> > [ 52.370592] [<ffffffff81196ac2>] ? map_vm_area+0x32/0x50
> > [ 52.370595] [<ffffffff81197761>] ? __vmalloc_node_range+0x121/0x1f0
> > [ 52.370597] [<ffffffff810a08ab>] ? bpf_jit_compile+0x105b/0x1200
> > [ 52.370600] [<ffffffff81079d4f>] set_memory_ro+0x2f/0x40
> > [ 52.370602] [<ffffffff810744ca>] ? module_alloc+0x5a/0x60
> > [ 52.370604] [<ffffffff810a081c>] bpf_jit_compile+0xfcc/0x1200
> > [ 52.370607] [<ffffffff811aa75b>] ? __kmalloc+0x18b/0x1f0
> > [ 52.370610] [<ffffffff811aa606>] ? __kmalloc+0x36/0x1f0
> > [ 52.370612] [<ffffffff815f4b43>] ? sk_chk_filter+0x283/0x390
> > [ 52.370614] [<ffffffff815f4d4b>] sk_attach_filter+0xfb/0x1b0
> > [ 52.370617] [<ffffffff815d071d>] sock_setsockopt+0x4fd/0x900
> > [ 52.370620] [<ffffffff811d2342>] ? fget_light+0x92/0x100
> > [ 52.370623] [<ffffffff815cbdd6>] SyS_setsockopt+0xc6/0xd0
> > [ 52.370625] [<ffffffff816b6dc6>] system_call_fastpath+0x1a/0x1f
> > [ 52.370626] Code: 89 e5 65 48 8b 04 25 f0 b8 00 00 83 80 44 e0 ff ff 01 b8 00 01 00 00 f0 66 0f c1 07 0f b6 d4 38 c2 74 0f 66 0f 1f 44 00 00 f3 90 <0f> b6 07 38 d0 75 f7 5d c3 0f 1f 44 00 00 66 66 66 66 90 55 48
>
> Could you try latest tree, as it includes :
>
> commit d45ed4a4e33ae103053c0a53d280014e7101bb5c
> Author: Alexei Starovoitov <ast@plumgrid.com>
> Date: Fri Oct 4 00:14:06 2013 -0700
>
> net: fix unsafe set_memory_rw from softirq
This seems to fix it, thank you! :D
You can add, if you like:
Tested-by: Darrick J. Wong <darrick.wong@oracle.com>
--D
>
>
>
> Thanks !
>
>
^ permalink raw reply
* Bluetooth 6LoWPAN and routing
From: Jukka Rissanen @ 2013-10-24 6:45 UTC (permalink / raw)
To: netdev
Hi,
I have been prototyping with BT 6LoWPAN support (using this draft
http://tools.ietf.org/html/draft-ietf-6lowpan-btle-12 as a reference). I
sent first version yesterday to linux-bluetooth ml
http://thread.gmane.org/gmane.linux.bluez.kernel/39394
In this current prototype, after the BT connection is created, the code
set ups the virtual network interface, sets the IPv6 LL address for it
and creates an IPv6 route to peer (the BT 6LoWPAN connections are
point-to-point connections). I am using ip6_route_add() function from
net/ipv6/route.c file to do that. Unfortunately that function is not
exported so I GPL exported it for this prototype. Will this kind of
export accepted in upstream or should I figure out some other way to
create the desired route?
--
Cheers,
Jukka
^ permalink raw reply
* Re: [PATCH net 2/2] ipv6: ip6_dst_check needs to check for expired dst_entries
From: Eric Dumazet @ 2013-10-24 6:40 UTC (permalink / raw)
To: Hannes Frederic Sowa; +Cc: netdev, sgunderson, valentyn, yoshfuji
In-Reply-To: <20131024054824.GA15744@order.stressinduktion.org>
On Thu, 2013-10-24 at 07:48 +0200, Hannes Frederic Sowa wrote:
> On receiving a packet too big icmp error we check if our current cached
> dst_entry in the socket is still valid. This validation check did not
> care about the expiration of the (cached) route.
>
> The error path I traced down:
> The socket receives a packet too big mtu notification. It still has a
> valid dst_entry and thus issues the ip6_rt_pmtu_update on this dst_entry,
> setting RTF_EXPIRE and updates the dst.expiration value (which could
> fail because of not up-to-date expiration values, see previous patch).
>
> In some seldom cases we race with a) the ip6_fib gc or b) another routing
> lookup which would result in a recreation of the cached rt6_info from its
> parent non-cached rt6_info. While copying the rt6_info we reinitialize the
> metrics store by copying it over from the parent thus invalidating the
> just installed pmtu update (both dsts use the same key to the inetpeer
> storage). The dst_entry with the just invalidated metrics data would
> just get its RTF_EXPIRES flag cleared and would continue to stay valid
> for the socket.
>
> We should have not issued the pmtu update on the already expired dst_entry
> in the first placed. By checking the expiration on the dst entry and
> doing a relookup in case it is out of date we close the race because
> we would install a new rt6_info into the fib before we issue the pmtu
> update, thus closing this race.
>
> Not reliably updating the dst.expire value was fixed by the patch "ipv6:
> reset dst.expires value when clearing expire flag".
>
> Reported-by: Steinar H. Gunderson <sgunderson@bigfoot.com>
> Reported-by: Valentijn Sessink <valentyn@blub.net>
> Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> ---
> I would propose this patch for -stable.
>
> net/ipv6/route.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
Excellent, thanks a lot !
Reviewed-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply
* Re: [PATCH net 1/2] ipv6: reset dst.expires value when clearing expire flag
From: Eric Dumazet @ 2013-10-24 6:36 UTC (permalink / raw)
To: Hannes Frederic Sowa; +Cc: netdev, sgunderson, valentyn, yoshfuji
In-Reply-To: <20131024054816.GB5973@order.stressinduktion.org>
On Thu, 2013-10-24 at 07:48 +0200, Hannes Frederic Sowa wrote:
> On receiving a packet too big icmp error we update the expire value by
> calling rt6_update_expires. This function uses dst_set_expires which is
> implemented that it can only reduce the expiration value of the dst entry.
>
> If we insert new routing non-expiry information into the ipv6 fib where
> we already have a matching rt6_info we only clear the RTF_EXPIRES flag
> in rt6i_flags and leave the dst.expires value as is.
>
> When new mtu information arrives for that cached dst_entry we again
> call dst_set_expires. This time it won't update the dst.expire value
> because we left the dst.expire value intact from the last update. So
> dst_set_expires won't touch dst.expires.
>
> Fix this by resetting dst.expires when clearing the RTF_EXPIRE flag.
> dst_set_expires checks for a zero expiration and updates the
> dst.expires.
>
> In the past this (not updating dst.expires) was necessary because
> dst.expire was placed in a union with the dst_entry *from reference. So
> an update on the value would have caused page faults. This split happend
> in ecd9883724b78cc72ed92c98bcb1a46c764fff21 ("ipv6: fix race condition
> regarding dst->expires and dst->from").
>
Well, this patch removed the :
rt->dst.from = NULL;
from rt6_clean_expires(), right ?
Acked-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply
* Re: Deadlock in BPF JIT functions when running upowerd?
From: Eric Dumazet @ 2013-10-24 6:25 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: Eric Dumazet, David S. Miller, netdev, linux-kernel
In-Reply-To: <20131024011734.GA14083@birch.djwong.org>
On Wed, 2013-10-23 at 18:17 -0700, Darrick J. Wong wrote:
> Hi,
>
> I've been observing a softlockup with 3.11.6 and 3.12-rc6. It looks like
> there's a deadlock occurring on purge_lock in __purge_vmap_area_lazy(). In
> short, the BPF JIT code has been changed[1] to call set_memory_r[ow]() when
> compiling and freeing JIT bytecode memory. It seems that it's possible for
> upowerd to be compiling some BPF program and call __purge_vmap_area_lazy, then
> the timer interrupt comes in (due to the IPI?) and a softirq calls
> bpf_jit_free, which also calls __purge_vmap_area_lazy.
>
> I'm not really sure who's at fault here--is this a BPF bug?
>
> [1] 314beb9bcabfd6b4542ccbced2402af2c6f6142a
> "x86: bpf_jit_comp: secure bpf jit against spraying attacks"
>
> --D
>
> Here's what 3.11.6 spits out; the 3.12-rc6 message has the same traceback.
>
> [ 52.370437] BUG: soft lockup - CPU#3 stuck for 22s! [upowerd:8359]
> [ 52.370440] Modules linked in: ipt_MASQUERADE iptable_nat nf_nat_ipv4 xt_conntrack xt_CHECKSUM iptable_mangle fuse tun microcode nfsd nfs_acl exportfs auth_rpcgss nfs lockd sunrpc af_packet xt_physdev xt_hl ip6t_rt nf_conntrack_ipv6 nf_defrag_ipv6 ipt_REJECT xt_sctp xt_limit xt_tcpudp xt_addrtype nf_conntrack_ipv4 nf_defrag_ipv4 xt_state ip6table_filter ip6_tables nf_conntrack_netbios_ns nf_conntrack_broadcast nf_nat_ftp nf_nat nf_conntrack_ftp nf_conntrack iptable_filter ip_tables x_tables sch_fq_codel bridge stp llc lpc_ich mfd_core loop bcache dm_crypt zlib_deflate libcrc32c firewire_ohci firewire_core usb_storage mpt2sas scsi_transport_sas raid_class
> [ 52.370471] CPU: 3 PID: 8359 Comm: upowerd Not tainted 3.11.6-60-flax #1
> [ 52.370472] Hardware name: OEM OEM/131-GT-E767, BIOS 6.00 PG 08/25/2011
> [ 52.370474] task: ffff8806621f9700 ti: ffff88064b6a0000 task.ti: ffff88064b6a0000
> [ 52.370475] RIP: 0010:[<ffffffff816b5a22>] [<ffffffff816b5a22>] _raw_spin_lock+0x32/0x40
> [ 52.370480] RSP: 0018:ffff88067fc63c10 EFLAGS: 00000297
> [ 52.370481] RAX: 0000000000000061 RBX: ffff88065a318600 RCX: 0000000000000000
> [ 52.370483] RDX: 0000000000000062 RSI: ffff88067fc63ce0 RDI: ffffffff81ea42bc
> [ 52.370484] RBP: ffff88067fc63c10 R08: ffffffff81cdd608 R09: 0000000000000000
> [ 52.370485] R10: ffff88067fc6d8e0 R11: 0000000000000000 R12: ffff88067fc63b88
> [ 52.370486] R13: ffffffff816b7a47 R14: ffff88067fc63c10 R15: ffff88067fc63cd8
> [ 52.370487] FS: 00007f55fff297c0(0000) GS:ffff88067fc60000(0000) knlGS:0000000000000000
> [ 52.370488] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 52.370489] CR2: 00007f55fff47000 CR3: 000000065dd10000 CR4: 00000000000007e0
> [ 52.370490] Stack:
> [ 52.370491] ffff88067fc63cb0 ffffffff811955fd 0000000000000096 0000000000000347
> [ 52.370494] 00000000000003c1 0000000000000001 0000000000000000 0000000000000000
> [ 52.370496] 0000000000000033 ffff88067fc63c58 ffff88067fc63c58 0000000000000001
> [ 52.370499] Call Trace:
> [ 52.370500] <IRQ>
> [ 52.370501] [<ffffffff811955fd>] __purge_vmap_area_lazy+0x12d/0x4c0
> [ 52.370507] [<ffffffff8119612c>] vm_unmap_aliases+0x17c/0x190
> [ 52.370512] [<ffffffff81079814>] change_page_attr_set_clr+0xb4/0x4a0
> [ 52.370516] [<ffffffff810a927e>] ? irq_exit+0x7e/0xb0
> [ 52.370519] [<ffffffff81048e44>] ? smp_irq_work_interrupt+0x34/0x40
> [ 52.370522] [<ffffffff81079d8f>] set_memory_rw+0x2f/0x40
> [ 52.370525] [<ffffffff810a0a7c>] bpf_jit_free+0x2c/0x40
> [ 52.370528] [<ffffffff815f48aa>] sk_filter_release_rcu+0x1a/0x30
> [ 52.370532] [<ffffffff811262d2>] rcu_process_callbacks+0x1e2/0x5b0
> [ 52.370535] [<ffffffff810c9999>] ? enqueue_hrtimer+0x39/0xf0
> [ 52.370537] [<ffffffff810a8f20>] __do_softirq+0xe0/0x2f0
> [ 52.370541] [<ffffffff816b851c>] call_softirq+0x1c/0x30
> [ 52.370543] [<ffffffff81046155>] do_softirq+0x55/0x90
> [ 52.370545] [<ffffffff810a928e>] irq_exit+0x8e/0xb0
> [ 52.370547] [<ffffffff816b8b0a>] smp_apic_timer_interrupt+0x4a/0x60
> [ 52.370549] [<ffffffff816b7a47>] apic_timer_interrupt+0x67/0x70
> [ 52.370550] <EOI>
> [ 52.370552] [<ffffffff8106eeb4>] ? default_send_IPI_mask_allbutself_phys+0xb4/0xe0
> [ 52.370559] [<ffffffff81188af7>] ? handle_pte_fault+0x567/0x920
> [ 52.370561] [<ffffffff8107cf30>] ? rbt_memtype_copy_nth_element+0xc0/0xc0
> [ 52.370563] [<ffffffff81072057>] physflat_send_IPI_allbutself+0x17/0x20
> [ 52.370566] [<ffffffff8106a992>] native_send_call_func_ipi+0x72/0x80
> [ 52.370568] [<ffffffff8107cf30>] ? rbt_memtype_copy_nth_element+0xc0/0xc0
> [ 52.370570] [<ffffffff81105834>] smp_call_function_many+0x1f4/0x290
> [ 52.370572] [<ffffffff81105a8a>] smp_call_function+0x3a/0x60
> [ 52.370574] [<ffffffff8107cf30>] ? rbt_memtype_copy_nth_element+0xc0/0xc0
> [ 52.370576] [<ffffffff81105b18>] on_each_cpu+0x38/0x80
> [ 52.370578] [<ffffffff8107d59d>] flush_tlb_kernel_range+0x6d/0x70
> [ 52.370581] [<ffffffff81195916>] __purge_vmap_area_lazy+0x446/0x4c0
> [ 52.370584] [<ffffffff81228e85>] ? ext4_file_open+0x75/0x1b0
> [ 52.370586] [<ffffffff8119612c>] vm_unmap_aliases+0x17c/0x190
> [ 52.370590] [<ffffffff81079814>] change_page_attr_set_clr+0xb4/0x4a0
> [ 52.370592] [<ffffffff81196ac2>] ? map_vm_area+0x32/0x50
> [ 52.370595] [<ffffffff81197761>] ? __vmalloc_node_range+0x121/0x1f0
> [ 52.370597] [<ffffffff810a08ab>] ? bpf_jit_compile+0x105b/0x1200
> [ 52.370600] [<ffffffff81079d4f>] set_memory_ro+0x2f/0x40
> [ 52.370602] [<ffffffff810744ca>] ? module_alloc+0x5a/0x60
> [ 52.370604] [<ffffffff810a081c>] bpf_jit_compile+0xfcc/0x1200
> [ 52.370607] [<ffffffff811aa75b>] ? __kmalloc+0x18b/0x1f0
> [ 52.370610] [<ffffffff811aa606>] ? __kmalloc+0x36/0x1f0
> [ 52.370612] [<ffffffff815f4b43>] ? sk_chk_filter+0x283/0x390
> [ 52.370614] [<ffffffff815f4d4b>] sk_attach_filter+0xfb/0x1b0
> [ 52.370617] [<ffffffff815d071d>] sock_setsockopt+0x4fd/0x900
> [ 52.370620] [<ffffffff811d2342>] ? fget_light+0x92/0x100
> [ 52.370623] [<ffffffff815cbdd6>] SyS_setsockopt+0xc6/0xd0
> [ 52.370625] [<ffffffff816b6dc6>] system_call_fastpath+0x1a/0x1f
> [ 52.370626] Code: 89 e5 65 48 8b 04 25 f0 b8 00 00 83 80 44 e0 ff ff 01 b8 00 01 00 00 f0 66 0f c1 07 0f b6 d4 38 c2 74 0f 66 0f 1f 44 00 00 f3 90 <0f> b6 07 38 d0 75 f7 5d c3 0f 1f 44 00 00 66 66 66 66 90 55 48
Could you try latest tree, as it includes :
commit d45ed4a4e33ae103053c0a53d280014e7101bb5c
Author: Alexei Starovoitov <ast@plumgrid.com>
Date: Fri Oct 4 00:14:06 2013 -0700
net: fix unsafe set_memory_rw from softirq
Thanks !
^ permalink raw reply
* Re: 16% regression on 10G caused by TCP small queues
From: Eric Dumazet @ 2013-10-24 6:19 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, ncardwell, dave.taht, netdev
In-Reply-To: <1382595011.7572.36.camel@edumazet-glaptop.roam.corp.google.com>
On Wed, 2013-10-23 at 23:10 -0700, Eric Dumazet wrote:
> Btw what is the NIC you are using ?
Oh well I read you mail and saw ixgbe was mentioned ;)
^ permalink raw reply
* Re: [PATCH next] be2net: add support for ndo_busy_poll
From: Eric Dumazet @ 2013-10-24 6:13 UTC (permalink / raw)
To: Sathya Perla; +Cc: netdev
In-Reply-To: <1382593638-8079-1-git-send-email-sathya.perla@emulex.com>
On Thu, 2013-10-24 at 11:17 +0530, Sathya Perla wrote:
> Includes:
> - ndo_busy_poll implementation
> - Locking between napi and busy_poll
> - Fix rx_post_starvation (replenish rx-queues in out-of-mememory scenario)
> logic to accomodate busy_poll.
> if (work_done) {
> + gfp_t gfp = (polling == BUSY_POLLING) ? GFP_KERNEL : GFP_ATOMIC;
> +
> be_cq_notify(adapter, rx_cq->id, true, work_done);
>
I do not think its right.
ndo_busy_poll() is not allowed to sleep.
^ permalink raw reply
* Re: 16% regression on 10G caused by TCP small queues
From: Eric Dumazet @ 2013-10-24 6:10 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, ncardwell, dave.taht, netdev
In-Reply-To: <20131023214557.386aad1a@nehalam.linuxnetplumber.net>
On Wed, 2013-10-23 at 21:45 -0700, Stephen Hemminger wrote:
> On Wed, 23 Oct 2013 23:38:16 -0400 (EDT)
> David Miller <davem@davemloft.net> wrote:
>
> > From: Stephen Hemminger <stephen@networkplumber.org>
> > Date: Wed, 23 Oct 2013 20:09:49 -0700
> >
> > > I will check 3.12, but what about users on 3.10 which is the LTS
> > > kernel used by most distros?
>
> 3.12-rc6 gets line rate again (9.41 Gbit/sec)
>
> > The fix will be backported to -stable, relax Stephen.
>
> Sorry, thought sk_pacing_rate depended on FQ qdisc but it is other way around.
> In which case doing merge of these two was sufficient to fix the problem.
> With a minor manual fix up to tcp.h.
Btw what is the NIC you are using ?
I also had to patch mlx4 driver because it had too big coalescing
parameters, it was before TCP Small Queue dynamic sizing, but its worth
noting that for the initial ramp up (when flow sk_pacing_rate is low
because initial cwin is 10), it might make a difference
This was
commit ecfd2ce1a9d5e6376ff5c00b366345160abdbbb7
Author: Eric Dumazet <edumazet@google.com>
Date: Mon Nov 5 16:20:42 2012 +0000
mlx4: change TX coalescing defaults
mlx4 currently uses a too high tx coalescing setting, deferring
TX completion interrupts by up to 128 us.
With the recent skb_orphan() removal in commit 8112ec3b872,
performance of a single TCP flow is capped to ~4 Gbps, unless
we increase tcp_limit_output_bytes.
I suggest using 16 us instead of 128 us, allowing a finer control.
Performance of a single TCP flow is restored to previous levels,
while keeping TCP small queues fully enabled with default sysctl.
This patch is also a BQL prereq.
^ permalink raw reply
* Re: 16% regression on 10G caused by TCP small queues
From: Eric Dumazet @ 2013-10-24 6:05 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, ncardwell, dave.taht, netdev
In-Reply-To: <20131023214557.386aad1a@nehalam.linuxnetplumber.net>
On Wed, 2013-10-23 at 21:45 -0700, Stephen Hemminger wrote:
> On Wed, 23 Oct 2013 23:38:16 -0400 (EDT)
> David Miller <davem@davemloft.net> wrote:
>
> > From: Stephen Hemminger <stephen@networkplumber.org>
> > Date: Wed, 23 Oct 2013 20:09:49 -0700
> >
> > > I will check 3.12, but what about users on 3.10 which is the LTS
> > > kernel used by most distros?
>
> 3.12-rc6 gets line rate again (9.41 Gbit/sec)
>
> > The fix will be backported to -stable, relax Stephen.
>
> Sorry, thought sk_pacing_rate depended on FQ qdisc but it is other way around.
> In which case doing merge of these two was sufficient to fix the problem.
> With a minor manual fix up to tcp.h.
>
>
> commit 95bd09eb27507691520d39ee1044d6ad831c1168
> Author: Eric Dumazet <edumazet@google.com>
> Date: Tue Aug 27 05:46:32 2013 -0700
>
> tcp: TSO packets automatic sizing
>
> commit c9eeec26e32e087359160406f96e0949b3cc6f10
> Author: Eric Dumazet <edumazet@google.com>
> Date: Fri Sep 27 03:28:54 2013 -0700
>
> tcp: TSQ can use a dynamic limit
Perfect, thanks for testing Stephen !
^ permalink raw reply
* [PATCH net 2/2] ipv6: ip6_dst_check needs to check for expired dst_entries
From: Hannes Frederic Sowa @ 2013-10-24 5:48 UTC (permalink / raw)
To: netdev; +Cc: sgunderson, valentyn, yoshfuji
On receiving a packet too big icmp error we check if our current cached
dst_entry in the socket is still valid. This validation check did not
care about the expiration of the (cached) route.
The error path I traced down:
The socket receives a packet too big mtu notification. It still has a
valid dst_entry and thus issues the ip6_rt_pmtu_update on this dst_entry,
setting RTF_EXPIRE and updates the dst.expiration value (which could
fail because of not up-to-date expiration values, see previous patch).
In some seldom cases we race with a) the ip6_fib gc or b) another routing
lookup which would result in a recreation of the cached rt6_info from its
parent non-cached rt6_info. While copying the rt6_info we reinitialize the
metrics store by copying it over from the parent thus invalidating the
just installed pmtu update (both dsts use the same key to the inetpeer
storage). The dst_entry with the just invalidated metrics data would
just get its RTF_EXPIRES flag cleared and would continue to stay valid
for the socket.
We should have not issued the pmtu update on the already expired dst_entry
in the first placed. By checking the expiration on the dst entry and
doing a relookup in case it is out of date we close the race because
we would install a new rt6_info into the fib before we issue the pmtu
update, thus closing this race.
Not reliably updating the dst.expire value was fixed by the patch "ipv6:
reset dst.expires value when clearing expire flag".
Reported-by: Steinar H. Gunderson <sgunderson@bigfoot.com>
Reported-by: Valentijn Sessink <valentyn@blub.net>
Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
I would propose this patch for -stable.
net/ipv6/route.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index f54e3a1..04e17b3 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1087,10 +1087,13 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
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 dst;
+ if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie))
+ return NULL;
- return NULL;
+ if (rt6_check_expired(rt))
+ return NULL;
+
+ return dst;
}
static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 1/2] ipv6: reset dst.expires value when clearing expire flag
From: Hannes Frederic Sowa @ 2013-10-24 5:48 UTC (permalink / raw)
To: netdev; +Cc: sgunderson, valentyn, yoshfuji
On receiving a packet too big icmp error we update the expire value by
calling rt6_update_expires. This function uses dst_set_expires which is
implemented that it can only reduce the expiration value of the dst entry.
If we insert new routing non-expiry information into the ipv6 fib where
we already have a matching rt6_info we only clear the RTF_EXPIRES flag
in rt6i_flags and leave the dst.expires value as is.
When new mtu information arrives for that cached dst_entry we again
call dst_set_expires. This time it won't update the dst.expire value
because we left the dst.expire value intact from the last update. So
dst_set_expires won't touch dst.expires.
Fix this by resetting dst.expires when clearing the RTF_EXPIRE flag.
dst_set_expires checks for a zero expiration and updates the
dst.expires.
In the past this (not updating dst.expires) was necessary because
dst.expire was placed in a union with the dst_entry *from reference. So
an update on the value would have caused page faults. This split happend
in ecd9883724b78cc72ed92c98bcb1a46c764fff21 ("ipv6: fix race condition
regarding dst->expires and dst->from").
Reported-by: Steinar H. Gunderson <sgunderson@bigfoot.com>
Reported-by: Valentijn Sessink <valentyn@blub.net>
Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
I would propose this patch for -stable.
include/net/ip6_fib.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 48ec25a..5e661a9 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -165,6 +165,7 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
static inline void rt6_clean_expires(struct rt6_info *rt)
{
rt->rt6i_flags &= ~RTF_EXPIRES;
+ rt->dst.expires = 0;
}
static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires)
--
1.8.3.1
^ permalink raw reply related
* [PATCH next] be2net: add support for ndo_busy_poll
From: Sathya Perla @ 2013-10-24 5:47 UTC (permalink / raw)
To: netdev
Includes:
- ndo_busy_poll implementation
- Locking between napi and busy_poll
- Fix rx_post_starvation (replenish rx-queues in out-of-mememory scenario)
logic to accomodate busy_poll.
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 122 +++++++++++++++++++++++++++
drivers/net/ethernet/emulex/benet/be_main.c | 86 +++++++++++++++----
2 files changed, 189 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 1bce77f..b2765eb 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -199,6 +199,19 @@ struct be_eq_obj {
u16 spurious_intr;
struct napi_struct napi;
struct be_adapter *adapter;
+
+#ifdef CONFIG_NET_RX_BUSY_POLL
+#define BE_EQ_IDLE 0
+#define BE_EQ_NAPI 1 /* napi owns this EQ */
+#define BE_EQ_POLL 2 /* poll owns this EQ */
+#define BE_EQ_LOCKED (BE_EQ_NAPI | BE_EQ_POLL)
+#define BE_EQ_NAPI_YIELD 4 /* napi yielded this EQ */
+#define BE_EQ_POLL_YIELD 8 /* poll yielded this EQ */
+#define BE_EQ_YIELD (BE_EQ_NAPI_YIELD | BE_EQ_POLL_YIELD)
+#define BE_EQ_USER_PEND (BE_EQ_POLL | BE_EQ_POLL_YIELD)
+ unsigned int state;
+ spinlock_t lock; /* lock to serialize napi and busy-poll */
+#endif /* CONFIG_NET_RX_BUSY_POLL */
} ____cacheline_aligned_in_smp;
struct be_aic_obj { /* Adaptive interrupt coalescing (AIC) info */
@@ -212,6 +225,11 @@ struct be_aic_obj { /* Adaptive interrupt coalescing (AIC) info */
u64 tx_reqs_prev; /* Used to calculate TX pps */
};
+enum {
+ NAPI_POLLING,
+ BUSY_POLLING
+};
+
struct be_mcc_obj {
struct be_queue_info q;
struct be_queue_info cq;
@@ -561,6 +579,10 @@ extern const struct ethtool_ops be_ethtool_ops;
for (i = 0, eqo = &adapter->eq_obj[i]; i < adapter->num_evt_qs; \
i++, eqo++)
+#define for_all_rx_queues_on_eq(adapter, eqo, rxo, i) \
+ for (i = eqo->idx, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs;\
+ i += adapter->num_evt_qs, rxo += adapter->num_evt_qs)
+
#define is_mcc_eqo(eqo) (eqo->idx == 0)
#define mcc_eqo(adapter) (&adapter->eq_obj[0])
@@ -711,6 +733,106 @@ static inline int qnq_async_evt_rcvd(struct be_adapter *adapter)
return adapter->flags & BE_FLAGS_QNQ_ASYNC_EVT_RCVD;
}
+#ifdef CONFIG_NET_RX_BUSY_POLL
+static inline bool be_lock_napi(struct be_eq_obj *eqo)
+{
+ bool status = true;
+
+ spin_lock(&eqo->lock); /* BH is already disabled */
+ if (eqo->state & BE_EQ_LOCKED) {
+ WARN_ON(eqo->state & BE_EQ_NAPI);
+ eqo->state |= BE_EQ_NAPI_YIELD;
+ status = false;
+ } else {
+ eqo->state = BE_EQ_NAPI;
+ }
+ spin_unlock(&eqo->lock);
+ return status;
+}
+
+static inline void be_unlock_napi(struct be_eq_obj *eqo)
+{
+ spin_lock(&eqo->lock); /* BH is already disabled */
+
+ WARN_ON(eqo->state & (BE_EQ_POLL | BE_EQ_NAPI_YIELD));
+ eqo->state = BE_EQ_IDLE;
+
+ spin_unlock(&eqo->lock);
+}
+
+static inline bool be_lock_busy_poll(struct be_eq_obj *eqo)
+{
+ bool status = true;
+
+ spin_lock_bh(&eqo->lock);
+ if (eqo->state & BE_EQ_LOCKED) {
+ eqo->state |= BE_EQ_POLL_YIELD;
+ status = false;
+ } else {
+ eqo->state |= BE_EQ_POLL;
+ }
+ spin_unlock_bh(&eqo->lock);
+ return status;
+}
+
+static inline void be_unlock_busy_poll(struct be_eq_obj *eqo)
+{
+ spin_lock_bh(&eqo->lock);
+
+ WARN_ON(eqo->state & (BE_EQ_NAPI));
+ eqo->state = BE_EQ_IDLE;
+
+ spin_unlock_bh(&eqo->lock);
+}
+
+static inline void be_enable_busy_poll(struct be_eq_obj *eqo)
+{
+ spin_lock_init(&eqo->lock);
+ eqo->state = BE_EQ_IDLE;
+}
+
+static inline void be_disable_busy_poll(struct be_eq_obj *eqo)
+{
+ local_bh_disable();
+
+ /* It's enough to just acquire napi lock on the eqo to stop
+ * be_busy_poll() from processing any queueus.
+ */
+ while (!be_lock_napi(eqo))
+ mdelay(1);
+
+ local_bh_enable();
+}
+
+#else /* CONFIG_NET_RX_BUSY_POLL */
+
+static inline bool be_lock_napi(struct be_eq_obj *eqo)
+{
+ return true;
+}
+
+static inline void be_unlock_napi(struct be_eq_obj *eqo)
+{
+}
+
+static inline bool be_lock_busy_poll(struct be_eq_obj *eqo)
+{
+ return false;
+}
+
+static inline void be_unlock_busy_poll(struct be_eq_obj *eqo)
+{
+}
+
+static inline void be_enable_busy_poll(struct be_eq_obj *eqo)
+{
+}
+
+static inline void be_disable_busy_poll(struct be_eq_obj *eqo)
+{
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
u16 num_popped);
void be_link_status_update(struct be_adapter *adapter, u8 link_status);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 393e3dc..bb1cd55 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -22,6 +22,7 @@
#include <asm/div64.h>
#include <linux/aer.h>
#include <linux/if_bridge.h>
+#include <net/busy_poll.h>
MODULE_VERSION(DRV_VER);
MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -1556,7 +1557,7 @@ static void skb_fill_rx_data(struct be_rx_obj *rxo, struct sk_buff *skb,
}
/* Process the RX completion indicated by rxcp when GRO is disabled */
-static void be_rx_compl_process(struct be_rx_obj *rxo,
+static void be_rx_compl_process(struct be_rx_obj *rxo, struct napi_struct *napi,
struct be_rx_compl_info *rxcp)
{
struct be_adapter *adapter = rxo->adapter;
@@ -1581,7 +1582,7 @@ static void be_rx_compl_process(struct be_rx_obj *rxo,
skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]);
if (netdev->features & NETIF_F_RXHASH)
skb->rxhash = rxcp->rss_hash;
-
+ skb_mark_napi_id(skb, napi);
if (rxcp->vlanf)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), rxcp->vlan_tag);
@@ -1639,6 +1640,7 @@ static void be_rx_compl_process_gro(struct be_rx_obj *rxo,
skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]);
if (adapter->netdev->features & NETIF_F_RXHASH)
skb->rxhash = rxcp->rss_hash;
+ skb_mark_napi_id(skb, napi);
if (rxcp->vlanf)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), rxcp->vlan_tag);
@@ -1819,6 +1821,8 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp)
if (posted) {
atomic_add(posted, &rxq->used);
+ if (rxo->rx_post_starved)
+ rxo->rx_post_starved = false;
be_rxq_notify(adapter, rxq->id, posted);
} else if (atomic_read(&rxq->used) == 0) {
/* Let be_worker replenish when memory is available */
@@ -2021,6 +2025,7 @@ static void be_evt_queues_destroy(struct be_adapter *adapter)
if (eqo->q.created) {
be_eq_clean(eqo);
be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ);
+ napi_hash_del(&eqo->napi);
netif_napi_del(&eqo->napi);
}
be_queue_free(adapter, &eqo->q);
@@ -2262,7 +2267,7 @@ static inline bool do_gro(struct be_rx_compl_info *rxcp)
}
static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
- int budget)
+ int budget, int polling)
{
struct be_adapter *adapter = rxo->adapter;
struct be_queue_info *rx_cq = &rxo->cq;
@@ -2293,19 +2298,27 @@ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
goto loop_continue;
}
- if (do_gro(rxcp))
+ /* Don't do gro when we're busy_polling */
+ if (do_gro(rxcp) && polling != BUSY_POLLING)
be_rx_compl_process_gro(rxo, napi, rxcp);
else
- be_rx_compl_process(rxo, rxcp);
+ be_rx_compl_process(rxo, napi, rxcp);
+
loop_continue:
be_rx_stats_update(rxo, rxcp);
}
if (work_done) {
+ gfp_t gfp = (polling == BUSY_POLLING) ? GFP_KERNEL : GFP_ATOMIC;
+
be_cq_notify(adapter, rx_cq->id, true, work_done);
- if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM)
- be_post_rx_frags(rxo, GFP_ATOMIC);
+ /* When an rx-obj gets into post_starved state, just
+ * let be_worker do the posting.
+ */
+ if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM &&
+ !rxo->rx_post_starved)
+ be_post_rx_frags(rxo, gfp);
}
return work_done;
@@ -2349,6 +2362,7 @@ int be_poll(struct napi_struct *napi, int budget)
struct be_eq_obj *eqo = container_of(napi, struct be_eq_obj, napi);
struct be_adapter *adapter = eqo->adapter;
int max_work = 0, work, i, num_evts;
+ struct be_rx_obj *rxo;
bool tx_done;
num_evts = events_get(eqo);
@@ -2361,13 +2375,18 @@ int be_poll(struct napi_struct *napi, int budget)
max_work = budget;
}
- /* This loop will iterate twice for EQ0 in which
- * completions of the last RXQ (default one) are also processed
- * For other EQs the loop iterates only once
- */
- for (i = eqo->idx; i < adapter->num_rx_qs; i += adapter->num_evt_qs) {
- work = be_process_rx(&adapter->rx_obj[i], napi, budget);
- max_work = max(work, max_work);
+ if (be_lock_napi(eqo)) {
+ /* This loop will iterate twice for EQ0 in which
+ * completions of the last RXQ (default one) are also processed
+ * For other EQs the loop iterates only once
+ */
+ for_all_rx_queues_on_eq(adapter, eqo, rxo, i) {
+ work = be_process_rx(rxo, napi, budget, NAPI_POLLING);
+ max_work = max(work, max_work);
+ }
+ be_unlock_napi(eqo);
+ } else {
+ max_work = budget;
}
if (is_mcc_eqo(eqo))
@@ -2383,6 +2402,28 @@ int be_poll(struct napi_struct *napi, int budget)
return max_work;
}
+#ifdef CONFIG_NET_RX_BUSY_POLL
+static int be_busy_poll(struct napi_struct *napi)
+{
+ struct be_eq_obj *eqo = container_of(napi, struct be_eq_obj, napi);
+ struct be_adapter *adapter = eqo->adapter;
+ struct be_rx_obj *rxo;
+ int i, work = 0;
+
+ if (!be_lock_busy_poll(eqo))
+ return LL_FLUSH_BUSY;
+
+ for_all_rx_queues_on_eq(adapter, eqo, rxo, i) {
+ work = be_process_rx(rxo, napi, 4, BUSY_POLLING);
+ if (work)
+ break;
+ }
+
+ be_unlock_busy_poll(eqo);
+ return work;
+}
+#endif
+
void be_detect_error(struct be_adapter *adapter)
{
u32 ue_lo = 0, ue_hi = 0, ue_lo_mask = 0, ue_hi_mask = 0;
@@ -2614,9 +2655,11 @@ static int be_close(struct net_device *netdev)
be_roce_dev_close(adapter);
- if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
- for_all_evt_queues(adapter, eqo, i)
+ for_all_evt_queues(adapter, eqo, i) {
+ if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
napi_disable(&eqo->napi);
+ be_disable_busy_poll(eqo);
+ }
adapter->flags &= ~BE_FLAGS_NAPI_ENABLED;
}
@@ -2727,6 +2770,7 @@ static int be_open(struct net_device *netdev)
for_all_evt_queues(adapter, eqo, i) {
napi_enable(&eqo->napi);
+ be_enable_busy_poll(eqo);
be_eq_notify(adapter, eqo->q.id, true, false, 0);
}
adapter->flags |= BE_FLAGS_NAPI_ENABLED;
@@ -3989,6 +4033,9 @@ static const struct net_device_ops be_netdev_ops = {
#endif
.ndo_bridge_setlink = be_ndo_bridge_setlink,
.ndo_bridge_getlink = be_ndo_bridge_getlink,
+#ifdef CONFIG_NET_RX_BUSY_POLL
+ .ndo_busy_poll = be_busy_poll
+#endif
};
static void be_netdev_init(struct net_device *netdev)
@@ -4376,10 +4423,11 @@ static void be_worker(struct work_struct *work)
be_cmd_get_die_temperature(adapter);
for_all_rx_queues(adapter, rxo, i) {
- if (rxo->rx_post_starved) {
- rxo->rx_post_starved = false;
+ /* Replenish RX-queues starved due to memory
+ * allocation failures.
+ */
+ if (rxo->rx_post_starved)
be_post_rx_frags(rxo, GFP_KERNEL);
- }
}
be_eqd_update(adapter);
--
1.7.1
^ permalink raw reply related
* Re: 16% regression on 10G caused by TCP small queues
From: Stephen Hemminger @ 2013-10-24 4:45 UTC (permalink / raw)
To: David Miller; +Cc: ncardwell, eric.dumazet, dave.taht, netdev
In-Reply-To: <20131023.233816.1396918839771657154.davem@davemloft.net>
On Wed, 23 Oct 2013 23:38:16 -0400 (EDT)
David Miller <davem@davemloft.net> wrote:
> From: Stephen Hemminger <stephen@networkplumber.org>
> Date: Wed, 23 Oct 2013 20:09:49 -0700
>
> > I will check 3.12, but what about users on 3.10 which is the LTS
> > kernel used by most distros?
3.12-rc6 gets line rate again (9.41 Gbit/sec)
> The fix will be backported to -stable, relax Stephen.
Sorry, thought sk_pacing_rate depended on FQ qdisc but it is other way around.
In which case doing merge of these two was sufficient to fix the problem.
With a minor manual fix up to tcp.h.
commit 95bd09eb27507691520d39ee1044d6ad831c1168
Author: Eric Dumazet <edumazet@google.com>
Date: Tue Aug 27 05:46:32 2013 -0700
tcp: TSO packets automatic sizing
commit c9eeec26e32e087359160406f96e0949b3cc6f10
Author: Eric Dumazet <edumazet@google.com>
Date: Fri Sep 27 03:28:54 2013 -0700
tcp: TSQ can use a dynamic limit
^ permalink raw reply
* [PATCH] ibm emac: Don't call napi_complete if napi_reschedule failed
From: Alistair Popple @ 2013-10-24 3:36 UTC (permalink / raw)
To: netdev, davem; +Cc: benh, Alistair Popple
This patch fixes a bug which would trigger the BUG_ON() at
net/core/dev.c:4156. It was found that this was due to napi_complete
being called even when the corresponding call to napi_reschedule had
failed.
This patch ensures that we only contine processing rotting packets in
the current mal_poll call if we are not already on the polling list.
It also adds locking calls to protect the read-write-modify of the
MAL_CFG DCR.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
drivers/net/ethernet/ibm/emac/mal.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c
index 856ea66..b10ad5d 100644
--- a/drivers/net/ethernet/ibm/emac/mal.c
+++ b/drivers/net/ethernet/ibm/emac/mal.c
@@ -263,7 +263,9 @@ static inline void mal_schedule_poll(struct mal_instance *mal)
{
if (likely(napi_schedule_prep(&mal->napi))) {
MAL_DBG2(mal, "schedule_poll" NL);
+ spin_lock(&mal->lock);
mal_disable_eob_irq(mal);
+ spin_unlock(&mal->lock);
__napi_schedule(&mal->napi);
} else
MAL_DBG2(mal, "already in poll" NL);
@@ -442,17 +444,14 @@ static int mal_poll(struct napi_struct *napi, int budget)
if (unlikely(mc->ops->peek_rx(mc->dev) ||
test_bit(MAL_COMMAC_RX_STOPPED, &mc->flags))) {
MAL_DBG2(mal, "rotting packet" NL);
- if (napi_reschedule(napi))
- mal_disable_eob_irq(mal);
- else
- MAL_DBG2(mal, "already in poll list" NL);
-
- if (budget > 0)
- goto again;
- else
+ if (!napi_reschedule(napi))
goto more_work;
+
+ spin_lock_irqsave(&mal->lock, flags);
+ mal_disable_eob_irq(mal);
+ spin_unlock_irqrestore(&mal->lock, flags);
+ goto again;
}
- mc->ops->poll_tx(mc->dev);
}
more_work:
--
1.7.10.4
^ permalink raw reply related
* Re: 16% regression on 10G caused by TCP small queues
From: David Miller @ 2013-10-24 3:38 UTC (permalink / raw)
To: stephen; +Cc: ncardwell, eric.dumazet, dave.taht, netdev
In-Reply-To: <CAOaVG15indAxBz7E-T+9MK03indiXBa0UhQZ5j6K5DxYP44Mxg@mail.gmail.com>
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Wed, 23 Oct 2013 20:09:49 -0700
> I will check 3.12, but what about users on 3.10 which is the LTS
> kernel used by most distros?
The fix will be backported to -stable, relax Stephen.
^ permalink raw reply
* [PATCH NEXT 3/5] staging: r8188eu: Fix sparse warnings in rtl8188e.cmd.c
From: Larry Finger @ 2013-10-24 3:31 UTC (permalink / raw)
To: gregkh; +Cc: netdev, devel, Larry Finger
In-Reply-To: <1382585497-6787-1-git-send-email-Larry.Finger@lwfinger.net>
Sparse displays the following:
CHECK drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:285:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:285:15: expected unsigned short [usertype] *fctrl
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:285:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:368:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:368:15: expected unsigned short [usertype] *fctrl
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:368:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:403:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:403:15: expected unsigned short [usertype] *fctrl
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:403:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:465:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:465:15: expected unsigned short [usertype] *fctrl
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c:465:15: got restricted __le16 *<noident>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
index 0b0c68c..8be2ad7 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
@@ -273,7 +273,7 @@ void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, __le16 mstatus_rpt)
static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength)
{
struct rtw_ieee80211_hdr *pwlanhdr;
- u16 *fctrl;
+ __le16 *fctrl;
u32 rate_len, pktlen;
struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -360,7 +360,7 @@ static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength)
struct rtw_ieee80211_hdr *pwlanhdr;
struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- u16 *fctrl;
+ __le16 *fctrl;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -391,7 +391,7 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
u8 bForcePowerSave)
{
struct rtw_ieee80211_hdr *pwlanhdr;
- u16 *fctrl;
+ __le16 *fctrl;
u32 pktlen;
struct mlme_priv *pmlmepriv = &adapt->mlmepriv;
struct wlan_network *cur_network = &pmlmepriv->cur_network;
@@ -450,7 +450,7 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u8 *StaAddr, bool bHideSSID)
{
struct rtw_ieee80211_hdr *pwlanhdr;
- u16 *fctrl;
+ __le16 *fctrl;
u8 *mac, *bssid;
u32 pktlen;
struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
--
1.8.4
^ permalink raw reply related
* [PATCH NEXT 2/5] staging: r8188eu: Fix sparse warnings in rtw_ieee80211.c
From: Larry Finger @ 2013-10-24 3:31 UTC (permalink / raw)
To: gregkh; +Cc: netdev, devel, Larry Finger
In-Reply-To: <1382585497-6787-1-git-send-email-Larry.Finger@lwfinger.net>
Sparse reports the following:
CHECK drivers/staging/rtl8188eu/core/rtw_ieee80211.c
drivers/staging/rtl8188eu/core/rtw_ieee80211.c:1593:14: warning: cast to restricted __le16
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
drivers/staging/rtl8188eu/include/ieee80211.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/staging/rtl8188eu/include/ieee80211.h b/drivers/staging/rtl8188eu/include/ieee80211.h
index cd37ea4..c4d38d1 100644
--- a/drivers/staging/rtl8188eu/include/ieee80211.h
+++ b/drivers/staging/rtl8188eu/include/ieee80211.h
@@ -306,8 +306,8 @@ struct ieee_ibss_seq {
};
struct rtw_ieee80211_hdr {
- u16 frame_ctl;
- u16 duration_id;
+ __le16 frame_ctl;
+ __le16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
@@ -316,8 +316,8 @@ struct rtw_ieee80211_hdr {
} __packed;
struct rtw_ieee80211_hdr_3addr {
- u16 frame_ctl;
- u16 duration_id;
+ __le16 frame_ctl;
+ __le16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
@@ -325,8 +325,8 @@ struct rtw_ieee80211_hdr_3addr {
} __packed;
struct rtw_ieee80211_hdr_qos {
- u16 frame_ctl;
- u16 duration_id;
+ __le16 frame_ctl;
+ __le16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
@@ -336,8 +336,8 @@ struct rtw_ieee80211_hdr_qos {
} __packed;
struct rtw_ieee80211_hdr_3addr_qos {
- u16 frame_ctl;
- u16 duration_id;
+ __le16 frame_ctl;
+ __le16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
--
1.8.4
^ permalink raw reply related
* [PATCH NEXT 1/5] staging: r8188eu: Fix sparse warnings in ioctl_linux.c
From: Larry Finger @ 2013-10-24 3:31 UTC (permalink / raw)
To: gregkh; +Cc: netdev, devel, Larry Finger
In-Reply-To: <1382585497-6787-1-git-send-email-Larry.Finger@lwfinger.net>
Sparse checking results in the following warnings:
CHECK drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3932:17: warning: cast removes address space of expression
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3933:31: warning: incorrect type in argument 1 (different address spaces)
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3933:31: expected void const *<noident>
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3933:31: got void [noderef] <asn:1>*pointer
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3935:38: warning: incorrect type in argument 1 (different address spaces)
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3935:38: expected void const *<noident>
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3935:38: got void [noderef] <asn:1>*pointer
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3937:38: warning: incorrect type in argument 1 (different address spaces)
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3937:38: expected void const *<noident>
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3937:38: got void [noderef] <asn:1>*pointer
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3939:38: warning: incorrect type in argument 1 (different address spaces)
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3939:38: expected void const *<noident>
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3939:38: got void [noderef] <asn:1>*pointer
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3941:38: warning: incorrect type in argument 1 (different address spaces)
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3941:38: expected void const *<noident>
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3941:38: got void [noderef] <asn:1>*pointer
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3944:38: warning: incorrect type in argument 1 (different address spaces)
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3944:38: expected void const *<noident>
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3944:38: got void [noderef] <asn:1>*pointer
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3946:38: warning: incorrect type in argument 1 (different address spaces)
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3946:38: expected void const *<noident>
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3946:38: got void [noderef] <asn:1>*pointer
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3949:38: warning: incorrect type in argument 1 (different address spaces)
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3949:38: expected void const *<noident>
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3949:38: got void [noderef] <asn:1>*pointer
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c:3963:9: warning: cast removes address space of expression
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index ae54587..5dc3fed 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -3929,24 +3929,24 @@ static int rtw_p2p_get(struct net_device *dev,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
if (padapter->bShowGetP2PState)
- DBG_88E("[%s] extra = %s\n", __func__, (char *)wrqu->data.pointer);
- if (!memcmp(wrqu->data.pointer, "status", 6)) {
+ DBG_88E("[%s] extra = %s\n", __func__, (__force char *)wrqu->data.pointer);
+ if (!memcmp((__force const char *)wrqu->data.pointer, "status", 6)) {
rtw_p2p_get_status(dev, info, wrqu, extra);
- } else if (!memcmp(wrqu->data.pointer, "role", 4)) {
+ } else if (!memcmp((__force const char *)wrqu->data.pointer, "role", 4)) {
rtw_p2p_get_role(dev, info, wrqu, extra);
- } else if (!memcmp(wrqu->data.pointer, "peer_ifa", 8)) {
+ } else if (!memcmp((__force const char *)wrqu->data.pointer, "peer_ifa", 8)) {
rtw_p2p_get_peer_ifaddr(dev, info, wrqu, extra);
- } else if (!memcmp(wrqu->data.pointer, "req_cm", 6)) {
+ } else if (!memcmp((__force const char *)wrqu->data.pointer, "req_cm", 6)) {
rtw_p2p_get_req_cm(dev, info, wrqu, extra);
- } else if (!memcmp(wrqu->data.pointer, "peer_deva", 9)) {
+ } else if (!memcmp((__force const char *)wrqu->data.pointer, "peer_deva", 9)) {
/* Get the P2P device address when receiving the provision discovery request frame. */
rtw_p2p_get_peer_devaddr(dev, info, wrqu, extra);
- } else if (!memcmp(wrqu->data.pointer, "group_id", 8)) {
+ } else if (!memcmp((__force const char *)wrqu->data.pointer, "group_id", 8)) {
rtw_p2p_get_groupid(dev, info, wrqu, extra);
- } else if (!memcmp(wrqu->data.pointer, "peer_deva_inv", 9)) {
+ } else if (!memcmp((__force const char *)wrqu->data.pointer, "peer_deva_inv", 9)) {
/* Get the P2P device address when receiving the P2P Invitation request frame. */
rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra);
- } else if (!memcmp(wrqu->data.pointer, "op_ch", 5)) {
+ } else if (!memcmp((__force const char *)wrqu->data.pointer, "op_ch", 5)) {
rtw_p2p_get_op_ch(dev, info, wrqu, extra);
}
#endif /* CONFIG_88EU_P2P */
@@ -3960,7 +3960,7 @@ static int rtw_p2p_get2(struct net_device *dev,
int ret = 0;
#ifdef CONFIG_88EU_P2P
- DBG_88E("[%s] extra = %s\n", __func__, (char *)wrqu->data.pointer);
+ DBG_88E("[%s] extra = %s\n", __func__, (__force char *)wrqu->data.pointer);
if (!memcmp(extra, "wpsCM =", 6)) {
wrqu->data.length -= 6;
rtw_p2p_get_wps_configmethod(dev, info, wrqu, &extra[6]);
--
1.8.4
^ permalink raw reply related
* [PATCH NEXT 5/5] staging: r8188eu: Fix sparse warnings in rtl_p2p.c
From: Larry Finger @ 2013-10-24 3:31 UTC (permalink / raw)
To: gregkh; +Cc: devel, netdev, Larry Finger
In-Reply-To: <1382585497-6787-1-git-send-email-Larry.Finger@lwfinger.net>
Sparse displays the following:
CHECK drivers/staging/rtl8188eu/core/rtw_p2p.c
drivers/staging/rtl8188eu/core/rtw_p2p.c:162:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_p2p.c:162:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_p2p.c:162:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_p2p.c:221:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_p2p.c:221:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_p2p.c:221:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_p2p.c:292:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_p2p.c:292:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_p2p.c:292:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_p2p.c:371:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_p2p.c:371:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_p2p.c:371:15: got restricted __le16 *<noident>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
drivers/staging/rtl8188eu/core/rtw_p2p.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/rtl8188eu/core/rtw_p2p.c b/drivers/staging/rtl8188eu/core/rtw_p2p.c
index 8cf915f..f46cab1 100644
--- a/drivers/staging/rtl8188eu/core/rtw_p2p.c
+++ b/drivers/staging/rtl8188eu/core/rtw_p2p.c
@@ -135,7 +135,7 @@ static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da)
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct adapter *padapter = pwdinfo->padapter;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
@@ -192,7 +192,7 @@ static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 s
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct adapter *padapter = pwdinfo->padapter;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
@@ -272,7 +272,7 @@ static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8 *raddr,
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
@@ -342,7 +342,7 @@ static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct adapter *padapter = pwdinfo->padapter;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
--
1.8.4
^ permalink raw reply related
* [PATCH NEXT 4/5] staging: r8188eu: Fix sparse warnings in rtw_mlme_ext.c
From: Larry Finger @ 2013-10-24 3:31 UTC (permalink / raw)
To: gregkh; +Cc: devel, netdev, Larry Finger
In-Reply-To: <1382585497-6787-1-git-send-email-Larry.Finger@lwfinger.net>
Sparse displays the following:
CHECK drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:1874:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:1874:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:1874:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:2221:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:2221:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:2221:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:2583:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:2583:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:2583:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:2750:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:2750:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:2750:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3002:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3002:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3002:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3197:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3197:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3197:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3311:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3311:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3311:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3563:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3563:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:3563:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:4522:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:4522:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:4522:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:4750:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:4750:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:4750:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:4906:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:4906:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:4906:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5040:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5040:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5040:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5184:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5184:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5184:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5322:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5322:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5322:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5654:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5654:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5654:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5769:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5769:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5769:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5894:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5894:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5894:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5996:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5996:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:5996:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:6066:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:6066:15: expected unsigned short [usertype] *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:6066:15: got restricted __le16 *<noident>
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:6200:15: warning: incorrect type in assignment (different base types)
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:6200:15: expected unsigned short *fctrl
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:6200:15: got restricted __le16 *<noident>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 41 ++++++++++++++-------------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
index 9982dd0..7ab5ff0 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
@@ -1852,7 +1852,7 @@ void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr)
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
@@ -2199,7 +2199,7 @@ static void issue_p2p_GO_response(struct adapter *padapter, u8 *raddr, u8 *frame
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
@@ -2561,7 +2561,7 @@ static void issue_p2p_GO_confirm(struct adapter *padapter, u8 *raddr, u8 result)
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
@@ -2729,7 +2729,7 @@ void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr)
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
@@ -2981,7 +2981,7 @@ void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, u8 dialo
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
@@ -3175,7 +3175,7 @@ void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid, u8 ussidle
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
@@ -3283,7 +3283,7 @@ void issue_probersp_p2p(struct adapter *padapter, unsigned char *da)
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
unsigned char *mac;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
@@ -3534,7 +3534,7 @@ static int _issue_probereq_p2p(struct adapter *padapter, u8 *da, int wait_ack)
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
unsigned char *mac;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
@@ -4484,7 +4484,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms)
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
unsigned int rate_len;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
#if defined(CONFIG_88EU_AP_MODE)
@@ -4713,7 +4713,7 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
unsigned char *mac, *bssid;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
#if defined (CONFIG_88EU_AP_MODE)
@@ -4876,7 +4876,7 @@ static int _issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *ps
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
unsigned char *mac;
unsigned char bssrate[NumRates];
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
@@ -5013,7 +5013,7 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
unsigned int val32;
u16 val16;
#ifdef CONFIG_88EU_AP_MODE
@@ -5153,7 +5153,7 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
struct pkt_attrib *pattrib;
unsigned char *pbuf, *pframe;
unsigned short val;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
@@ -5290,7 +5290,7 @@ void issue_assocreq(struct adapter *padapter)
struct pkt_attrib *pattrib;
unsigned char *pframe, *p;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
__le16 le_tmp;
unsigned int i, j, ie_len, index = 0;
unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
@@ -5625,7 +5625,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv;
struct mlme_ext_priv *pmlmeext;
struct mlme_ext_info *pmlmeinfo;
@@ -5740,7 +5740,8 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl, *qc;
+ __le16 *fctrl;
+ unsigned short *qc;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -5860,7 +5861,7 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned s
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -5972,7 +5973,7 @@ void issue_action_spct_ch_switch (struct adapter *padapter, u8 *ra, u8 new_ch, u
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
@@ -6040,7 +6041,7 @@ void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned ch
struct pkt_attrib *pattrib;
u8 *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- u16 *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -6162,7 +6163,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct wlan_network *pnetwork = NULL;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
--
1.8.4
^ permalink raw reply related
* [PATCH 0/5 NEXT V2] staging: r8188eu: Fix sparse warnings.
From: Larry Finger @ 2013-10-24 3:31 UTC (permalink / raw)
To: gregkh; +Cc: devel, netdev, Larry Finger
This set of patches resubmits the set of fixes for sparse warnings. The two that
were criticized have been removed, and this set should not have white-space
damage.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Larry Finger (5):
staging: r8188eu: Fix sparse warnings in ioctl_linux.c
staging: r8188eu: Fix sparse warnings in rtw_ieee80211.c
staging: r8188eu: Fix sparse warnings in rtl8188e.cmd.c
staging: r8188eu: Fix sparse warnings in rtw_mlme_ext.c
staging: r8188eu: Fix sparse warnings in rtl_p2p.c
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 41 +++++++++++++-------------
drivers/staging/rtl8188eu/core/rtw_p2p.c | 8 ++---
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c | 8 ++---
drivers/staging/rtl8188eu/include/ieee80211.h | 16 +++++-----
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 20 ++++++-------
6 files changed, 47 insertions(+), 46 deletions(-)
--
1.8.4
^ permalink raw reply
* [PATCH net-next v2 2/5] bonding: remove bond read lock for bond_alb_monitor()
From: Ding Tianhong @ 2013-10-24 3:09 UTC (permalink / raw)
To: Jay Vosburgh, Andy Gospodarek, David S. Miller,
Nikolay Aleksandrov, Veaceslav Falico, Netdev
The bond slave list may change when the monitor is running, the slave list is no longer
protected by bond->lock, only protected by rtnl lock(), so we has 3 way to modify it:
1.add bond_master_upper_dev_link() and bond_upper_dev_unlink() in bond->lock, but it is unsafe
to call call_netdevice_notifiers() in write lock.
2.remove unused bond->lock for monitor function, only use the exist rtnl lock().
3.use rcu_read_lock() to protect it, of course, it will transform bond_for_each_slave to
bond_for_each_slave_rcu() and performance is better, but in slow path, it is ignored.
so I remove the bond->lock and move the rtnl lock to protect the whole monitor function.
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
drivers/net/bonding/bond_alb.c | 20 ++++----------------
1 file changed, 4 insertions(+), 16 deletions(-)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 0287240..5d79f5e 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1495,11 +1495,13 @@ void bond_alb_monitor(struct work_struct *work)
struct list_head *iter;
struct slave *slave;
- read_lock(&bond->lock);
+ if (!rtnl_trylock())
+ goto re_arm;
if (!bond_has_slaves(bond)) {
bond_info->tx_rebalance_counter = 0;
bond_info->lp_counter = 0;
+ rtnl_unlock();
goto re_arm;
}
@@ -1548,16 +1550,6 @@ void bond_alb_monitor(struct work_struct *work)
if (bond_info->primary_is_promisc &&
(++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) {
- /*
- * dev_set_promiscuity requires rtnl and
- * nothing else. Avoid race with bond_close.
- */
- read_unlock(&bond->lock);
- if (!rtnl_trylock()) {
- read_lock(&bond->lock);
- goto re_arm;
- }
-
bond_info->rlb_promisc_timeout_counter = 0;
/* If the primary was set to promiscuous mode
@@ -1566,9 +1558,6 @@ void bond_alb_monitor(struct work_struct *work)
*/
dev_set_promiscuity(bond->curr_active_slave->dev, -1);
bond_info->primary_is_promisc = 0;
-
- rtnl_unlock();
- read_lock(&bond->lock);
}
if (bond_info->rlb_rebalance) {
@@ -1591,10 +1580,9 @@ void bond_alb_monitor(struct work_struct *work)
}
}
+ rtnl_unlock();
re_arm:
queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks);
-
- read_unlock(&bond->lock);
}
/* assumption: called before the slave is attached to the bond
--
1.8.2.1
^ permalink raw reply related
* [PATCH net-next v2 5/5] bonding: remove bond read lock for bond_3ad_state_machine_handler()
From: Ding Tianhong @ 2013-10-24 3:09 UTC (permalink / raw)
To: Jay Vosburgh, Andy Gospodarek, David S. Miller,
Nikolay Aleksandrov, Veaceslav Falico, Netdev
The bond slave list may change when the monitor is running, the slave list is no longer
protected by bond->lock, only protected by rtnl lock(), so we has 3 way to modify it:
1.add bond_master_upper_dev_link() and bond_upper_dev_unlink() in bond->lock, but it is unsafe
to call call_netdevice_notifiers() in write lock.
2.remove unused bond->lock for monitor function, only use the exist rtnl lock().
3.use rcu_read_lock() to protect it, of course, it will transform bond_for_each_slave to
bond_for_each_slave_rcu() and performance is better, but in slow path, it is ignored.
so I remove the bond->lock and move the rtnl lock to protect the whole monitor function.
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
drivers/net/bonding/bond_3ad.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 187b1b7..d6fe00b 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2068,8 +2068,10 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
struct slave *slave;
struct port *port;
- read_lock(&bond->lock);
-
+ if (!rtnl_trylock()) {
+ queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks);
+ return;
+ }
//check if there are any slaves
if (!bond_has_slaves(bond))
goto re_arm;
@@ -2122,9 +2124,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
}
re_arm:
+ rtnl_unlock();
queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks);
-
- read_unlock(&bond->lock);
}
/**
--
1.8.2.1
^ permalink raw reply related
* [PATCH net-next v2 3/5] bonding: remove bond read lock for bond_loadbalance_arp_mon()
From: Ding Tianhong @ 2013-10-24 3:09 UTC (permalink / raw)
To: Jay Vosburgh, Andy Gospodarek, David S. Miller,
Nikolay Aleksandrov, Veaceslav Falico, Netdev
The bond slave list may change when the monitor is running, the slave list is no longer
protected by bond->lock, only protected by rtnl lock(), so we has 3 way to modify it:
1.add bond_master_upper_dev_link() and bond_upper_dev_unlink() in bond->lock, but it is unsafe
to call call_netdevice_notifiers() in write lock.
2.remove unused bond->lock for monitor function, only use the exist rtnl lock().
3.use rcu_read_lock() to protect it, of course, it will transform bond_for_each_slave to
bond_for_each_slave_rcu() and performance is better, but in slow path, it is ignored.
so I remove the bond->lock and add the rtnl lock to protect the whole monitor function.
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
drivers/net/bonding/bond_main.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index ba90f45..149f4b9 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2433,10 +2433,13 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
struct list_head *iter;
int do_failover = 0;
- read_lock(&bond->lock);
+ if (!rtnl_trylock())
+ goto re_arm;
- if (!bond_has_slaves(bond))
+ if (!bond_has_slaves(bond)) {
+ rtnl_unlock();
goto re_arm;
+ }
oldcurrent = bond->curr_active_slave;
/* see if any of the previous devices are up now (i.e. they have
@@ -2518,13 +2521,12 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
write_unlock_bh(&bond->curr_slave_lock);
unblock_netpoll_tx();
}
+ rtnl_unlock();
re_arm:
if (bond->params.arp_interval)
queue_delayed_work(bond->wq, &bond->arp_work,
msecs_to_jiffies(bond->params.arp_interval));
-
- read_unlock(&bond->lock);
}
/*
--
1.8.2.1
^ permalink raw reply related
* [PATCH net-next v2 4/5] bonding: remove bond read lock for bond_activebackup_arp_mon()
From: Ding Tianhong @ 2013-10-24 3:09 UTC (permalink / raw)
To: Jay Vosburgh, Andy Gospodarek, David S. Miller,
Nikolay Aleksandrov, Veaceslav Falico, Netdev
The bond slave list may change when the monitor is running, the slave list is no longer
protected by bond->lock, only protected by rtnl lock(), so we has 3 way to modify it:
1.add bond_master_upper_dev_link() and bond_upper_dev_unlink() in bond->lock, but it is unsafe
to call call_netdevice_notifiers() in write lock.
2.remove unused bond->lock for monitor function, only use the exist rtnl lock().
3.use rcu_read_lock() to protect it, of course, it will transform bond_for_each_slave to
bond_for_each_slave_rcu() and performance is better, but in slow path, it is ignored.
so I remove the bond->lock and move the rtnl lock to protect the whole monitor function.
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
drivers/net/bonding/bond_main.c | 46 ++++++++++++-----------------------------
1 file changed, 13 insertions(+), 33 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 149f4b9..f3df532 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2763,51 +2763,31 @@ void bond_activebackup_arp_mon(struct work_struct *work)
struct bonding *bond = container_of(work, struct bonding,
arp_work.work);
bool should_notify_peers = false;
- int delta_in_ticks;
- read_lock(&bond->lock);
-
- delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
+ if (!rtnl_trylock())
+ goto re_arm;
- if (!bond_has_slaves(bond))
+ if (!bond_has_slaves(bond)) {
+ rtnl_unlock();
goto re_arm;
+ }
should_notify_peers = bond_should_notify_peers(bond);
- if (bond_ab_arp_inspect(bond)) {
- read_unlock(&bond->lock);
-
- /* Race avoidance with bond_close flush of workqueue */
- if (!rtnl_trylock()) {
- read_lock(&bond->lock);
- delta_in_ticks = 1;
- should_notify_peers = false;
- goto re_arm;
- }
-
- read_lock(&bond->lock);
-
+ if (bond_ab_arp_inspect(bond))
bond_ab_arp_commit(bond);
- read_unlock(&bond->lock);
- rtnl_unlock();
- read_lock(&bond->lock);
- }
-
bond_ab_arp_probe(bond);
-re_arm:
- if (bond->params.arp_interval)
- queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
+ if (should_notify_peers)
+ call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev);
- read_unlock(&bond->lock);
+ rtnl_unlock();
- if (should_notify_peers) {
- if (!rtnl_trylock())
- return;
- call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev);
- rtnl_unlock();
- }
+re_arm:
+ if (bond->params.arp_interval)
+ queue_delayed_work(bond->wq, &bond->arp_work,
+ msecs_to_jiffies(bond->params.arp_interval));
}
/*-------------------------- netdev event handling --------------------------*/
--
1.8.2.1
^ 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