* Re: [GIT] Networking
From: Linus Torvalds @ 2017-09-07 4:57 UTC (permalink / raw)
To: Coelho, Luciano
Cc: davem@davemloft.net, kvalo@codeaurora.org, Berg, Johannes,
Grumbach, Emmanuel, linuxwifi, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org,
akpm@linux-foundation.org
In-Reply-To: <1504757495.5400.89.camel@intel.com>
On Wed, Sep 6, 2017 at 9:11 PM, Coelho, Luciano
<luciano.coelho@intel.com> wrote:
>
> This seems to be a problem with backwards-compatibility with FW version
> 27. We are now in version 31[1] and upgrading will probably fix that.
I can confirm that fw version 31 works.
> But obviously the driver should not fail miserably like this with
> version 27, because it claims to support it still.
Not just "claims to support it", but if it's what is shipped with a
fairly recent distro like an up-to-date version of F26, I would really
hope that the driver can still work with it.
> I'm looking into this now and will provide a fix asap.
Thanks,
Linus
^ permalink raw reply
* Re: [GIT] Networking
From: Coelho, Luciano @ 2017-09-07 5:04 UTC (permalink / raw)
To: torvalds@linux-foundation.org
Cc: linux-kernel@vger.kernel.org, linuxwifi, Berg, Johannes,
akpm@linux-foundation.org, kvalo@codeaurora.org,
netdev@vger.kernel.org, davem@davemloft.net,
linux-wireless@vger.kernel.org, Grumbach, Emmanuel
In-Reply-To: <CA+55aFzECjnpFWo_ZfbV+vE-5zRst7JfDC0hxnoitCGN0rmE3Q@mail.gmail.com>
On Wed, 2017-09-06 at 21:57 -0700, Linus Torvalds wrote:
> On Wed, Sep 6, 2017 at 9:11 PM, Coelho, Luciano
> <luciano.coelho@intel.com> wrote:
> >
> > This seems to be a problem with backwards-compatibility with FW version
> > 27. We are now in version 31[1] and upgrading will probably fix that.
>
> I can confirm that fw version 31 works.
Great, so I know for sure that this is a backwards-compatibility issue
with the FW API.
> > But obviously the driver should not fail miserably like this with
> > version 27, because it claims to support it still.
>
> Not just "claims to support it", but if it's what is shipped with a
> fairly recent distro like an up-to-date version of F26, I would really
> hope that the driver can still work with it.
I totally agree, we support a bunch of older versions for that exact
reason. We just don't really test all the supported versions very
often. We should probably change that.
I'll make sure it still works with version 27.
--
Cheers,
Luca.
^ permalink raw reply
* WARNING: at net/netfilter/core.c:218 __nf_hook_entries_try_shrink+0xf7/0x110
From: Mike Galbraith @ 2017-09-07 5:11 UTC (permalink / raw)
To: netdev
[-- Attachment #1: Type: text/plain, Size: 9981 bytes --]
[ 21.219604] ip6_tables: (C) 2000-2006 Netfilter Core Team
[ 21.433091] nf_conntrack version 0.5.0 (65536 buckets, 262144 max)
[ 21.495849] ip_tables: (C) 2000-2006 Netfilter Core Team
[ 22.404040] ------------[ cut here ]------------
[ 22.404267] WARNING: CPU: 2 PID: 1379 at net/netfilter/core.c:218 __nf_hook_entries_try_shrink+0xf7/0x110
[ 22.404484] Modules linked in: xt_tcpudp(E) iptable_filter(E) ip6table_mangle(E) nf_conntrack_netbios_ns(E) nf_conntrack_broadcast(E) nf_conntrack_ipv4(E) nf_defrag_ipv4(E) ip_tables(E) xt_conntrack(E) nf_conntrack(E) ip6table_filter(E) ip6_tables(E) x_tables(E) nls_iso8859_1(E) nls_cp437(E) intel_rapl(E) x86_pkg_temp_thermal(E) intel_powerclamp(E) coretemp(E) snd_hda_codec_hdmi(E) kvm_intel(E) kvm(E) snd_hda_codec_realtek(E) snd_hda_codec_generic(E) snd_hda_intel(E) irqbypass(E) joydev(E) snd_hda_codec(E) snd_hwdep(E) snd_hda_core(E) snd_pcm(E) crct10dif_pclmul(E) snd_timer(E) crc32_pclmul(E) crc32c_intel(E) ghash_clmulni_intel(E) snd(E) pcbc(E) aesni_intel(E) iTCO_wdt(E) aes_x86_64(E) r8169(E) iTCO_vendor_support(E) crypto_simd(E) glue_helper(E) lpc_ich(E) mii(E) mei_me(E) mei(E) mfd_
core(E) soundcore(E)
[ 22.405405] cryptd(E) i2c_i801(E) shpchp(E) intel_smartconnect(E) thermal(E) fan(E) battery(E) tpm_infineon(E) pcspkr(E) nfsd(E) auth_rpcgss(E) nfs_acl(E) lockd(E) grace(E) sunrpc(E) sr_mod(E) cdrom(E) hid_logitech_hidpp(E) hid_logitech_dj(E) uas(E) usb_storage(E) hid_generic(E) usbhid(E) nouveau(E) wmi(E) i2c_algo_bit(E) drm_kms_helper(E) syscopyarea(E) sysfillrect(E) sysimgblt(E) ehci_pci(E) fb_sys_fops(E) ahci(E) xhci_pci(E) ttm(E) libahci(E) ehci_hcd(E) xhci_hcd(E) libata(E) drm(E) usbcore(E) video(E) button(E) sd_mod(E) vfat(E) fat(E) virtio_rng(E) virtio_blk(E) virtio_mmio(E) virtio_pci(E) virtio_ring(E) virtio(E) ext4(E) crc16(E) mbcache(E) jbd2(E) fscrypto(E) loop(E) sg(E) dm_multipath(E) dm_mod(E) scsi_dh_rdac(E) scsi_dh_emc(E) scsi_dh_alua(E) scsi_mod(E) efivarfs(E) autofs4(E
)
[ 22.406419] CPU: 2 PID: 1379 Comm: iptables-batch Tainted: G E 4.13.0.g1c9fe44-master #10
[ 22.406662] Hardware name: MEDION MS-7848/MS-7848, BIOS M7848W08.20C 09/23/2013
[ 22.406911] task: ffff88041e822940 task.stack: ffffc900003f4000
[ 22.407161] RIP: 0010:__nf_hook_entries_try_shrink+0xf7/0x110
[ 22.407411] RSP: 0018:ffffc900003f7c18 EFLAGS: 00010246
[ 22.407668] RAX: 0000000000000010 RBX: ffff8803cce14e40 RCX: 0000000000000000
[ 22.407918] RDX: 0000000000000001 RSI: 0000000000000000 RDI: 0000000000000001
[ 22.408162] RBP: ffffc900003f7c38 R08: 0000000000000001 R09: 0000000000000000
[ 22.408410] R10: 0000000000000000 R11: 0000000000040001 R12: ffff8803cce14e58
[ 22.408663] R13: ffffffff81aac2c8 R14: ffffffffa09290a0 R15: ffffffff81aab9c0
[ 22.408928] FS: 00007f6c31c1a700(0000) GS:ffff88041ec80000(0000) knlGS:0000000000000000
[ 22.409186] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 22.409447] CR2: 00007f708537af14 CR3: 00000003fa4e5004 CR4: 00000000001606e0
[ 22.409710] Call Trace:
[ 22.409978] nf_unregister_net_hooks+0xf2/0x1a0
[ 22.410246] ? mutex_lock+0xe/0x30
[ 22.410518] ? mutex_lock+0xe/0x30
[ 22.410786] ? cleanup_match+0x40/0x50 [ip_tables]
[ 22.411052] ipv4_hooks_unregister+0x58/0x70 [nf_conntrack_ipv4]
[ 22.411322] nf_ct_netns_put+0x3c/0x80 [nf_conntrack]
[ 22.411584] cleanup_match+0x32/0x50 [ip_tables]
[ 22.411845] cleanup_entry+0x2e/0x90 [ip_tables]
[ 22.412110] translate_table+0x454/0x570 [ip_tables]
[ 22.412371] do_ipt_set_ctl+0xed/0x193 [ip_tables]
[ 22.412641] nf_setsockopt+0x3e/0x60
[ 22.412909] ip_setsockopt+0x6f/0x90
[ 22.413178] SyS_setsockopt+0x5e/0xb0
[ 22.413450] entry_SYSCALL_64_fastpath+0x1a/0xa5
[ 22.413706] RIP: 0033:0x7f6c3137cbca
[ 22.413969] RSP: 002b:00007ffc32d9d558 EFLAGS: 00000202 ORIG_RAX: 0000000000000036
[ 22.414224] RAX: ffffffffffffffda RBX: 00007f6c3162f678 RCX: 00007f6c3137cbca
[ 22.414490] RDX: 0000000000000040 RSI: 0000000000000000 RDI: 0000000000000007
[ 22.414758] RBP: 00007f6c3162f620 R08: 0000000000000ac8 R09: fefefefeff626d74
[ 22.415016] R10: 0000000001ed8920 R11: 0000000000000202 R12: 0000000000000af0
[ 22.415293] R13: 0000000000000ac8 R14: 0000000000002709 R15: 0000000000000ad1
[ 22.415564] Code: 39 d1 77 ba 4c 89 f7 e8 98 fe ff ff 4d 89 75 00 48 89 d8 5b 41 5c 41 5d 41 5e 5d c3 45 31 f6 eb eb 31 c0 eb ee 0f ff 31 c0 eb e8 <0f> ff 31 c0 0f 1f 44 00 00 eb dd 0f 1f 40 00 66 2e 0f 1f 84 00
[ 22.415881] ---[ end trace d15c01c3a7360856 ]---
Met 10 of those during this boot. The first time I booted, the
warnings were followed by the explosion below, but that kernel was not
entirely virgin, so add a pinch of salt.
[ 48.592298] Ebtables v2.0 registered
[ 48.730755] BUG: unable to handle kernel NULL pointer dereference at 000000000000003c
[ 48.732723] IP: _raw_read_lock_bh+0x15/0x30
[ 48.734526] PGD 0 P4D 0
[ 48.736482] Oops: 0002 [#1] SMP
[ 48.738317] Dumping ftrace buffer:
[ 48.740260] (ftrace buffer empty)
[ 48.742226] Modules linked in: ebtable_filter(E+) ebtables(E) af_packet(E) bridge(E) stp(E) llc(E) iscsi_ibft(E) iscsi_boot_sysfs(E) nf_conntrack_ipv6(E) nf_defrag_ipv6(E) ipt_REJECT(E) xt_tcpudp(E) iptable_filter(E) ip6table_mangle(E) nf_conntrack_netbios_ns(E) nf_conntrack_broadcast(E) nf_conntrack_ipv4(E) nf_defrag_ipv4(E) ip_tables(E) xt_conntrack(E) nf_conntrack(E) ip6table_filter(E) ip6_tables(E) x_tables(E) nls_iso8859_1(E) nls_cp437(E) intel_rapl(E) x86_pkg_temp_thermal(E) intel_powerclamp(E) coretemp(E) kvm_intel(E) kvm(E) snd_hda_codec_hdmi(E) irqbypass(E) snd_hda_codec_realtek(E) snd_hda_codec_generic(E) snd_hda_intel(E) snd_hda_codec(E) snd_hwdep(E) crct10dif_pclmul(E) snd_hda_core(E) crc32_pclmul(E) snd_pcm(E) joydev(E) snd_timer(E) r8169(E) crc32c_intel(E) ghash_clmulni_in
tel(E) snd(E)
[ 48.751616] mii(E) pcbc(E) aesni_intel(E) aes_x86_64(E) iTCO_wdt(E) shpchp(E) iTCO_vendor_support(E) crypto_simd(E) soundcore(E) glue_helper(E) mei_me(E) lpc_ich(E) mfd_core(E) mei(E) i2c_i801(E) cryptd(E) pcspkr(E) intel_smartconnect(E) battery(E) tpm_infineon(E) thermal(E) fan(E) nfsd(E) auth_rpcgss(E) nfs_acl(E) lockd(E) grace(E) sunrpc(E) sr_mod(E) cdrom(E) hid_logitech_hidpp(E) hid_logitech_dj(E) uas(E) usb_storage(E) hid_generic(E) usbhid(E) nouveau(E) wmi(E) i2c_algo_bit(E) drm_kms_helper(E) syscopyarea(E) sysfillrect(E) sysimgblt(E) fb_sys_fops(E) ttm(E) ahci(E) libahci(E) ehci_pci(E) xhci_pci(E) ehci_hcd(E) xhci_hcd(E) libata(E) drm(E) usbcore(E) video(E) button(E) sd_mod(E) vfat(E) fat(E) virtio_rng(E) virtio_blk(E) virtio_mmio(E) virtio_pci(E) virtio_ring(E) virtio(E) ext4(E
) crc16(E)
[ 48.763168] mbcache(E) jbd2(E) fscrypto(E) loop(E) sg(E) dm_multipath(E) dm_mod(E) scsi_dh_rdac(E) scsi_dh_emc(E) scsi_dh_alua(E) scsi_mod(E) efivarfs(E) autofs4(E)
[ 48.766157] CPU: 2 PID: 0 Comm: swapper/2 Tainted: G W E 4.13.0.g1c9fe44-master #9
[ 48.769108] Hardware name: MEDION MS-7848/MS-7848, BIOS M7848W08.20C 09/23/2013
[ 48.772251] task: ffff88018fe42940 task.stack: ffffc90000088000
[ 48.775370] RIP: 0010:_raw_read_lock_bh+0x15/0x30
[ 48.776496] RSP: 0018:ffff88041ec83bd0 EFLAGS: 00010286
[ 48.777414] RAX: 0000000000000100 RBX: 0000000000000001 RCX: 0000000000000000
[ 48.778302] RDX: 0000000000000000 RSI: ffff88041ec83ca8 RDI: 000000000000003c
[ 48.779189] RBP: 0000000000000000 R08: 0000000000000001 R09: 00000000088a0c8d
[ 48.780072] R10: 0000000000000000 R11: 0000000000007b00 R12: ffff8803cdcc1300
[ 48.780950] R13: ffff8803cdcc1300 R14: 0000000000000000 R15: ffff8803f1b8b000
[ 48.781845] FS: 0000000000000000(0000) GS:ffff88041ec80000(0000) knlGS:0000000000000000
[ 48.782727] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 48.783533] CR2: 000000000000003c CR3: 00000003f19fa001 CR4: 00000000001606e0
[ 48.784348] Call Trace:
[ 48.785160] <IRQ>
[ 48.786004] ebt_do_table+0x3b/0x6ca [ebtables]
[ 48.786900] ? dequeue_rt_stack+0x4c/0x290
[ 48.787792] ? enqueue_task_rt+0x1da/0x300
[ 48.789001] nf_hook_slow+0x37/0xb0
[ 48.790662] br_pass_frame_up+0xbe/0xd0 [bridge]
[ 48.792328] ? __br_handle_local_finish+0x40/0x40 [bridge]
[ 48.794011] br_handle_frame_finish+0x21f/0x4b0 [bridge]
[ 48.795688] ? __udp4_lib_lookup+0x187/0x360
[ 48.797368] br_handle_frame+0x149/0x2b0 [bridge]
[ 48.799054] ? udp4_lib_lookup_skb+0x78/0x90
[ 48.800737] ? br_handle_local_finish+0x40/0x40 [bridge]
[ 48.802424] __netif_receive_skb_core+0x244/0xa40
[ 48.804107] ? inet_gro_receive+0x20c/0x2a0
[ 48.805870] netif_receive_skb_internal+0x8a/0xb0
[ 48.807627] napi_gro_receive+0xbc/0xe0
[ 48.809381] rtl8169_poll+0x189/0x660 [r8169]
[ 48.811139] net_rx_action+0x26e/0x3a0
[ 48.812869] __do_softirq+0xc8/0x26b
[ 48.814704] irq_exit+0xc7/0xd0
[ 48.816633] do_IRQ+0x4c/0xd0
[ 48.818554] common_interrupt+0x96/0x96
[ 48.820471] </IRQ>
[ 48.822381] RIP: 0010:cpuidle_enter_state+0xe8/0x270
[ 48.824296] RSP: 0018:ffffc9000008bec8 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff6d
[ 48.826243] RAX: ffff88041ec99800 RBX: ffff88041eca0800 RCX: 000000000000001f
[ 48.828195] RDX: 0000000000000000 RSI: fffffffdbfeaa3d2 RDI: 0000000000000000
[ 48.830156] RBP: 0000000000000001 R08: 0000000000000006 R09: 0000000000000001
[ 48.832096] R10: 0000000000000002 R11: 0000000000000006 R12: 0000000000000002
[ 48.834018] R13: 0000000000000000 R14: 0000000b585e3b60 R15: 0000000b5893f5ee
[ 48.835946] ? cpuidle_enter_state+0xc3/0x270
[ 48.837869] do_idle+0x170/0x1d0
[ 48.839779] cpu_startup_entry+0x19/0x20
[ 48.841697] start_secondary+0x103/0x130
[ 48.843611] secondary_startup_64+0xa5/0xa5
[ 48.845524] Code: f0 0f c1 07 8d b0 00 01 00 00 40 84 f6 75 02 f3 c3 e9 f0 14 b0 ff 0f 1f 44 00 00 65 81 05 e8 b8 a6 7e 00 02 00 00 b8 00 01 00 00 <f0> 0f c1 07 8d b0 00 01 00 00 40 84 f6 75 02 f3 c3 e9 c5 14 b0
[ 48.847593] RIP: _raw_read_lock_bh+0x15/0x30 RSP: ffff88041ec83bd0
[ 48.849636] CR2: 000000000000003c
[-- Attachment #2: config.xz --]
[-- Type: application/x-xz, Size: 28044 bytes --]
^ permalink raw reply
* Re: ipset losing entries on its own
From: Akshat Kakkar @ 2017-09-07 5:17 UTC (permalink / raw)
To: Denys Fedoryshchenko; +Cc: netdev, netdev-owner
In-Reply-To: <CAA5aLPgUcrUpqJJ8stu1543LBy0qekgQDuJyokqLPP0TirySgg@mail.gmail.com>
What I observed is rehashing of set is not happening.
When I add multiple IPs to the ipset manually on ipset v6.32,
rehashing is not happening and my hashsize remains same as 1024
but when I add to ipset 4.5 (pretty old, I know!), rehashing is
happening and my hashsize changes from 1024 to 1536 to 2304 to 3456!
^ permalink raw reply
* [LPC] 2nd RDMA Mini-Summit Schedule
From: Leon Romanovsky @ 2017-09-07 5:18 UTC (permalink / raw)
To: RDMA mailing list
Cc: linux-netdev, NVME mailing list, Jason Gunthorpe, Bart Van Assche,
Knut Omang, Christoph Lameter, Don Dutile, Liran Liss, Tzahi Oved,
Matan Barak, Dennis Dalessandro, Yuval Shaia, Marcel Apfelbaum,
lwn-T1hC0tSOHrs
[-- Attachment #1: Type: text/plain, Size: 2686 bytes --]
Hi,
We're happy to announce schedule of the 2nd RDMA mini-summit, which will be
held as part of coming Linux Plumbers Conference 2017.
During the conference, we will have two sessions: main track session and
round table session.
First session will be held on Thursday, September 14, 2017 from 9:30am – 12:30pm
with the topics relevant for the wider audience.
In the second session, we will focus on more face to face discussions in round
table format and it will be scheduled a little bit later once we will get meeting
room.
---------------------------------------------------------------------------------------
FIRST SESSION:
---------------------------------------------------------------------------------------
* Backporting issues with multi-subsystem device (RDMA + netdev + more) by Don Dutile
- More and more devices in RDMA are dependent on netdev as well as other
subsystems -- target, NFS, scsi, block, cgroups, SELinux.... Can we make
backporting task for distro people easier?
* kABI Update by Matan Barak
- Going forward with a flexible and secure RDMA kABI
* System Boot and RDMA by Jason Gunthrope
- Discuss boot-time issues with the RDMA subsystem
* Paravirtual RDMA device by Marcel Apfelbaum and Yuval Shaia
- QEMU's limited RDMA support leaves it behind other modern hypervisors.
Marcel and Yuval will present the implementation of an emulated RDMA device,
analyze its performance and usability, and finally talk about future plans
for a possible virtio-rdma device.
* TX Flow Steering for IPsec by Liran Liss (pending time slot)
- The IPsec protocol provides both encryption and authentication for IP
protocol packets. Users of the raw ethernet QP that send/receive IPsec packets
could benefit from the IPsec crypto offloads capabilities that are
available in recent NICs.
* OpenFabrics Alliance - Status and New Directions by Jason Gunthrope
* BOF - Open Discussion
- Open discussion with the community lead by Leon Romanovsky, Jason Gunthorpe,
Christoph Lameter and Dennis Dalessandro
---------------------------------------------------------------------------------------
ROUND TABLE SESSION:
---------------------------------------------------------------------------------------
Possible list, bring your own topics:
* RDMA and ULPs
* Verbs testing suite
* RDMA netlink and RDMAtool future plans
* RDMA and the Linux IP stack
* Infrastructure issues with Travis CI
* Infrastructure gaps with rdma-core
* Packaging as part of CI for rdma-core.
* ....
See you next week at Linux Plumber Conference 2017.
Thanks
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [RFC net-next 0/5] TSN: Add qdisc-based config interfaces for traffic shapers
From: Henrik Austad @ 2017-09-07 5:34 UTC (permalink / raw)
To: Vinicius Costa Gomes
Cc: netdev, jhs, xiyou.wangcong, jiri, intel-wired-lan, andre.guedes,
ivan.briano, jesus.sanchez-palencia, boon.leong.ong,
richardcochran
In-Reply-To: <20170901012625.14838-1-vinicius.gomes@intel.com>
[-- Attachment #1: Type: text/plain, Size: 12931 bytes --]
On Thu, Aug 31, 2017 at 06:26:20PM -0700, Vinicius Costa Gomes wrote:
> Hi,
>
> This patchset is an RFC on a proposal of how the Traffic Control subsystem can
> be used to offload the configuration of traffic shapers into network devices
> that provide support for them in HW. Our goal here is to start upstreaming
> support for features related to the Time-Sensitive Networking (TSN) set of
> standards into the kernel.
Nice to see that others are working on this as well! :)
A short disclaimer; I'm pretty much anchored in the view "linux is the
end-station in a TSN domain", is this your approach as well, or are you
looking at this driver to be used in bridges as well? (because that will
affect the comments on time-aware shaper and frame preemption)
Yet another disclaimer; I am not a linux networking subsystem expert. Not
by a long shot! There are black magic happening in the internals of the
networking subsystem that I am not even aware of. So if something I say or
ask does not make sense _at_all_, that's probably why..
I do know a tiny bit about TSN though, and I have been messing around
with it for a little while, hence my comments below
> As part of this work, we've assessed previous public discussions related to TSN
> enabling: patches from Henrik Austad (Cisco), the presentation from Eric Mann
> at Linux Plumbers 2012, patches from Gangfeng Huang (National Instruments) and
> the current state of the OpenAVNU project (https://github.com/AVnu/OpenAvnu/).
/me eyes Cc ;p
> Overview
> ========
>
> Time-sensitive Networking (TSN) is a set of standards that aim to address
> resources availability for providing bandwidth reservation and bounded latency
> on Ethernet based LANs. The proposal described here aims to cover mainly what is
> needed to enable the following standards: 802.1Qat, 802.1Qav, 802.1Qbv and
> 802.1Qbu.
>
> The initial target of this work is the Intel i210 NIC, but other controllers'
> datasheet were also taken into account, like the Renesas RZ/A1H RZ/A1M group and
> the Synopsis DesignWare Ethernet QoS controller.
NXP has a TSN aware chip on the i.MX7 sabre board as well </fyi>
> Proposal
> ========
>
> Feature-wise, what is covered here are configuration interfaces for HW
> implementations of the Credit-Based shaper (CBS, 802.1Qav), Time-Aware shaper
> (802.1Qbv) and Frame Preemption (802.1Qbu). CBS is a per-queue shaper, while
> Qbv and Qbu must be configured per port, with the configuration covering all
> queues. Given that these features are related to traffic shaping, and that the
> traffic control subsystem already provides a queueing discipline that offloads
> config into the device driver (i.e. mqprio), designing new qdiscs for the
> specific purpose of offloading the config for each shaper seemed like a good
> fit.
just to be clear, you register sch_cbs as a subclass to mqprio, not as a
root class?
> For steering traffic into the correct queues, we use the socket option
> SO_PRIORITY and then a mechanism to map priority to traffic classes / Tx queues.
> The qdisc mqprio is currently used in our tests.
Right, fair enough, I'd prefer the TSN qdisc to be the root-device and
rather have mqprio for high priority traffic and another for 'everything
else'', but this would work too. This is not that relevant at this stage I
guess :)
> As for the shapers config interface:
>
> * CBS (802.1Qav)
>
> This patchset is proposing a new qdisc called 'cbs'. Its 'tc' cmd line is:
> $ tc qdisc add dev IFACE parent ID cbs locredit N hicredit M sendslope S \
> idleslope I
So this confuses me a bit, why specify sendSlope?
sendSlope = portTransmitRate - idleSlope
and portTransmitRate is the speed of the MAC (which you get from the
driver). Adding sendSlope here is just redundant I think.
Also, does this mean that when you create the qdisc, you have locked the
bandwidth for the scheduler? Meaning, if I later want to add another
stream that requires more bandwidth, I have to close all active streams,
reconfigure the qdisc and then restart?
> Note that the parameters for this qdisc are the ones defined by the
> 802.1Q-2014 spec, so no hardware specific functionality is exposed here.
You do need to know if the link is brought up as 100 or 1000 though - which
the driver already knows.
> * Time-aware shaper (802.1Qbv):
>
> The idea we are currently exploring is to add a "time-aware", priority based
> qdisc, that also exposes the Tx queues available and provides a mechanism for
> mapping priority <-> traffic class <-> Tx queues in a similar fashion as
> mqprio. We are calling this qdisc 'taprio', and its 'tc' cmd line would be:
As far as I know, this is not supported by i210, and if time-aware shaping
is enabled in the network - you'll be queued on a bridge until the window
opens as time-aware shaping is enforced on the tx-port and not on rx. Is
this required in this driver?
> $ $ tc qdisc add dev ens4 parent root handle 100 taprio num_tc 4 \
> map 2 2 1 0 3 3 3 3 3 3 3 3 3 3 3 3 \
> queues 0 1 2 3 \
> sched-file gates.sched [base-time <interval>] \
> [cycle-time <interval>] [extension-time <interval>]
That was a lot of priorities! 802.1Q lists 8 priorities, where does these
16 come from?
You map pri 0,1 to queue 2, pri 2 to queue 1 (Class B), pri 3 to queue 0
(class A) and everythign else to queue 3. This is what I would expect,
except for the additional 8 priorities.
> <file> is multi-line, with each line being of the following format:
> <cmd> <gate mask> <interval in nanoseconds>
>
> Qbv only defines one <cmd>: "S" for 'SetGates'
>
> For example:
>
> S 0x01 300
> S 0x03 500
>
> This means that there are two intervals, the first will have the gate
> for traffic class 0 open for 300 nanoseconds, the second will have
> both traffic classes open for 500 nanoseconds.
Are you aware of any hw except dedicated switching stuff that supports
this? (meant as "I'm curious and would like to know")
> Additionally, an option to set just one entry of the gate control list will
> also be provided by 'taprio':
>
> $ tc qdisc (...) \
> sched-row <row number> <cmd> <gate mask> <interval> \
> [base-time <interval>] [cycle-time <interval>] \
> [extension-time <interval>]
>
>
> * Frame Preemption (802.1Qbu):
So Frame preemption is nice, but my understanding of Qbu is that the real
benefit is at the bridges and not in the endpoints. As jumbo-frames is
explicitly disallowed in Qav, the maximum latency incurred by a frame in
flight is 12us on a 1Gbps link. I am not sure if these 12us is what will be
the main delay in your application.
Or have I missed some crucial point here?
> To control even further the latency, it may prove useful to signal which
> traffic classes are marked as preemptable. For that, 'taprio' provides the
> preemption command so you set each traffic class as preemptable or not:
>
> $ tc qdisc (...) \
> preemption 0 1 1 1
>
> * Time-aware shaper + Preemption:
>
> As an example of how Qbv and Qbu can be used together, we may specify
> both the schedule and the preempt-mask, and this way we may also
> specify the Set-Gates-and-Hold and Set-Gates-and-Release commands as
> specified in the Qbu spec:
>
> $ tc qdisc add dev ens4 parent root handle 100 taprio num_tc 4 \
> map 2 2 1 0 3 3 3 3 3 3 3 3 3 3 3 3 \
> queues 0 1 2 3 \
> preemption 0 1 1 1 \
> sched-file preempt_gates.sched
>
> <file> is multi-line, with each line being of the following format:
> <cmd> <gate mask> <interval in nanoseconds>
>
> For this case, two new commands are introduced:
>
> "H" for 'set gates and hold'
> "R" for 'set gates and release'
>
> H 0x01 300
> R 0x03 500
So my understanding of all of this is that you configure the *total*
bandwith for each class when you load the qdisc and then let userspace
handle the rest. Is this correct?
In my view, it would be nice if the qdisc had some notion about streams so
that you could create a stream, feed frames to it and let the driver pace
them out. (The fewer you queue, the shorter the delay). This will also
allow you to enforce per-stream bandwidth restrictions. I don't see how you
can do this here unless you want to do this in userspace.
Do you have any plans for adding support for multiplexing streams? If you
have multiple streams, how do you enforce that one stream does not eat into
the bandwidth of another stream? AFAIK, this is something the network must
enforce, but I see no option of doing som here.
> Testing this RFC
> ================
>
> For testing the patches of this RFC only, you can refer to the samples and
> helper script being added to samples/tsn/ and the use the 'mqprio' qdisc to
> setup the priorities to Tx queues mapping, together with the 'cbs' qdisc to
> configure the HW shaper of the i210 controller:
I will test it, feedback will be provided soon! :)
Thanks!
-Henrik
> 1) Setup priorities to traffic classes to hardware queues mapping
> $ tc qdisc replace dev enp3s0 parent root mqprio num_tc 3 \
> map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 queues 1@0 1@1 2@2 hw 0
>
> 2) Check scheme. You want to get the inner qdiscs ID from the bottom up
> $ tc -g class show dev enp3s0
>
> Ex.:
> +---(802a:3) mqprio
> | +---(802a:6) mqprio
> | +---(802a:7) mqprio
> |
> +---(802a:2) mqprio
> | +---(802a:5) mqprio
> |
> +---(802a:1) mqprio
> +---(802a:4) mqprio
>
> * Here '802a:4' is Tx Queue #0 and '802a:5' is Tx Queue #1.
>
> 3) Calculate CBS parameters for classes A and B. i.e. BW for A is 20Mbps and
> for B is 10Mbps:
> $ ./samples/tsn/calculate_cbs_params.py -A 20000 -a 1500 -B 10000 -b 1500
>
> 4) Configure CBS for traffic class A (priority 3) as provided by the script:
> $ tc qdisc replace dev enp3s0 parent 802a:4 cbs locredit -1470 \
> hicredit 30 sendslope -980000 idleslope 20000
>
> 5) Configure CBS for traffic class B (priority 2):
> $ tc qdisc replace dev enp3s0 parent 802a:5 cbs \
> locredit -1485 hicredit 31 sendslope -990000 idleslope 10000
>
> 6) Run Listener, compiled from samples/tsn/listener.c
> $ ./listener -i enp3s0
>
> 7) Run Talker for class A (prio 3 here), compiled from samples/tsn/talker.c
> $ ./talker -i enp3s0 -p 3
>
> * The bandwidth displayed on the listener output at this stage should be very
> close to the one configured for class A.
>
> 8) You can also run a Talker for class B (prio 2 here)
> $ ./talker -i enp3s0 -p 2
>
> * The bandwidth displayed on the listener output now should increase to very
> close to the one configured for class A + class B.
Because you grab both class A *and* B, or because B will eat what A does
not use?
-H
> Authors
> =======
> - Andre Guedes <andre.guedes@intel.com>
> - Ivan Briano <ivan.briano@intel.com>
> - Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
> - Vinicius Gomes <vinicius.gomes@intel.com>
>
>
> Andre Guedes (2):
> igb: Add support for CBS offload
> samples/tsn: Add script for calculating CBS config
>
> Jesus Sanchez-Palencia (1):
> sample: Add TSN Talker and Listener examples
>
> Vinicius Costa Gomes (2):
> net/sched: Introduce the user API for the CBS shaper
> net/sched: Introduce Credit Based Shaper (CBS) qdisc
>
> drivers/net/ethernet/intel/igb/e1000_defines.h | 23 ++
> drivers/net/ethernet/intel/igb/e1000_regs.h | 8 +
> drivers/net/ethernet/intel/igb/igb.h | 6 +
> drivers/net/ethernet/intel/igb/igb_main.c | 349 +++++++++++++++++++++++++
> include/linux/netdevice.h | 1 +
> include/uapi/linux/pkt_sched.h | 29 ++
> net/sched/Kconfig | 11 +
> net/sched/Makefile | 1 +
> net/sched/sch_cbs.c | 286 ++++++++++++++++++++
> samples/tsn/calculate_cbs_params.py | 112 ++++++++
> samples/tsn/listener.c | 254 ++++++++++++++++++
> samples/tsn/talker.c | 136 ++++++++++
> 12 files changed, 1216 insertions(+)
> create mode 100644 net/sched/sch_cbs.c
> create mode 100755 samples/tsn/calculate_cbs_params.py
> create mode 100644 samples/tsn/listener.c
> create mode 100644 samples/tsn/talker.c
>
> --
> 2.14.1
--
Henrik Austad
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply
* Re: [GIT] Networking
From: Luca Coelho @ 2017-09-07 5:40 UTC (permalink / raw)
To: torvalds@linux-foundation.org
Cc: linux-kernel@vger.kernel.org, linuxwifi, Berg, Johannes,
akpm@linux-foundation.org, kvalo@codeaurora.org,
netdev@vger.kernel.org, davem@davemloft.net,
linux-wireless@vger.kernel.org, Grumbach, Emmanuel
In-Reply-To: <1504760688.5400.91.camel@intel.com>
On Thu, 2017-09-07 at 05:04 +0000, Coelho, Luciano wrote:
> On Wed, 2017-09-06 at 21:57 -0700, Linus Torvalds wrote:
> > On Wed, Sep 6, 2017 at 9:11 PM, Coelho, Luciano
> > <luciano.coelho@intel.com> wrote:
> > >
> > > This seems to be a problem with backwards-compatibility with FW version
> > > 27. We are now in version 31[1] and upgrading will probably fix that.
> >
> > I can confirm that fw version 31 works.
>
> Great, so I know for sure that this is a backwards-compatibility issue
> with the FW API.
>
>
> > > But obviously the driver should not fail miserably like this with
> > > version 27, because it claims to support it still.
> >
> > Not just "claims to support it", but if it's what is shipped with a
> > fairly recent distro like an up-to-date version of F26, I would really
> > hope that the driver can still work with it.
>
> I totally agree, we support a bunch of older versions for that exact
> reason. We just don't really test all the supported versions very
> often. We should probably change that.
>
> I'll make sure it still works with version 27.
Okay, I found the offending patch:
commit 7089ae634c50544b29b31faf1a751e8765c8de3b
Author: Johannes Berg <johannes.berg@intel.com>
AuthorDate: Wed Jun 28 16:19:49 2017 +0200
Commit: Luca Coelho <luciano.coelho@intel.com>
CommitDate: Wed Aug 9 09:15:32 2017 +0300
iwlwifi: mvm: use firmware LED command where applicable
On devices starting from 8000 series, the host can no longer toggle
the LED through the CSR_LED_REG register, but must do it via the
firmware instead. Add support for this. Note that this means that
the LED cannot be turned on while the firmware is off, so using an
arbitrary LED trigger may not work as expected.
Fixes: 503ab8c56ca0 ("iwlwifi: Add 8000 HW family support")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Reverting it solves the problem. We introduced a new command to control
the LED lights and assumed it was available in older FW versions as
well, which turned out not to be the case.
This patch is not very important (unless you really like blinking lights
-- maybe I'll change my mind when the holidays approach :P). so it is
fine if you just want to revert it for now.
In any case, I'll send a patch fixing this problem soon.
--
Cheers,
Luca.
^ permalink raw reply
* Re: [GIT] Networking
From: Linus Torvalds @ 2017-09-07 5:46 UTC (permalink / raw)
To: Luca Coelho
Cc: linux-kernel@vger.kernel.org, linuxwifi, Berg, Johannes,
akpm@linux-foundation.org, kvalo@codeaurora.org,
netdev@vger.kernel.org, davem@davemloft.net,
linux-wireless@vger.kernel.org, Grumbach, Emmanuel
In-Reply-To: <1504762851.5400.93.camel@coelho.fi>
On Wed, Sep 6, 2017 at 10:40 PM, Luca Coelho <luca@coelho.fi> wrote:
>
> This patch is not very important (unless you really like blinking lights
> -- maybe I'll change my mind when the holidays approach :P). so it is
> fine if you just want to revert it for now.
>
> In any case, I'll send a patch fixing this problem soon.
No need to revert if we can get this fixed quickly enough.
I'll leave the fw-31 on my laptop, so that I can continue to use it for now.
Thanks,
Linus
^ permalink raw reply
* [PATCH 0/7] net: qrtr: Fixes and support receiving version 2 packets
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
On the latest Qualcomm platforms remote processors are sending packets with
version 2 of the message header. This series starts off with some fixes and
then refactors the qrtr code to support receiving messages of both version 1
and version 2.
As all remotes are backwards compatible transmitted packets continues to be
send as version 1, but some groundwork has been done to make this a per-link
property.
Bjorn Andersson (7):
net: qrtr: Invoke sk_error_report() after setting sk_err
net: qrtr: Move constants to header file
net: qrtr: Add control packet definition to uapi
net: qrtr: Pass source and destination to enqueue functions
net: qrtr: Clean up control packet handling
net: qrtr: Use sk_buff->cb in receive path
net: qrtr: Support decoding incoming v2 packets
include/uapi/linux/qrtr.h | 35 +++++
net/qrtr/qrtr.c | 377 +++++++++++++++++++++++++---------------------
2 files changed, 241 insertions(+), 171 deletions(-)
--
2.12.0
^ permalink raw reply
* [PATCH 3/7] net: qrtr: Add control packet definition to uapi
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org>
The QMUX protocol specification defines structure of the special control
packet messages being sent between handlers of the control port.
Add these to the uapi header, as this structure and the associated types
are shared between the kernel and all userspace handlers of control
messages.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
include/uapi/linux/qrtr.h | 32 ++++++++++++++++++++++++++++++++
net/qrtr/qrtr.c | 12 ------------
2 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/include/uapi/linux/qrtr.h b/include/uapi/linux/qrtr.h
index 63e8803e4d90..179af64846e0 100644
--- a/include/uapi/linux/qrtr.h
+++ b/include/uapi/linux/qrtr.h
@@ -13,4 +13,36 @@ struct sockaddr_qrtr {
__u32 sq_port;
};
+enum qrtr_pkt_type {
+ QRTR_TYPE_DATA = 1,
+ QRTR_TYPE_HELLO = 2,
+ QRTR_TYPE_BYE = 3,
+ QRTR_TYPE_NEW_SERVER = 4,
+ QRTR_TYPE_DEL_SERVER = 5,
+ QRTR_TYPE_DEL_CLIENT = 6,
+ QRTR_TYPE_RESUME_TX = 7,
+ QRTR_TYPE_EXIT = 8,
+ QRTR_TYPE_PING = 9,
+ QRTR_TYPE_NEW_LOOKUP = 10,
+ QRTR_TYPE_DEL_LOOKUP = 11,
+};
+
+struct qrtr_ctrl_pkt {
+ __le32 cmd;
+
+ union {
+ struct {
+ __le32 service;
+ __le32 instance;
+ __le32 node;
+ __le32 port;
+ } server;
+
+ struct {
+ __le32 node;
+ __le32 port;
+ } client;
+ };
+} __packed;
+
#endif /* _LINUX_QRTR_H */
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 0d7d3968414e..fac7cd6ea445 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -26,18 +26,6 @@
#define QRTR_MIN_EPH_SOCKET 0x4000
#define QRTR_MAX_EPH_SOCKET 0x7fff
-enum qrtr_pkt_type {
- QRTR_TYPE_DATA = 1,
- QRTR_TYPE_HELLO = 2,
- QRTR_TYPE_BYE = 3,
- QRTR_TYPE_NEW_SERVER = 4,
- QRTR_TYPE_DEL_SERVER = 5,
- QRTR_TYPE_DEL_CLIENT = 6,
- QRTR_TYPE_RESUME_TX = 7,
- QRTR_TYPE_EXIT = 8,
- QRTR_TYPE_PING = 9,
-};
-
/**
* struct qrtr_hdr - (I|R)PCrouter packet header
* @version: protocol version
--
2.12.0
^ permalink raw reply related
* [PATCH 4/7] net: qrtr: Pass source and destination to enqueue functions
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org>
Defer writing the message header to the skb until its time to enqueue
the packet. As the receive path is reworked to decode the message header
as it's received from the transport and only pass around the payload in
the skb this change means that we do not have to fill out the full
message header just to decode it immediately in qrtr_local_enqueue().
In the future this change also makes it possible to prepend message
headers based on the version of each link.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
net/qrtr/qrtr.c | 120 ++++++++++++++++++++++++++++++++------------------------
1 file changed, 69 insertions(+), 51 deletions(-)
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index fac7cd6ea445..bcec2432b833 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -97,8 +97,12 @@ struct qrtr_node {
struct list_head item;
};
-static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb);
-static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb);
+static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
+ int type, struct sockaddr_qrtr *from,
+ struct sockaddr_qrtr *to);
+static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,
+ int type, struct sockaddr_qrtr *from,
+ struct sockaddr_qrtr *to);
/* Release node resources and free the node.
*
@@ -136,10 +140,27 @@ static void qrtr_node_release(struct qrtr_node *node)
}
/* Pass an outgoing packet socket buffer to the endpoint driver. */
-static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb)
+static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
+ int type, struct sockaddr_qrtr *from,
+ struct sockaddr_qrtr *to)
{
+ struct qrtr_hdr *hdr;
+ size_t len = skb->len;
int rc = -ENODEV;
+ hdr = skb_push(skb, QRTR_HDR_SIZE);
+ hdr->version = cpu_to_le32(QRTR_PROTO_VER);
+ hdr->type = cpu_to_le32(type);
+ hdr->src_node_id = cpu_to_le32(from->sq_node);
+ hdr->src_port_id = cpu_to_le32(from->sq_port);
+ hdr->dst_node_id = cpu_to_le32(to->sq_node);
+ hdr->dst_port_id = cpu_to_le32(to->sq_port);
+
+ hdr->size = cpu_to_le32(len);
+ hdr->confirm_rx = 0;
+
+ skb_put_padto(skb, ALIGN(len, 4));
+
mutex_lock(&node->ep_lock);
if (node->ep)
rc = node->ep->xmit(node->ep, skb);
@@ -237,23 +258,13 @@ EXPORT_SYMBOL_GPL(qrtr_endpoint_post);
static struct sk_buff *qrtr_alloc_ctrl_packet(u32 type, size_t pkt_len,
u32 src_node, u32 dst_node)
{
- struct qrtr_hdr *hdr;
struct sk_buff *skb;
skb = alloc_skb(QRTR_HDR_SIZE + pkt_len, GFP_KERNEL);
if (!skb)
return NULL;
- skb_reset_transport_header(skb);
- hdr = skb_put(skb, QRTR_HDR_SIZE);
- hdr->version = cpu_to_le32(QRTR_PROTO_VER);
- hdr->type = cpu_to_le32(type);
- hdr->src_node_id = cpu_to_le32(src_node);
- hdr->src_port_id = cpu_to_le32(QRTR_PORT_CTRL);
- hdr->confirm_rx = cpu_to_le32(0);
- hdr->size = cpu_to_le32(pkt_len);
- hdr->dst_node_id = cpu_to_le32(dst_node);
- hdr->dst_port_id = cpu_to_le32(QRTR_PORT_CTRL);
+ skb_reserve(skb, QRTR_HDR_SIZE);
return skb;
}
@@ -326,6 +337,8 @@ static void qrtr_port_put(struct qrtr_sock *ipc);
static void qrtr_node_rx_work(struct work_struct *work)
{
struct qrtr_node *node = container_of(work, struct qrtr_node, work);
+ struct sockaddr_qrtr dst;
+ struct sockaddr_qrtr src;
struct sk_buff *skb;
while ((skb = skb_dequeue(&node->rx_queue)) != NULL) {
@@ -341,6 +354,11 @@ static void qrtr_node_rx_work(struct work_struct *work)
dst_port = le32_to_cpu(phdr->dst_port_id);
confirm = !!phdr->confirm_rx;
+ src.sq_node = src_node;
+ src.sq_port = le32_to_cpu(phdr->src_port_id);
+ dst.sq_node = dst_node;
+ dst.sq_port = dst_port;
+
qrtr_node_assign(node, src_node);
ipc = qrtr_port_lookup(dst_port);
@@ -357,7 +375,9 @@ static void qrtr_node_rx_work(struct work_struct *work)
skb = qrtr_alloc_resume_tx(dst_node, node->nid, dst_port);
if (!skb)
break;
- if (qrtr_node_enqueue(node, skb))
+
+ if (qrtr_node_enqueue(node, skb, QRTR_TYPE_RESUME_TX,
+ &dst, &src))
break;
}
}
@@ -407,6 +427,8 @@ EXPORT_SYMBOL_GPL(qrtr_endpoint_register);
void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
{
struct qrtr_node *node = ep->node;
+ struct sockaddr_qrtr src = {AF_QIPCRTR, node->nid, QRTR_PORT_CTRL};
+ struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL};
struct sk_buff *skb;
mutex_lock(&node->ep_lock);
@@ -416,7 +438,7 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
/* Notify the local controller about the event */
skb = qrtr_alloc_local_bye(node->nid);
if (skb)
- qrtr_local_enqueue(NULL, skb);
+ qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst);
qrtr_node_release(node);
ep->node = NULL;
@@ -454,11 +476,17 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
{
struct sk_buff *skb;
int port = ipc->us.sq_port;
+ struct sockaddr_qrtr to;
+
+ to.sq_family = AF_QIPCRTR;
+ to.sq_node = QRTR_NODE_BCAST;
+ to.sq_port = QRTR_PORT_CTRL;
skb = qrtr_alloc_del_client(&ipc->us);
if (skb) {
skb_set_owner_w(skb, &ipc->sk);
- qrtr_bcast_enqueue(NULL, skb);
+ qrtr_bcast_enqueue(NULL, skb, QRTR_TYPE_DEL_CLIENT, &ipc->us,
+ &to);
}
if (port == QRTR_PORT_CTRL)
@@ -606,19 +634,25 @@ static int qrtr_bind(struct socket *sock, struct sockaddr *saddr, int len)
}
/* Queue packet to local peer socket. */
-static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb)
+static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
+ int type, struct sockaddr_qrtr *from,
+ struct sockaddr_qrtr *to)
{
- const struct qrtr_hdr *phdr;
struct qrtr_sock *ipc;
+ struct qrtr_hdr *phdr;
- phdr = (const struct qrtr_hdr *)skb_transport_header(skb);
-
- ipc = qrtr_port_lookup(le32_to_cpu(phdr->dst_port_id));
+ ipc = qrtr_port_lookup(to->sq_port);
if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */
kfree_skb(skb);
return -ENODEV;
}
+ phdr = skb_push(skb, QRTR_HDR_SIZE);
+ skb_reset_transport_header(skb);
+
+ phdr->src_node_id = cpu_to_le32(from->sq_node);
+ phdr->src_port_id = cpu_to_le32(from->sq_port);
+
if (sock_queue_rcv_skb(&ipc->sk, skb)) {
qrtr_port_put(ipc);
kfree_skb(skb);
@@ -631,7 +665,9 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb)
}
/* Queue packet for broadcast. */
-static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb)
+static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,
+ int type, struct sockaddr_qrtr *from,
+ struct sockaddr_qrtr *to)
{
struct sk_buff *skbn;
@@ -641,11 +677,11 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb)
if (!skbn)
break;
skb_set_owner_w(skbn, skb->sk);
- qrtr_node_enqueue(node, skbn);
+ qrtr_node_enqueue(node, skbn, type, from, to);
}
mutex_unlock(&qrtr_node_lock);
- qrtr_local_enqueue(node, skb);
+ qrtr_local_enqueue(node, skb, type, from, to);
return 0;
}
@@ -653,13 +689,14 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb)
static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
{
DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name);
- int (*enqueue_fn)(struct qrtr_node *, struct sk_buff *);
+ int (*enqueue_fn)(struct qrtr_node *, struct sk_buff *, int,
+ struct sockaddr_qrtr *, struct sockaddr_qrtr *);
struct qrtr_sock *ipc = qrtr_sk(sock->sk);
struct sock *sk = sock->sk;
struct qrtr_node *node;
- struct qrtr_hdr *hdr;
struct sk_buff *skb;
size_t plen;
+ u32 type = QRTR_TYPE_DATA;
int rc;
if (msg->msg_flags & ~(MSG_DONTWAIT))
@@ -713,32 +750,14 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
if (!skb)
goto out_node;
- skb_reset_transport_header(skb);
- skb_put(skb, len + QRTR_HDR_SIZE);
-
- hdr = (struct qrtr_hdr *)skb_transport_header(skb);
- hdr->version = cpu_to_le32(QRTR_PROTO_VER);
- hdr->src_node_id = cpu_to_le32(ipc->us.sq_node);
- hdr->src_port_id = cpu_to_le32(ipc->us.sq_port);
- hdr->confirm_rx = cpu_to_le32(0);
- hdr->size = cpu_to_le32(len);
- hdr->dst_node_id = cpu_to_le32(addr->sq_node);
- hdr->dst_port_id = cpu_to_le32(addr->sq_port);
+ skb_reserve(skb, QRTR_HDR_SIZE);
- rc = skb_copy_datagram_from_iter(skb, QRTR_HDR_SIZE,
- &msg->msg_iter, len);
+ rc = memcpy_from_msg(skb_put(skb, len), msg, len);
if (rc) {
kfree_skb(skb);
goto out_node;
}
- if (plen != len) {
- rc = skb_pad(skb, plen - len);
- if (rc)
- goto out_node;
- skb_put(skb, plen - len);
- }
-
if (ipc->us.sq_port == QRTR_PORT_CTRL) {
if (len < 4) {
rc = -EINVAL;
@@ -747,12 +766,11 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
}
/* control messages already require the type as 'command' */
- skb_copy_bits(skb, QRTR_HDR_SIZE, &hdr->type, 4);
- } else {
- hdr->type = cpu_to_le32(QRTR_TYPE_DATA);
+ skb_copy_bits(skb, 0, &type, 4);
+ type = le32_to_cpu(type);
}
- rc = enqueue_fn(node, skb);
+ rc = enqueue_fn(node, skb, type, &ipc->us, addr);
if (rc >= 0)
rc = len;
--
2.12.0
^ permalink raw reply related
* [PATCH 5/7] net: qrtr: Clean up control packet handling
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org>
As the message header generation is deferred the internal functions for
generating control packets can be simplified.
This patch modifies qrtr_alloc_ctrl_packet() to, in addition to the
sk_buff, return a reference to a struct qrtr_ctrl_pkt, which clarifies
and simplifies the helpers to the point that these functions can be
folded back into the callers.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
net/qrtr/qrtr.c | 93 ++++++++++++++++++---------------------------------------
1 file changed, 29 insertions(+), 64 deletions(-)
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index bcec2432b833..f28ecd7d735b 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -255,9 +255,18 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
}
EXPORT_SYMBOL_GPL(qrtr_endpoint_post);
-static struct sk_buff *qrtr_alloc_ctrl_packet(u32 type, size_t pkt_len,
- u32 src_node, u32 dst_node)
+/**
+ * qrtr_alloc_ctrl_packet() - allocate control packet skb
+ * @pkt: reference to qrtr_ctrl_pkt pointer
+ *
+ * Returns newly allocated sk_buff, or NULL on failure
+ *
+ * This function allocates a sk_buff large enough to carry a qrtr_ctrl_pkt and
+ * on success returns a reference to the control packet in @pkt.
+ */
+static struct sk_buff *qrtr_alloc_ctrl_packet(struct qrtr_ctrl_pkt **pkt)
{
+ const int pkt_len = sizeof(struct qrtr_ctrl_pkt);
struct sk_buff *skb;
skb = alloc_skb(QRTR_HDR_SIZE + pkt_len, GFP_KERNEL);
@@ -265,64 +274,7 @@ static struct sk_buff *qrtr_alloc_ctrl_packet(u32 type, size_t pkt_len,
return NULL;
skb_reserve(skb, QRTR_HDR_SIZE);
-
- return skb;
-}
-
-/* Allocate and construct a resume-tx packet. */
-static struct sk_buff *qrtr_alloc_resume_tx(u32 src_node,
- u32 dst_node, u32 port)
-{
- const int pkt_len = 20;
- struct sk_buff *skb;
- __le32 *buf;
-
- skb = qrtr_alloc_ctrl_packet(QRTR_TYPE_RESUME_TX, pkt_len,
- src_node, dst_node);
- if (!skb)
- return NULL;
-
- buf = skb_put_zero(skb, pkt_len);
- buf[0] = cpu_to_le32(QRTR_TYPE_RESUME_TX);
- buf[1] = cpu_to_le32(src_node);
- buf[2] = cpu_to_le32(port);
-
- return skb;
-}
-
-/* Allocate and construct a BYE message to signal remote termination */
-static struct sk_buff *qrtr_alloc_local_bye(u32 src_node)
-{
- const int pkt_len = 20;
- struct sk_buff *skb;
- __le32 *buf;
-
- skb = qrtr_alloc_ctrl_packet(QRTR_TYPE_BYE, pkt_len,
- src_node, qrtr_local_nid);
- if (!skb)
- return NULL;
-
- buf = skb_put_zero(skb, pkt_len);
- buf[0] = cpu_to_le32(QRTR_TYPE_BYE);
-
- return skb;
-}
-
-static struct sk_buff *qrtr_alloc_del_client(struct sockaddr_qrtr *sq)
-{
- const int pkt_len = 20;
- struct sk_buff *skb;
- __le32 *buf;
-
- skb = qrtr_alloc_ctrl_packet(QRTR_TYPE_DEL_CLIENT, pkt_len,
- sq->sq_node, QRTR_NODE_BCAST);
- if (!skb)
- return NULL;
-
- buf = skb_put_zero(skb, pkt_len);
- buf[0] = cpu_to_le32(QRTR_TYPE_DEL_CLIENT);
- buf[1] = cpu_to_le32(sq->sq_node);
- buf[2] = cpu_to_le32(sq->sq_port);
+ *pkt = skb_put_zero(skb, pkt_len);
return skb;
}
@@ -337,6 +289,7 @@ static void qrtr_port_put(struct qrtr_sock *ipc);
static void qrtr_node_rx_work(struct work_struct *work)
{
struct qrtr_node *node = container_of(work, struct qrtr_node, work);
+ struct qrtr_ctrl_pkt *pkt;
struct sockaddr_qrtr dst;
struct sockaddr_qrtr src;
struct sk_buff *skb;
@@ -372,10 +325,14 @@ static void qrtr_node_rx_work(struct work_struct *work)
}
if (confirm) {
- skb = qrtr_alloc_resume_tx(dst_node, node->nid, dst_port);
+ skb = qrtr_alloc_ctrl_packet(&pkt);
if (!skb)
break;
+ pkt->cmd = cpu_to_le32(QRTR_TYPE_RESUME_TX);
+ pkt->client.node = cpu_to_le32(dst.sq_node);
+ pkt->client.port = cpu_to_le32(dst.sq_port);
+
if (qrtr_node_enqueue(node, skb, QRTR_TYPE_RESUME_TX,
&dst, &src))
break;
@@ -429,6 +386,7 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
struct qrtr_node *node = ep->node;
struct sockaddr_qrtr src = {AF_QIPCRTR, node->nid, QRTR_PORT_CTRL};
struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL};
+ struct qrtr_ctrl_pkt *pkt;
struct sk_buff *skb;
mutex_lock(&node->ep_lock);
@@ -436,9 +394,11 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
mutex_unlock(&node->ep_lock);
/* Notify the local controller about the event */
- skb = qrtr_alloc_local_bye(node->nid);
- if (skb)
+ skb = qrtr_alloc_ctrl_packet(&pkt);
+ if (skb) {
+ pkt->cmd = cpu_to_le32(QRTR_TYPE_BYE);
qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst);
+ }
qrtr_node_release(node);
ep->node = NULL;
@@ -474,6 +434,7 @@ static void qrtr_port_put(struct qrtr_sock *ipc)
/* Remove port assignment. */
static void qrtr_port_remove(struct qrtr_sock *ipc)
{
+ struct qrtr_ctrl_pkt *pkt;
struct sk_buff *skb;
int port = ipc->us.sq_port;
struct sockaddr_qrtr to;
@@ -482,8 +443,12 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
to.sq_node = QRTR_NODE_BCAST;
to.sq_port = QRTR_PORT_CTRL;
- skb = qrtr_alloc_del_client(&ipc->us);
+ skb = qrtr_alloc_ctrl_packet(&pkt);
if (skb) {
+ pkt->cmd = cpu_to_le32(QRTR_TYPE_DEL_CLIENT);
+ pkt->client.node = cpu_to_le32(ipc->us.sq_node);
+ pkt->client.port = cpu_to_le32(ipc->us.sq_port);
+
skb_set_owner_w(skb, &ipc->sk);
qrtr_bcast_enqueue(NULL, skb, QRTR_TYPE_DEL_CLIENT, &ipc->us,
&to);
--
2.12.0
^ permalink raw reply related
* [PATCH 6/7] net: qrtr: Use sk_buff->cb in receive path
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org>
Rather than parsing the header of incoming messages throughout the
implementation do it once when we retrieve the message and store the
relevant information in the "cb" member of the sk_buff.
This allows us to, in a later commit, decode version 2 messages into
this same structure.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
net/qrtr/qrtr.c | 70 ++++++++++++++++++++++++++++++++-------------------------
1 file changed, 40 insertions(+), 30 deletions(-)
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index f28ecd7d735b..5042999756ce 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -48,6 +48,16 @@ struct qrtr_hdr {
__le32 dst_port_id;
} __packed;
+struct qrtr_cb {
+ u32 src_node;
+ u32 src_port;
+ u32 dst_node;
+ u32 dst_port;
+
+ u8 type;
+ u8 confirm_rx;
+};
+
#define QRTR_HDR_SIZE sizeof(struct qrtr_hdr)
struct qrtr_sock {
@@ -216,6 +226,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
struct qrtr_node *node = ep->node;
const struct qrtr_hdr *phdr = data;
struct sk_buff *skb;
+ struct qrtr_cb *cb;
unsigned int psize;
unsigned int size;
unsigned int type;
@@ -245,8 +256,15 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
if (!skb)
return -ENOMEM;
- skb_reset_transport_header(skb);
- skb_put_data(skb, data, len);
+ cb = (struct qrtr_cb *)skb->cb;
+ cb->src_node = le32_to_cpu(phdr->src_node_id);
+ cb->src_port = le32_to_cpu(phdr->src_port_id);
+ cb->dst_node = le32_to_cpu(phdr->dst_node_id);
+ cb->dst_port = le32_to_cpu(phdr->dst_port_id);
+ cb->type = type;
+ cb->confirm_rx = !!phdr->confirm_rx;
+
+ skb_put_data(skb, data + QRTR_HDR_SIZE, size);
skb_queue_tail(&node->rx_queue, skb);
schedule_work(&node->work);
@@ -295,26 +313,20 @@ static void qrtr_node_rx_work(struct work_struct *work)
struct sk_buff *skb;
while ((skb = skb_dequeue(&node->rx_queue)) != NULL) {
- const struct qrtr_hdr *phdr;
- u32 dst_node, dst_port;
struct qrtr_sock *ipc;
- u32 src_node;
+ struct qrtr_cb *cb;
int confirm;
- phdr = (const struct qrtr_hdr *)skb_transport_header(skb);
- src_node = le32_to_cpu(phdr->src_node_id);
- dst_node = le32_to_cpu(phdr->dst_node_id);
- dst_port = le32_to_cpu(phdr->dst_port_id);
- confirm = !!phdr->confirm_rx;
+ cb = (struct qrtr_cb *)skb->cb;
+ src.sq_node = cb->src_node;
+ src.sq_port = cb->src_port;
+ dst.sq_node = cb->dst_node;
+ dst.sq_port = cb->dst_port;
+ confirm = !!cb->confirm_rx;
- src.sq_node = src_node;
- src.sq_port = le32_to_cpu(phdr->src_port_id);
- dst.sq_node = dst_node;
- dst.sq_port = dst_port;
+ qrtr_node_assign(node, cb->src_node);
- qrtr_node_assign(node, src_node);
-
- ipc = qrtr_port_lookup(dst_port);
+ ipc = qrtr_port_lookup(cb->dst_port);
if (!ipc) {
kfree_skb(skb);
} else {
@@ -604,7 +616,7 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
struct sockaddr_qrtr *to)
{
struct qrtr_sock *ipc;
- struct qrtr_hdr *phdr;
+ struct qrtr_cb *cb;
ipc = qrtr_port_lookup(to->sq_port);
if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */
@@ -612,11 +624,9 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
return -ENODEV;
}
- phdr = skb_push(skb, QRTR_HDR_SIZE);
- skb_reset_transport_header(skb);
-
- phdr->src_node_id = cpu_to_le32(from->sq_node);
- phdr->src_port_id = cpu_to_le32(from->sq_port);
+ cb = (struct qrtr_cb *)skb->cb;
+ cb->src_node = from->sq_node;
+ cb->src_port = from->sq_port;
if (sock_queue_rcv_skb(&ipc->sk, skb)) {
qrtr_port_put(ipc);
@@ -750,9 +760,9 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg,
size_t size, int flags)
{
DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name);
- const struct qrtr_hdr *phdr;
struct sock *sk = sock->sk;
struct sk_buff *skb;
+ struct qrtr_cb *cb;
int copied, rc;
lock_sock(sk);
@@ -769,22 +779,22 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg,
return rc;
}
- phdr = (const struct qrtr_hdr *)skb_transport_header(skb);
- copied = le32_to_cpu(phdr->size);
+ copied = skb->len;
if (copied > size) {
copied = size;
msg->msg_flags |= MSG_TRUNC;
}
- rc = skb_copy_datagram_msg(skb, QRTR_HDR_SIZE, msg, copied);
+ rc = skb_copy_datagram_msg(skb, 0, msg, copied);
if (rc < 0)
goto out;
rc = copied;
if (addr) {
+ cb = (struct qrtr_cb *)skb->cb;
addr->sq_family = AF_QIPCRTR;
- addr->sq_node = le32_to_cpu(phdr->src_node_id);
- addr->sq_port = le32_to_cpu(phdr->src_port_id);
+ addr->sq_node = cb->src_node;
+ addr->sq_port = cb->src_port;
msg->msg_namelen = sizeof(*addr);
}
@@ -877,7 +887,7 @@ static int qrtr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case TIOCINQ:
skb = skb_peek(&sk->sk_receive_queue);
if (skb)
- len = skb->len - QRTR_HDR_SIZE;
+ len = skb->len;
rc = put_user(len, (int __user *)argp);
break;
case SIOCGIFADDR:
--
2.12.0
^ permalink raw reply related
* [PATCH 7/7] net: qrtr: Support decoding incoming v2 packets
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org>
Add the necessary logic for decoding incoming messages of version 2 as
well. Also make sure there's room for the bigger of version 1 and 2
headers in the code allocating skbs for outgoing messages.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
net/qrtr/qrtr.c | 132 ++++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 94 insertions(+), 38 deletions(-)
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 5042999756ce..5f397fa1c109 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -20,14 +20,15 @@
#include "qrtr.h"
-#define QRTR_PROTO_VER 1
+#define QRTR_PROTO_VER_1 1
+#define QRTR_PROTO_VER_2 3
/* auto-bind range */
#define QRTR_MIN_EPH_SOCKET 0x4000
#define QRTR_MAX_EPH_SOCKET 0x7fff
/**
- * struct qrtr_hdr - (I|R)PCrouter packet header
+ * struct qrtr_hdr_v1 - (I|R)PCrouter packet header version 1
* @version: protocol version
* @type: packet type; one of QRTR_TYPE_*
* @src_node_id: source node
@@ -37,7 +38,7 @@
* @dst_node_id: destination node
* @dst_port_id: destination port
*/
-struct qrtr_hdr {
+struct qrtr_hdr_v1 {
__le32 version;
__le32 type;
__le32 src_node_id;
@@ -48,6 +49,32 @@ struct qrtr_hdr {
__le32 dst_port_id;
} __packed;
+/**
+ * struct qrtr_hdr_v2 - (I|R)PCrouter packet header later versions
+ * @version: protocol version
+ * @type: packet type; one of QRTR_TYPE_*
+ * @flags: bitmask of QRTR_FLAGS_*
+ * @optlen: length of optional header data
+ * @size: length of packet, excluding this header and optlen
+ * @src_node_id: source node
+ * @src_port_id: source port
+ * @dst_node_id: destination node
+ * @dst_port_id: destination port
+ */
+struct qrtr_hdr_v2 {
+ u8 version;
+ u8 type;
+ u8 flags;
+ u8 optlen;
+ __le32 size;
+ __le16 src_node_id;
+ __le16 src_port_id;
+ __le16 dst_node_id;
+ __le16 dst_port_id;
+} __packed;
+
+#define QRTR_FLAGS_CONFIRM_RX BIT(0)
+
struct qrtr_cb {
u32 src_node;
u32 src_port;
@@ -58,7 +85,8 @@ struct qrtr_cb {
u8 confirm_rx;
};
-#define QRTR_HDR_SIZE sizeof(struct qrtr_hdr)
+#define QRTR_HDR_MAX_SIZE max_t(size_t, sizeof(struct qrtr_hdr_v1), \
+ sizeof(struct qrtr_hdr_v2))
struct qrtr_sock {
/* WARNING: sk must be the first member */
@@ -154,12 +182,12 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
int type, struct sockaddr_qrtr *from,
struct sockaddr_qrtr *to)
{
- struct qrtr_hdr *hdr;
+ struct qrtr_hdr_v1 *hdr;
size_t len = skb->len;
int rc = -ENODEV;
- hdr = skb_push(skb, QRTR_HDR_SIZE);
- hdr->version = cpu_to_le32(QRTR_PROTO_VER);
+ hdr = skb_push(skb, sizeof(*hdr));
+ hdr->version = cpu_to_le32(QRTR_PROTO_VER_1);
hdr->type = cpu_to_le32(type);
hdr->src_node_id = cpu_to_le32(from->sq_node);
hdr->src_port_id = cpu_to_le32(from->sq_port);
@@ -224,52 +252,80 @@ static void qrtr_node_assign(struct qrtr_node *node, unsigned int nid)
int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
{
struct qrtr_node *node = ep->node;
- const struct qrtr_hdr *phdr = data;
+ const struct qrtr_hdr_v1 *v1;
+ const struct qrtr_hdr_v2 *v2;
struct sk_buff *skb;
struct qrtr_cb *cb;
- unsigned int psize;
unsigned int size;
- unsigned int type;
unsigned int ver;
- unsigned int dst;
+ size_t hdrlen;
- if (len < QRTR_HDR_SIZE || len & 3)
+ if (len & 3)
return -EINVAL;
- ver = le32_to_cpu(phdr->version);
- size = le32_to_cpu(phdr->size);
- type = le32_to_cpu(phdr->type);
- dst = le32_to_cpu(phdr->dst_port_id);
+ skb = netdev_alloc_skb(NULL, len);
+ if (!skb)
+ return -ENOMEM;
- psize = (size + 3) & ~3;
+ cb = (struct qrtr_cb *)skb->cb;
- if (ver != QRTR_PROTO_VER)
- return -EINVAL;
+ /* Version field in v1 is little endian, so this works for both cases */
+ ver = *(u8 *)data;
- if (len != psize + QRTR_HDR_SIZE)
- return -EINVAL;
+ switch (ver) {
+ case QRTR_PROTO_VER_1:
+ v1 = data;
+ hdrlen = sizeof(*v1);
- if (dst != QRTR_PORT_CTRL && type != QRTR_TYPE_DATA)
- return -EINVAL;
+ cb->type = le32_to_cpu(v1->type);
+ cb->src_node = le32_to_cpu(v1->src_node_id);
+ cb->src_port = le32_to_cpu(v1->src_port_id);
+ cb->confirm_rx = !!v1->confirm_rx;
+ cb->dst_node = le32_to_cpu(v1->dst_node_id);
+ cb->dst_port = le32_to_cpu(v1->dst_port_id);
- skb = netdev_alloc_skb(NULL, len);
- if (!skb)
- return -ENOMEM;
+ size = le32_to_cpu(v1->size);
+ break;
+ case QRTR_PROTO_VER_2:
+ v2 = data;
+ hdrlen = sizeof(*v2) + v2->optlen;
+
+ cb->type = v2->type;
+ cb->confirm_rx = !!(v2->flags & QRTR_FLAGS_CONFIRM_RX);
+ cb->src_node = le16_to_cpu(v2->src_node_id);
+ cb->src_port = le16_to_cpu(v2->src_port_id);
+ cb->dst_node = le16_to_cpu(v2->dst_node_id);
+ cb->dst_port = le16_to_cpu(v2->dst_port_id);
+
+ if (cb->src_port == (u16)QRTR_PORT_CTRL)
+ cb->src_port = QRTR_PORT_CTRL;
+ if (cb->dst_port == (u16)QRTR_PORT_CTRL)
+ cb->dst_port = QRTR_PORT_CTRL;
+
+ size = le32_to_cpu(v2->size);
+ break;
+ default:
+ pr_err("qrtr: Invalid version %d\n", ver);
+ goto err;
+ }
- cb = (struct qrtr_cb *)skb->cb;
- cb->src_node = le32_to_cpu(phdr->src_node_id);
- cb->src_port = le32_to_cpu(phdr->src_port_id);
- cb->dst_node = le32_to_cpu(phdr->dst_node_id);
- cb->dst_port = le32_to_cpu(phdr->dst_port_id);
- cb->type = type;
- cb->confirm_rx = !!phdr->confirm_rx;
+ if (len != ALIGN(size, 4) + hdrlen)
+ goto err;
- skb_put_data(skb, data + QRTR_HDR_SIZE, size);
+ if (cb->dst_port != QRTR_PORT_CTRL && cb->type != QRTR_TYPE_DATA)
+ goto err;
+
+ skb_put_data(skb, data + hdrlen, size);
skb_queue_tail(&node->rx_queue, skb);
schedule_work(&node->work);
return 0;
+
+err:
+ kfree_skb(skb);
+ return -EINVAL;
+
}
EXPORT_SYMBOL_GPL(qrtr_endpoint_post);
@@ -287,11 +343,11 @@ static struct sk_buff *qrtr_alloc_ctrl_packet(struct qrtr_ctrl_pkt **pkt)
const int pkt_len = sizeof(struct qrtr_ctrl_pkt);
struct sk_buff *skb;
- skb = alloc_skb(QRTR_HDR_SIZE + pkt_len, GFP_KERNEL);
+ skb = alloc_skb(QRTR_HDR_MAX_SIZE + pkt_len, GFP_KERNEL);
if (!skb)
return NULL;
- skb_reserve(skb, QRTR_HDR_SIZE);
+ skb_reserve(skb, QRTR_HDR_MAX_SIZE);
*pkt = skb_put_zero(skb, pkt_len);
return skb;
@@ -720,12 +776,12 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
}
plen = (len + 3) & ~3;
- skb = sock_alloc_send_skb(sk, plen + QRTR_HDR_SIZE,
+ skb = sock_alloc_send_skb(sk, plen + QRTR_HDR_MAX_SIZE,
msg->msg_flags & MSG_DONTWAIT, &rc);
if (!skb)
goto out_node;
- skb_reserve(skb, QRTR_HDR_SIZE);
+ skb_reserve(skb, QRTR_HDR_MAX_SIZE);
rc = memcpy_from_msg(skb_put(skb, len), msg, len);
if (rc) {
--
2.12.0
^ permalink raw reply related
* [PATCH 1/7] net: qrtr: Invoke sk_error_report() after setting sk_err
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org>
Rather than manually waking up any context sleeping on the sock to
signal an error we should call sk_error_report(). This has the added
benefit that in-kernel consumers can override this notificatino with
its own callback.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
net/qrtr/qrtr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 5586609afa27..2058b27821a4 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -541,7 +541,7 @@ static void qrtr_reset_ports(void)
sock_hold(&ipc->sk);
ipc->sk.sk_err = ENETRESET;
- wake_up_interruptible(sk_sleep(&ipc->sk));
+ ipc->sk.sk_error_report(&ipc->sk);
sock_put(&ipc->sk);
}
mutex_unlock(&qrtr_port_lock);
--
2.12.0
^ permalink raw reply related
* [PATCH 2/7] net: qrtr: Move constants to header file
From: Bjorn Andersson @ 2017-09-07 6:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm, Chris Lew
In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org>
The constants are used by both the name server and clients, so clarify
their value and move them to the uapi header.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
include/uapi/linux/qrtr.h | 3 +++
net/qrtr/qrtr.c | 2 --
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/qrtr.h b/include/uapi/linux/qrtr.h
index 9d76c566f66e..63e8803e4d90 100644
--- a/include/uapi/linux/qrtr.h
+++ b/include/uapi/linux/qrtr.h
@@ -4,6 +4,9 @@
#include <linux/socket.h>
#include <linux/types.h>
+#define QRTR_NODE_BCAST 0xffffffffu
+#define QRTR_PORT_CTRL 0xfffffffeu
+
struct sockaddr_qrtr {
__kernel_sa_family_t sq_family;
__u32 sq_node;
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 2058b27821a4..0d7d3968414e 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -61,8 +61,6 @@ struct qrtr_hdr {
} __packed;
#define QRTR_HDR_SIZE sizeof(struct qrtr_hdr)
-#define QRTR_NODE_BCAST ((unsigned int)-1)
-#define QRTR_PORT_CTRL ((unsigned int)-2)
struct qrtr_sock {
/* WARNING: sk must be the first member */
--
2.12.0
^ permalink raw reply related
* Re: [patch net] net: sched: fix memleak for chain zero
From: Jiri Pirko @ 2017-09-07 6:07 UTC (permalink / raw)
To: Cong Wang
Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
Jakub Kicinski, mlxsw
In-Reply-To: <CAM_iQpX8q8A-J+7w0rzxuZBrTYLmmgLgU1K=cH9-9f0ikkSaPw@mail.gmail.com>
Thu, Sep 07, 2017 at 01:37:59AM CEST, xiyou.wangcong@gmail.com wrote:
>On Wed, Sep 6, 2017 at 1:33 PM, Jiri Pirko <jiri@resnulli.us> wrote:
>> Wed, Sep 06, 2017 at 07:40:02PM CEST, xiyou.wangcong@gmail.com wrote:
>>>On Wed, Sep 6, 2017 at 4:14 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>>>> From: Jiri Pirko <jiri@mellanox.com>
>>>>
>>>> There's a memleak happening for chain 0. The thing is, chain 0 needs to
>>>> be always present, not created on demand. Therefore tcf_block_get upon
>>>> creation of block calls the tcf_chain_create function directly. The
>>>> chain is created with refcnt == 1, which is not correct in this case and
>>>> causes the memleak. So move the refcnt increment into tcf_chain_get
>>>> function even for the case when chain needs to be created.
>>>>
>>>
>>>Your approach could work but you just make the code even
>>>uglier than it is now:
>>>
>>>1. The current code is already ugly for special-casing chain 0:
>>>
>>> if (--chain->refcnt == 0 && !chain->filter_chain && chain->index != 0)
>>> tcf_chain_destroy(chain);
>>>
>>>2. With your patch, chain 0 has a different _initial_ refcnt with others.
>>
>> No. Initial refcnt is the same. ! for every action that holds the chain.
>> So actually, it returns it back where it should be.
>
>Not all all.
>
>tcf_block_get() calls tcf_chain_create(, 0), after your patch
>chain 0 has refcnt==0 initially.
>
>Non-0 chain? They are created via tcf_chain_get(), aka,
>refcnt==0 initially.
And if they are created on insertion of the filter, put is caller right
away which returns the ref back to 0. As I said, Non-0 refcnt means
either rule is being inserted/removed of there is an action that holds
reference to this chain. So my patch actually fixes the behaviour making
chain 0 and other chains to behave the same.
>
>
>>
>>
>>>
>>>3. Allowing an object (chain 0) exists with refcnt==0
>>
>> So? That is for every chain that does not have goto_chain action
>> pointing at. Please read the code.
>
>So you are pretending to be GC but you are apparently not.
>
>You create all the troubles by setting yourself to believe chain 0
>is special and refcnt==0 is okay. Both are wrong.
>
>Actually the !list_empty() check is totally unnecessary too,
>it is yet another place you get it wrong, you hide the race
>condition in commit 744a4cf63e52 which makes it harder
>to expose.
>
>I understand you don't trust me. Look at DaveM's reaction
>to your refcnt==0 madness.
>
>Remember, refcnt can be very simple, you just want to
>make it harder by abusing it or attempting to invent a GC.
>
>I am going to update my patch (to remove all your madness)
>since this is horribly wrong to me. Sorry.
It is not so easy to use the refcnt also for filters, I had good reason
to relend on filter_chain list to find out if there is a rule. If you
figure out how to do it better, be my guest. I suggest you do that for
net-next and let's fix the net in the easiest way possible.
^ permalink raw reply
* [PATCH 1/2] ip_tunnel: fix setting ttl and tos value in collect_md mode
From: Haishuang Yan @ 2017-09-07 6:08 UTC (permalink / raw)
To: David S. Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI
Cc: netdev, linux-kernel, Haishuang Yan, Alexei Starovoitov
ttl and tos variables are declared and assigned, but are not used in
iptunnel_xmit() function.
Fixes: cfc7381b3002 ("ip_tunnel: add collect_md mode to IPIP tunnel")
Cc: Alexei Starovoitov <ast@fb.com>
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
net/ipv4/ip_tunnel.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 129d1a3..e1856bf 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -618,8 +618,8 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, u8 proto)
ip_rt_put(rt);
goto tx_dropped;
}
- iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, proto, key->tos,
- key->ttl, df, !net_eq(tunnel->net, dev_net(dev)));
+ iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, proto, tos, ttl,
+ df, !net_eq(tunnel->net, dev_net(dev)));
return;
tx_error:
dev->stats.tx_errors++;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 2/2] ip6_tunnel: fix setting hop_limit value for ipv6 tunnel
From: Haishuang Yan @ 2017-09-07 6:08 UTC (permalink / raw)
To: David S. Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI
Cc: netdev, linux-kernel, Haishuang Yan
In-Reply-To: <1504764515-13536-1-git-send-email-yanhaishuang@cmss.chinamobile.com>
Similar to vxlan/geneve tunnel, if hop_limit is zero, it should fall
back to ip6_dst_hoplimt().
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
net/ipv6/ip6_tunnel.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 3a0ba2a..10a693a 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1184,6 +1184,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
init_tel_txopt(&opt, encap_limit);
ipv6_push_frag_opts(skb, &opt.ops, &proto);
}
+ hop_limit = hop_limit ? : ip6_dst_hoplimit(dst);
/* Calculate max headroom for all the headers and adjust
* needed_headroom if necessary.
--
1.8.3.1
^ permalink raw reply related
* Re: [Patch net v2 2/2] net_sched: fix all the madness of tc filter chain
From: Jiri Pirko @ 2017-09-07 6:32 UTC (permalink / raw)
To: Cong Wang; +Cc: netdev, jakub.kicinski, Jiri Pirko
In-Reply-To: <20170907042607.24413-2-xiyou.wangcong@gmail.com>
Thu, Sep 07, 2017 at 06:26:07AM CEST, xiyou.wangcong@gmail.com wrote:
>This patch fixes the following madness of tc filter chain:
Could you avoid expressive words like "madness" and such?
Please be technical.
>
>1) tcf_chain_destroy() is called by both tcf_block_put() and
> tcf_chain_put(). tcf_chain_put() is correctly refcnt'ed and paired
> with tcf_chain_get(), but tcf_block_put() is not, it should be paired
> with tcf_block_get() which means we still need to decrease the refcnt.
> Think it in another way: if we call tcf_bock_put() immediately after
> tcf_block_get(), could we get effectively a nop? This causes a memory
> leak as reported by Jakub.
>
>2) tp proto should hold a refcnt to the chain too. This significantly
> simplifies the logic:
>
>2a) Chain 0 is no longer special, it is created and refcnted by tp
> like any other chains. All the ugliness in tcf_chain_put() can be
> gone!
>
>2b) No need to handle the flushing oddly, because block still holds
> chain 0, it can not be released, this guarantees block is the last
> user.
>
>2c) The race condition with RCU callbacks is easier to handle with just
> a rcu_barrier()! Much easier to understand, nothing to hide! Thanks
> to the previous patch. Please see also the comments in code.
>
>2d) Make the code understandable by humans, much less error-prone.
>
>Fixes: 744a4cf63e52 ("net: sched: fix use after free when tcf_chain_destroy is called multiple times")
>Fixes: 5bc1701881e3 ("net: sched: introduce multichain support for filters")
>Reported-by: Jakub Kicinski <jakub.kicinski@netronome.com>
>Cc: Jiri Pirko <jiri@mellanox.com>
>Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
>---
> net/sched/cls_api.c | 38 ++++++++++++++++++++++----------------
> 1 file changed, 22 insertions(+), 16 deletions(-)
>
>diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
>index 6c5ea84d2682..e9060dc36519 100644
>--- a/net/sched/cls_api.c
>+++ b/net/sched/cls_api.c
>@@ -209,21 +209,20 @@ static void tcf_chain_flush(struct tcf_chain *chain)
> RCU_INIT_POINTER(*chain->p_filter_chain, NULL);
> while ((tp = rtnl_dereference(chain->filter_chain)) != NULL) {
> RCU_INIT_POINTER(chain->filter_chain, tp->next);
>+ tcf_chain_put(chain);
> tcf_proto_destroy(tp);
> }
> }
>
> static void tcf_chain_destroy(struct tcf_chain *chain)
> {
>- /* May be already removed from the list by the previous call. */
>- if (!list_empty(&chain->list))
>- list_del_init(&chain->list);
>+ list_del(&chain->list);
>+ kfree(chain);
>+}
>
>- /* There might still be a reference held when we got here from
>- * tcf_block_put. Wait for the user to drop reference before free.
>- */
>- if (!chain->refcnt)
>- kfree(chain);
>+static void tcf_chain_hold(struct tcf_chain *chain)
>+{
>+ ++chain->refcnt;
> }
>
> struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
>@@ -233,7 +232,7 @@ struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
>
> list_for_each_entry(chain, &block->chain_list, list) {
> if (chain->index == chain_index) {
>- chain->refcnt++;
>+ tcf_chain_hold(chain);
> return chain;
> }
> }
>@@ -246,10 +245,7 @@ EXPORT_SYMBOL(tcf_chain_get);
>
> void tcf_chain_put(struct tcf_chain *chain)
> {
>- /* Destroy unused chain, with exception of chain 0, which is the
>- * default one and has to be always present.
>- */
>- if (--chain->refcnt == 0 && !chain->filter_chain && chain->index != 0)
>+ if (--chain->refcnt == 0)
Okay, so you take the reference for every goto_chain action and every
tp, right? Note that for chain 0, you hold one more reference (due to
the creation). That is probably ok as we need chain 0 not to go away
even if all tps and goto_chain actions are gone.
> tcf_chain_destroy(chain);
> }
> EXPORT_SYMBOL(tcf_chain_put);
>@@ -294,10 +290,18 @@ void tcf_block_put(struct tcf_block *block)
> if (!block)
> return;
>
>- list_for_each_entry_safe(chain, tmp, &block->chain_list, list) {
>+ /* Standalone actions are not allowed to jump to any chain, and
>+ * bound actions should be all removed after flushing. However,
>+ * filters are destroyed in RCU callbacks, we have to flush and wait
>+ * for them before releasing this refcnt, otherwise we race with RCU
>+ * callbacks!!!
Why the "!!!"? Please avoid that. Not necessary at all.
>+ */
>+ list_for_each_entry(chain, &block->chain_list, list)
> tcf_chain_flush(chain);
>- tcf_chain_destroy(chain);
>- }
>+ rcu_barrier();
This actually tries to fix another bug I discovered yesterday. Good.
>+
>+ list_for_each_entry_safe(chain, tmp, &block->chain_list, list)
>+ tcf_chain_put(chain);
Which reference are you putting here? For chain 0, that is the original
reference due to creation from block_get. But how about the other
chains? If you do flush all in the previous list iteration, they are
removed there. Also note that they are removed from the list while
iterating it.
I believe that you need to add tcf_chain_hold(chain) to the start of the
previous list iteration to ensure all existing chains will stay, then
you can put them here.
Did you test this? I believe we need some simple test script.
> kfree(block);
> }
> EXPORT_SYMBOL(tcf_block_put);
>@@ -375,6 +379,7 @@ static void tcf_chain_tp_insert(struct tcf_chain *chain,
> rcu_assign_pointer(*chain->p_filter_chain, tp);
> RCU_INIT_POINTER(tp->next, tcf_chain_tp_prev(chain_info));
> rcu_assign_pointer(*chain_info->pprev, tp);
>+ tcf_chain_hold(chain);
> }
>
> static void tcf_chain_tp_remove(struct tcf_chain *chain,
>@@ -386,6 +391,7 @@ static void tcf_chain_tp_remove(struct tcf_chain *chain,
> if (chain->p_filter_chain && tp == chain->filter_chain)
> RCU_INIT_POINTER(*chain->p_filter_chain, next);
> RCU_INIT_POINTER(*chain_info->pprev, next);
>+ tcf_chain_put(chain);
> }
>
> static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain,
>--
>2.13.0
>
^ permalink raw reply
* Re: VLAN/bridge "compression" in wifi (was: Re: [PATCH 3/8] qtnfmac: implement AP_VLAN iftype support)
From: Johannes Berg @ 2017-09-07 6:45 UTC (permalink / raw)
To: Sergey Matyukevich; +Cc: linux-wireless, netdev, Igor Mitsyanko, Avinash Patil
In-Reply-To: <20170906154522.twtesbo2rxbrhekf@bars>
Hi,
> > To clarify, I think what you - conceptually - want is the following
> > topology:
> >
> > +--- eth0.1 --- br.1 --- wlan0.1
> > |
> > eth0 ---+--- eth0.2 --- br.2 --- wlan0.2
> > |
> > +--- eth0.3 --- br.3 --- wlan0.3
[...]
> That's right. In fact, hostapd is able to create this kind of network
> bridge infrastructure automatically when it is built
> with CONFIG_FULL_DYNAMIC_VLAN option enabled.
Cool, I was unaware of the exact functionality of this build-time
option. :)
> > Now, you seem to want to compress this to
> >
> > +--- wlan0.1
> > |
> > eth0 --- br ---+--- wlan0.2
> > |
> > +--- wlan0.3
[...]
> Exactly. And yes, the only purpose of this 'non-conventional' mode
> was to have 802.1Q acceleration on the ethernet port.
Right. You can still have acceleration in the top picture by placing
the feature into the Ethernet hardware, so that tagging/untagging
doesn't have to touch the packet data but just touches (skb) metadata.
But obviously that's something that happens on the other side and you
don't have control over it.
Anyway, I'm happy we cleared up what was going on and also that you
decided to leave it for now and work with the regular Linux topology
model.
Thanks,
johannes
^ permalink raw reply
* [PATCH net] smsc95xx: Configure pause time to 0xffff when tx flow control enabled
From: Nisar.Sayed @ 2017-09-07 6:51 UTC (permalink / raw)
To: davem; +Cc: UNGLinuxDriver, netdev, steve.glendinning
From: Nisar Sayed <Nisar.Sayed@microchip.com>
Configure pause time to 0xffff when tx flow control enabled
Signed-off-by: Nisar Sayed <Nisar.Sayed@microchip.com>
---
drivers/net/usb/smsc95xx.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 340c134..309b88a 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -526,7 +526,7 @@ static void smsc95xx_set_multicast(struct net_device *netdev)
static int smsc95xx_phy_update_flowcontrol(struct usbnet *dev, u8 duplex,
u16 lcladv, u16 rmtadv)
{
- u32 flow, afc_cfg = 0;
+ u32 flow = 0, afc_cfg;
int ret = smsc95xx_read_reg(dev, AFC_CFG, &afc_cfg);
if (ret < 0)
@@ -537,20 +537,19 @@ static int smsc95xx_phy_update_flowcontrol(struct usbnet *dev, u8 duplex,
if (cap & FLOW_CTRL_RX)
flow = 0xFFFF0002;
- else
- flow = 0;
- if (cap & FLOW_CTRL_TX)
+ if (cap & FLOW_CTRL_TX) {
afc_cfg |= 0xF;
- else
+ flow |= 0xFFFF0000;
+ } else {
afc_cfg &= ~0xF;
+ }
netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s\n",
cap & FLOW_CTRL_RX ? "enabled" : "disabled",
cap & FLOW_CTRL_TX ? "enabled" : "disabled");
} else {
netif_dbg(dev, link, dev->net, "half duplex\n");
- flow = 0;
afc_cfg |= 0xF;
}
--
1.9.1
^ permalink raw reply related
* pull-request: mac80211 2017-09-07
From: Johannes Berg @ 2017-09-07 7:09 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-wireless
Hi Dave,
During my long absence some things have accumulated, but there wasn't
actually all that much that could've gone into the last cycle, and a
fix or two was taken care of by others.
The most important thing here is probably the deadlock fix that a few
people have run into on 4.13, but that was only identified now, and
perhaps the 40 MHz fix from Emmanuel that helps avoid iwlwifi firmware
crashes.
Please pull and let me know if there's any problem.
Thanks,
johannes
The following changes since commit 6d9c153a0b84392406bc77600aa7d3ea365de041:
net: dsa: loop: Do not unregister invalid fixed PHY (2017-09-03 20:18:25 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git tags/mac80211-for-davem-2017-09-07
for you to fetch changes up to bde59c475e0883e4c4294bcd9b9c7e08ae18c828:
mac80211: fix deadlock in driver-managed RX BA session start (2017-09-06 15:22:02 +0200)
----------------------------------------------------------------
Back from a long absence, so we have a number of things:
* a remain-on-channel fix from Avi
* hwsim TX power fix from Beni
* null-PTR dereference with iTXQ in some rare configurations (Chunho)
* 40 MHz custom regdomain fixes (Emmanuel)
* look at right place in HT/VHT capability parsing (Igor)
* complete A-MPDU teardown properly (Ilan)
* Mesh ID Element ordering fix (Liad)
* avoid tracing warning in ht_dbg() (Sharon)
* fix print of assoc/reassoc (Simon)
* fix encrypted VLAN with iTXQ (myself)
* fix calling context of TX queue wake (myself)
* fix a deadlock with ath10k aggregation (myself)
----------------------------------------------------------------
Avraham Stern (1):
mac80211: flush hw_roc_start work before cancelling the ROC
Beni Lev (1):
mac80211_hwsim: Use proper TX power
Chunho Lee (1):
mac80211: Fix null pointer dereference with iTXQ support
Emmanuel Grumbach (1):
cfg80211: honor NL80211_RRF_NO_HT40{MINUS,PLUS}
Igor Mitsyanko (1):
nl80211: look for HT/VHT capabilities in beacon's tail
Ilan peer (1):
mac80211: Complete ampdu work schedule during session tear down
Johannes Berg (3):
mac80211: fix VLAN handling with TXQs
mac80211: agg-tx: call drv_wake_tx_queue in proper context
mac80211: fix deadlock in driver-managed RX BA session start
Liad Kaufman (1):
mac80211: add MESH IE in the correct order
Sharon Dvir (1):
mac80211: shorten debug prints using ht_dbg() to avoid warning
Simon Dinkin (1):
mac80211: fix incorrect assignment of reassoc value
drivers/net/wireless/mac80211_hwsim.c | 2 --
include/net/mac80211.h | 15 ++-------------
net/mac80211/agg-rx.c | 32 ++++++++++++++++++++-----------
net/mac80211/agg-tx.c | 8 ++++++--
net/mac80211/ht.c | 24 ++++++++++++++++++++---
net/mac80211/ieee80211_i.h | 4 ++++
net/mac80211/iface.c | 20 ++++++++++++++++---
net/mac80211/mlme.c | 2 +-
net/mac80211/offchannel.c | 2 ++
net/mac80211/tx.c | 36 ++++++++++++++++++++++++++++-------
net/mac80211/util.c | 2 +-
net/wireless/nl80211.c | 4 ++--
net/wireless/reg.c | 20 +++++++++++++++++--
13 files changed, 124 insertions(+), 47 deletions(-)
^ permalink raw reply
* [PATCH net 1/3] lan78xx: Fix for eeprom read/write when device autosuspend
From: Nisar.Sayed @ 2017-09-07 7:11 UTC (permalink / raw)
To: davem; +Cc: UNGLinuxDriver, netdev
From: Nisar Sayed <Nisar.Sayed@microchip.com>
Fix for eeprom read/write when device autosuspend
Signed-off-by: Nisar Sayed <Nisar.Sayed@microchip.com>
---
drivers/net/usb/lan78xx.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index b99a7fb..baf91c7 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -1265,30 +1265,44 @@ static int lan78xx_ethtool_get_eeprom(struct net_device *netdev,
struct ethtool_eeprom *ee, u8 *data)
{
struct lan78xx_net *dev = netdev_priv(netdev);
+ int ret = -EINVAL;
+
+ if (usb_autopm_get_interface(dev->intf) < 0)
+ return ret;
ee->magic = LAN78XX_EEPROM_MAGIC;
- return lan78xx_read_raw_eeprom(dev, ee->offset, ee->len, data);
+ ret = lan78xx_read_raw_eeprom(dev, ee->offset, ee->len, data);
+
+ usb_autopm_put_interface(dev->intf);
+
+ return ret;
}
static int lan78xx_ethtool_set_eeprom(struct net_device *netdev,
struct ethtool_eeprom *ee, u8 *data)
{
struct lan78xx_net *dev = netdev_priv(netdev);
+ int ret = -EINVAL;
+
+ if (usb_autopm_get_interface(dev->intf) < 0)
+ return ret;
/* Allow entire eeprom update only */
if ((ee->magic == LAN78XX_EEPROM_MAGIC) &&
(ee->offset == 0) &&
(ee->len == 512) &&
(data[0] == EEPROM_INDICATOR))
- return lan78xx_write_raw_eeprom(dev, ee->offset, ee->len, data);
+ ret = lan78xx_write_raw_eeprom(dev, ee->offset, ee->len, data);
else if ((ee->magic == LAN78XX_OTP_MAGIC) &&
(ee->offset == 0) &&
(ee->len == 512) &&
(data[0] == OTP_INDICATOR_1))
- return lan78xx_write_raw_otp(dev, ee->offset, ee->len, data);
+ ret = lan78xx_write_raw_otp(dev, ee->offset, ee->len, data);
- return -EINVAL;
+ usb_autopm_put_interface(dev->intf);
+
+ return ret;
}
static void lan78xx_get_strings(struct net_device *netdev, u32 stringset,
--
1.9.1
^ permalink raw reply related
* [PATCH net 0/3] lan78xx: Fixes to lan78xx driver
From: Nisar.Sayed @ 2017-09-07 7:10 UTC (permalink / raw)
To: davem; +Cc: UNGLinuxDriver, netdev
From: Nisar Sayed <Nisar.Sayed@microchip.com>
This series of patches are for lan78xx driver.
These patches fixes potential issues associated with lan78xx driver
Nisar Sayed (3):
Fix for eeprom read/write when device autosuspend
Allow EEPROM write for less than MAX_EEPROM_SIZE
Use default value loaded from EEPROM/OTP when resetting
drivers/net/usb/lan78xx.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
--
1.9.1
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox